java中的多态
多态,是面向对象的程序设计语言最核心的特征。
多态就是对象的多种形态,分为两个方面:
1.引用的多态 :父类的引用可以指向本类的对象 Animal obj1 = new Animal ();
父类的引用可以指向子类的对象 Animal obj2 = new Dog();
但是一定要注意,不能子类的引用指向父类的对象,否则会出错。
Dog obj3 = new Animal (); //这是错误的,报错
2.方法的多态: 创建本类对象时,调用的方法为本类方法
创建子类对象时,调用的方法为子类重写的方法或者继承的方法
如在父类Animal中创建一个eat()方法:

然后在子类Dog中重写这个eat()方法:

这时,我们用obj1.eat()则是调用了父类中的方法:

然后,我们再用obj2.eat()则是调用了子类中的方法:

以上,我们便称之为方法的多态,但是还有一种特殊的多态,如我们再创建一个子类Cat

我们再调用eat()方法,则是子类继承父类的方法:

另外,如果我们在子类中自定义一个watchDoor()方法,这个方法不是从父类继承来的:

这时候我们调用这个watchDoor()是不行的.

多态中的引用类型转换:
首先我们要知道什么是引用类型转换:

可以看出由大类型转换为小类型时是有风险的,那么如何避免这种风险的,我们可以用instanceof运算符进行转换,Java 中的instanceof 运算符是用来在运行时指出对象是否是特定类的一个实例。instanceof通过返回一个布尔值来指出,这个对象是否是这个特定类或者是它的子类的一个实例。
用法:
result = object(任意对象表达式) instanceof class(任意已定义的对象类)
说明:
如果 object 是 class 的一个实例,则 instanceof 运算符返回 true。如果 object 不是指定类的一个实例,或者 object 是 null,则返回 false。
当父类的引用指向子类对象时或者子类的引用指向该对象时,是没有问题的.而如果将父类的引用转换为子类的引用,那么这是有风险的.编译器是不允许这样做的.
而如果我们利用强制类型转换
Dog dog = new Dog();
Animal animal = dog; //自动类型提升,向上类型转换
Dog dog = (Dog)animal; //向下类型转换,强制转换
Cat cat = (Cat)animal; //编译时Cat类型,执行时是Dog类型
虽然此时,没有报错,但是当我们运行时,却出现了问题:

此时就可以利用instanceof运算符避免类型转换的安全性问题:

网友评论