1.知识点的过渡

1.1继承:

继承是建立在子类和父类的基础之上的
类之间的继承—单继承
接口之间的继承—多继承
类与接口之间的关系—一对多—实现关系:一个类实现多个接口

1.2基于以上的知识:

1.按照封装的高度来说—-接口(高)—>抽象类—>普通类
2.接口也是一个特殊的类,其实也是父类
3.如果一个子类与父类产生了关系—继承关系:从类型上来说子类属于父类的一个实例

1.3新知识:

如果说父类的引用指向子类的对象就是—-向上造型
对象的多态性,只适用于方法(编译看左边,运行看右边),不适用于属性(编译和运行都看左边)
多态的前提必须有子父类关系,或者实现接口关系

2.向上造型:是多态的一种实现

2.1向上造型

父类(接口)的引用可以指向子类的对象,展现出来的是父类(接口)的功能

  • 子类的引用变量可以指向子类的对象,展现出来的是子类的功能
  • 子类对象可以展现出多种形态,这多种形态叫做多态—多态后不能再调用子类特有的方法

  • 格式:
  • 父类类型 变量名=new 子类的对象();
  • 变量名.方法名

  • 当多态出现以后,编译期只能调用父类中声明的方法,但是在运行期实际执行的是子类重写父类的方法

