面向对象三大特性
什么是多态
同类型的对象
多态的表现形态
父类类型 对象名称 = 子类对象
多态的前提
有继承关系
有父类引用指向子类对象 (Fu f = new Zi();)
有方法重写
多态的好处 使用父类型作为参数,可以接受所有子类对象,体现多态的扩展性与便利
变量调用:编译看左边,运行也看左边 方法调用:编译看左边,运行看右边
public class Test { public static void main(String[] args) { Animal a1 = new Dog(); //调用成员变量:编译看左边,运行也看左边 //编译看左边:javac编译代码的时候,会看左边的父类中有没有这个变量,如果有,编译成功,如果没有,编译失败 //运行也看左边:java运行代码的时候,实际获取的就是左边父类中成员变量的值 System.out.println(a1.name);//动物 //调用成员方法:编译看左边,运行看右边 //编译看左边:Javac编译代码的时候,会看左边的父类有没有这个方法,如果有,编译成功,如没有,编译失败 //运行看右边:java运行代码的时候,实际上运行的是子类中的方法 a1.show();//Dog--show //理解 // Animal a1 = new Dog(); //现在用a1去调用变量的变量和方法 //而a是Animal类型的,所以默认都会从Animal这个类中去找 //成员变量:在子类的对象中,会吧父类的成员变量也继承下的。父:name 子:name //成员方法:如果子类对方法进行了重写,那么在虚方法表中是会把父类的方法进行覆盖的 } } class Animal{ String name = "动物"; public void show(){ System.out.println("animal--show"); } } class Dog extends Animal{ String name = "狗"; public void show(){ System.out.println("Dog--show"); } } class Cat extends Animal{ String name = "猫"; public void show(){ System.out.println("cat--show"); } }
多态调用成员的内存图解
在多态形式下,右边对象可以实现解耦合,便于扩展和维护
Person p = new Student();//修改时只需修改右边new的对象 p.work;//业务逻辑发生改变时,后续代码无需修改
定义方法的时候,使用父类型作为参数,可以接受所有子类对象,体现多态的扩展性与便利
不能调用子类的特有功能
public class Test { public static void main(String[] args) { Animal a = new Dog(); a.eat(); //为什么报错? //当调用成员方法的时候,编译看左边,运行看右边 //那么在编译的时候会先加成左边的父类中有没有这个方法,如果没有直接报错 // a.lookHome(); //解决方案: //变回子类类型就可以了 //注意:转换的时候不能瞎转,如果转成其他类的类型.就会报错 // Dog d = (Dog) a; // d.lookHome(); //有没有一种判断可以判断类型 //instanceof 你记录的这个变量是不是这个类型,如果是,则为true,如果不是,则为false // if (a instanceof Dog){ // Dog d = (Dog) a; // d.lookHome(); // } else if (a instanceof Cat){ // Cat c = (Cat) a; // c.catchMouse(); // } // 新特性,将判断和强转放在一起,jdk14之后出现 //先判断a是否为Dog类型,如果是,则强转成Dog类型,转换之后变量名为d //如果不是,则不强转,结或直接是false // if (a instanceof Dog d){ // 410 d.lookHome(); // } else if (a instanceof Cat c){ // c.catchMouse(); // } } } class Animal{ public void eat(){ System.out.println("动物吃东西"); } } class Dog extends Animal{ public void eat(){ System.out.println("狗吃骨头"); } public void lookHome(){ System.out.println("看家"); } } class Cat extends Animal{ public void eat(){ System.out.println("猫吃鱼"); } public void catchMouse(){ System.out.println("抓老鼠"); } }
1.多态的优势
方法中,使用父类型作为参数,可以接收所有子类对象
2.多态的弊端是什么
不能使用子类的特有功能
3.引用数据类型的类型转换,有几种方法
自动转换 Person p = new Studnet();
强制转换类型 Student s = (Student) p;
4。强制类型转换能解决什么问题
可以转换成真正的子类类型,从而调用子类独有功能
转换类型与真是类型不一致会报错
转换的时候用instanceof关键字进行判断(jdk14