多态的访问特点:
除了非静态方法以外,其他的变量和方法都是编译在父类中找方法,运行也在父类中找方法。
非静态方法:编译时在父类中找方法,运行时在子类中找方法,找不到再向父类中找
多态的几种表现形式:
普通父类多态:
public class Fu{} public class Zi extends Fu{} public class Demo{ public static void main(String[] args){ Fu f = new Zi();//左边是一个“父类” } }
抽象父类多态:
public abstract class Fu{} public class Zi extends Fu{} public class Demo{ public static void main(String[] args){ Fu f = new Zi();//左边是一个“父类” } }
父接口多态:
public interface A{} public class AImp implements A{} public class Demo{ public static void main(String[] args){ A a = new AImp(); } }
多态的应用场景:
变量多态:可以通过继承实现,意义不大
形参多态:
// 2.形参多态 Dog dog = new Dog(); invokeEat(dog); Cat cat = new Cat(); invokeEat(cat);// 实参赋值给形参: Animal anl = new Cat(); // 形参多态: 当你调用invokeEat方法的时候,传入Animal类的子类对象 // Animal anl = dog; ====> Animal anl = new Dog(); // 结论:如果方法的参数是父类类型,那么就可以接收所有该父类对象以及其所有子类对象 // Object类:是java中所有类的父类,所以如果参数为Object类型,那么就可以传入一切类的对象 public static void invokeEat(Animal anl){ anl.eat(); }
返回值多态:
// 3.返回值多态 Animal anl2 = getAnimal();// 返回值赋值给变量: Animal anl2 = new Dog() } // 3.返回值多态 // 结论:如果方法的返回值类型为父类类型,那么就可以返回该父类对象以及其所有子类对象 public static Animal getAnimal(){ // return new Animal(); return new Dog(); // return new Cat(); }
引用类型转换:
多态的弊端:多态的情况下,只能调用父类的共性内容,不能调用子类的特有的功能
所以出现了多态引用类型转换的方式。
向上转型:就是多态的写法,这个过程是默认的
向下转型:父类类型向子类类型向下转换,这个过程是强制的
Aniaml anl = new Cat(); Cat c = (Cat)anl;//向下转型 c.catchMouse();// 可以访问 子类独有的功能,解决多态的弊端
在向下转型的时候是有风险的,所以要进行验证:
instanceof关键字:
变量名 instanceof 数据类型 如果变量属于该数据类型,返回true。 如果变量不属于该数据类型,返回false。 if( anl instanceof Cat){//判断anl是否能转换为Cat类型,如果可以返回:true,否则返回:false Cat c = (Cat)anl;//安全转换 }