多态性的理解:
何为多态性:
在Java中的体现为对象的多态性:父类的引用指向子类的对象(或子类的对象赋给父类的引用)。
- 可以直接应用在抽象类和接口上
举例:
Person p = new Man();———Man是Person的子类;
作用:
提高了代码的通用性,常称作接口重用
注意:
- 多态性的使用前提:① 需要存在继承或者实现关系 ② 方法的重写
- 对象的多态性,只适用于方法,不适用于属性(属性:编译和运行都看左边)
- 在多态中,父类对象不能调用子类特有的方法和属性;只能调用父类中声明的方法(未重写时)或子类重写父类的方法;
- 有了对象的多态性以后,内存中实际上是加载了子类特有的属性和方法的,但是由于变量声明为父类类型,导致编译时,只能调用父类中声明的属性和方法。子类特有的属性和方法不能调用。如何才能调用子类特的属性和方法?应使用向下转型。
虚拟方法调用(Virtual Method Invocation):
- 子类中定义了与父类同名同参数的方法,在多态情况下,将此时父类的方法称为虚拟方法,父类根据赋给它的不同子类对象,动态调用属于子类的该方法。这样的方法调用在编译期是无法确定的。
Java引用变量有两个类型:
- 编译时类型和运行时类型
- 编译时类型由声明该变量时使用的类型决定,运行时类型由实际赋给该变量的对象决定。简称:编译时,看左边;运行时,看右边。
- 若编译时类型和运行时类型不一致,就出现了对象的多态性(Polymorphism) (我们在编译期,只能调用父类中声明的方法,但在运行期,我们实际执行的是子类重写父类的方法。)
- 多态情况下
“看左边” :看的是父类的引用(父类中不具备子类特有的方法)
“看右边” :看的是子类的对象(实际运行的是子类重写父类的方法)
向上转型与向下转型:
- 向上转型(upcasting):子类可看做是特殊的父类,所以父类类型的引用可以指向子类的对象。(即多态)
- 向下转型:使用强制类型转换符:()
注:
- 从子类到父类的类型转换可以自动进行
- 从父类到子类的类型转换必须通过造型(强制类型转换)实现
- 无继承关系的引用类型间的转换是非法的
- 使用强转时,可能出现ClassCastException的异常。在造型前可以使用instanceof操作符测试一个对象的类型
instanceof 操作符
x instanceof A:检验x是否为类A的对象,返回值为boolean型。
- 要求x所属的类与类A必须是子类和父类的关系,否则编译错误。
- 如果x属于类A的子类B(即:A是x的间接父类),x instanceof A值也为true。
多态笔试题:
public static void main(String[] args) {
Base base = new Sub();
// 多态:调用子类重写方法
base.add(1, 2, 3);// sub1
Sub s = (Sub) base;
s.add(1, 2, 3);// sub2
}
class Base {
public void add(int a, int... arr) {
System.out.println("base");
}
}
class Sub extends Base {
// 与父类base中的add方法构成重写
public void add(int a, int[] arr) {
System.out.println("sub_1");
}
// 与add(int a, int[] arr)构成重载,且优先调用此方法
// 与父类base中的add方法构成重载
public void add(int a, int b, int c) {
System.out.println("sub_2");
}
}