多态的使用场景:
1.为变量赋值的时候使用多态,达到父类的引用子类的对象,直接为变量赋值

  • 2.调用方法的时候,为方法的参数进行赋值
  • 3.方法的返回值,可以定义为父类的类型,但是返回的是子类的对象。
  • 当该方法被调用后,用父类的类型接收 ```java package duotai_01;

/**

  • @author Lynn
  • @create 2020-12-01-15:15 */

/**

  • 父类—动物类 *
  • 用于展示多态的抽象方法
  • 吃饭,睡觉 */ public abstract class Animal { //普通方法 public void eat(){

    1. System.out.println("吃饭");

    }

    //抽象方法 public abstract void sleep(); } java package duotai_01;

/**

  • @author Lynn
  • @create 2020-12-01-15:17 */

/**

  • 人类—子类(具体类) *
  • 用于展示多态的实现
  • 在父类的共性功能外,有自己学习,工作的方法 */ public class Person extends Animal{ @Override public void sleep() {

    1. System.out.println("睡在床上");

    }

    //拓展子类自己的方法 public void study(){

    1. System.out.println("学习使我快乐");

    }

    //工作的方法 public void work(){

    1. System.out.println("工作可以创造金钱");

    }

    //重写父类中的方法 @Override public void eat(){

    1. System.out.println("吃饱饭踏实");

    } } java package duotai_01;

/**

  • @author Lynn
  • @create 2020-12-01-15:53 */ public class Dog extends Animal{ @Override public void sleep() {

    1. System.out.println("睡在地上");

    }

    public void kanmen(){

    1. System.out.println("千里无极");

    }

    @Override public void eat(){

    1. System.out.println("吃骨头");

    } } java package duotai_01;

/**

  • @author Lynn
  • @create 2020-12-01-15:22 */

import java.security.PublicKey;

/**

  • 演示向上造型 *
  • 其实向上造型是多态的一种实现方式
  • 父类(接口)的引用可以指向子类的对象,展现出来的是父类(接口)的功能
  • 子类的引用变量可以指向子类的对象,展现出来的是子类的功能
  • 子类对象可以展现出多态的实现 *
  • 格式:
  • 父类类型 变量名=new 子类的对象();
  • 变量名.方法名 *
  • 当多态出现以后,调用的方法是子类重写后的方法 *
  • 多态的使用场景:
  • 1.为变量赋值的时候使用多态,达到父类的引用子类的对象,直接为变量赋值
  • 2.调用方法的时候,为方法的参数进行赋值
  • 3.方法的返回值,可以定义为父类的类型,但是返回的是子类的对象。
  • 当该方法被调用后,用父类的类型接收 */ public class SubClassType { public static void main(String[] args) {

    1. //创建子类对象
    2. Person p=new Person();
    3. p.eat();
    4. p.sleep();
    5. p.work();
    6. p.study();
    7. System.out.println("-------------------------");
    8. //使用向上造型--展现出来的是父类中的功能
    9. Animal a=new Person();
    10. //调用的是父类中的方法,结果是子类中重写后的方法
    11. a.eat();//吃饱饭踏实
    12. a.sleep();//睡在床上

    // a.work();//调用不到

  1. System.out.println("-------------------------------");
  2. //调用feed方法
  3. feed(new Person());//传一个Animal的子类对象
  4. feed(new Dog());//传一个Animal的子类对象

// feed(new Animal() //Animal是一个抽象类不能被实例化

  1. }
  2. //封装一个方法,用于灵活地调用所有的方法---传入参数是一个父类
  3. public static void feed(Animal a){//a是Animal的引用,可以接收Animal中所有的子类对象
  4. //调用该动物吃饭的方法
  5. System.out.println("feed方法内");
  6. a.eat();
  7. }

}

  1. <a name="RpARI"></a>
  2. ### 2.2重点补充:
  3. 1.方法的重载和重写的区别<br />方法的重载看到的是引用;<br />方法的重写看的是对象
  4. 2.方法的重载时在编译期绑定参数的--编译期就是按下保存键按钮之后jvm检查java代码的语法的时候<br />方法的重写实在运行期执行的--因为**对象实在运行期才出现的**
  5. <a name="3."></a>
  6. # 3.向下造型
  7. <a name="j6qXf"></a>
  8. ### 多态的实现:
  9. - 1.向上造型(向上转型):**多态本身就是子类类型向父类类型的转换** - 默认
  10. - 格式:父类类型 变量名 = new 子类对象();
  11. 2.向下转型:一个已经向上转型的子类对象可以**使用强制类型转换**的格式,将父类引用转为子类引用
  12. - 格式:子类类型 变量名 = (子类类型)变量名;
  13. **注意:**<br />在强制类型转换的时候,必须是什么对象就转换为什么对象!<br />如果使用错误,使用了其他类型的对象,那么编译期不会报错,但是在运行期会报错(造型异常)<br />java.ClassCastException--表示**造型异常**
  14. ```java
  15. package duotai_02;
  16. /**
  17. * @author Lynn
  18. * @create 2020-12-01-15:22
  19. */
  20. /**
  21. * 演示向下造型
  22. *
  23. * 其实向下造型是多态的一种实现方式
  24. * 多态的实现:
  25. * 1.向上造型(向上转型):多态本身就是子类类型向父类类型的转换 - 默认
  26. * 格式:父类类型 变量名 = new 子类对象();
  27. * 2.向下转型:使用起那个值类型转换
  28. * 格式:子类类型 变量名 = (子类类型)变量名;
  29. *
  30. *
  31. */
  32. public class SubClassType {
  33. public static void main(String[] args) {
  34. //创建子类对象
  35. Person p=new Person();
  36. p.eat();
  37. p.sleep();
  38. p.work();
  39. p.study();
  40. System.out.println("-------------------------");
  41. //使用向上造型--展现出来的是父类中的功能
  42. Animal a=new Person();
  43. //调用的是父类中的方法,结果是子类中重写后的方法
  44. a.eat();//吃饱饭踏实
  45. a.sleep();//吃饱饭踏实
  46. // a.work();//调用不到
  47. System.out.println("------------向下转型-----------------");
  48. Animal a1=new Dog();//向上造型
  49. /*Person p1=(Person)a1;//向下转型---强制类型转换--
  50. //造型异常(把狗造成人,不通)--对象在运行期产生的
  51. p1.eat();
  52. p1.sleep();*/
  53. //正确的向下转型---注意类型
  54. Dog d1=(Dog)a1;
  55. d1.eat();//吃骨头
  56. d1.sleep();//睡在地上
  57. /**
  58. * 在强制类型转换的时候,必须是什么对象就转换为什么对象!
  59. * 如果使用错误,使用了其他类型的对象,那么编译期不会报错,但是在运行期会报错(造型异常)
  60. * java.ClassCastException--表示造型异常
  61. */
  62. /* System.out.println("-------------拓展------------------");
  63. //调用feed方法
  64. feed(new Person());//传一个Animal的子类对象
  65. feed(new Dog());//传一个Animal的子类对象
  66. // feed(new Animal() //Animal是一个抽象类不能被实例化*/
  67. }
  68. /*//封装一个方法,用于灵活地调用所有的方法---传入参数是一个父类
  69. public static void feed(Animal a){//a是Animal的引用,可以接收Animal中所有的子类对象
  70. //调用该动物吃饭的方法
  71. System.out.println("feed方法内");
  72. a.eat();
  73. }*/
  74. }

image.png

解决造型异常的方案:

使用一个instanceof关键字来判断某个对象是不是属于某种类型
最后会返回true或false,进行了对象的判断后就可以保证

使用格式:
boolean b = 对象 instanceof 数据类型;

Person p1 = new Student(); // 前提条件,学生类已经继承了人类
boolean flag = p1 instanceof Student; //flag结果为true
boolean flag2 = p2 instanceof Teacher; //flag结果为false

  1. public class SubClassType {
  2. public static void main(String[] args) {
  3. System.out.println("------------向下转型-----------------");
  4. //狗
  5. Animal a1=new Dog();
  6. method(a1);
  7. //人
  8. Animal a2=new Person();
  9. method(a2);
  10. }
  11. //封装一个方法用于判断这个类型
  12. public static void method(Animal a){
  13. //如果是狗,就看门,如果是人就学习工作
  14. if(a instanceof Dog){
  15. //强制转换成狗
  16. Dog d=(Dog)a;
  17. d.kanmen();
  18. }
  19. if(a instanceof Person){
  20. //强制转换成人
  21. Person p=(Person)a;
  22. p.study();
  23. p.work();
  24. }
  25. }
  26. }

多态的好处:

  • 大大提高了程序的扩展性
  • 提高了程序的复用性