java之多态
多态:方法或对象具有多种形态
有多态的前提是:两个对象有继承关系存在
1. 方法的多态:
a. 重载:可以在一个类中定义多个同名的方法,其参数类型、参数个数、返回值类型不同。
注:方法不能只有返回值类型不同
b. 覆写(重写):子类实现跟父类同样的方法(包括形参列表、方法名要完全一样;返回值可以一样,或者子类重写方法的返回值是父类的子类)
2. 对象的多态:
a. 一个对象的编译类型和运行类型可以不一致
b. 编译类型在定义对象是就确定了,不能改变
c. 运行类型是可以变化的
d. 编译类型看定义时 =号的左边,运行类型看 = 号的右边
如:Animal animal = new Dog();animal的编译类型是Animal,运行类型是Dog
animal = new Cat();animal的编译类型是Animal,运行类型是Cat
向上转型:父类的引用指向子类的对象,如Animal animal = new Dog();
特点:
1. animal可以调用父类(Animal)中所有的成员(遵守访问权限),不能调用子类(Dog)中特有的成员;
这是为什么呢?因为在编译阶段,对象引用(animal)能调用哪些成员,是由编译类型决定。
2. 最终的运行效果看子类(运行类型)的具体实现
如animal.eat(),在执行方法调用时,按照从子类Dog(运行类型)中开始查找eat方法(方法的重写),然后调用
向下转型:能调用子类中特有的成员
语法:子类类型 引用名 = (子类类型)父类引用;
如:Dog dog = (Dog)animal;dog的编译类型为Dog,运行类型为Dog,所以在编译时,dog能调用Dog中的成员
1. 只能强转父类的引用,不能强转父类的对象
2. 要求父类的引用必须指向的是当前目标类型的对象
如animal当前指向的是Dog对象,所以向下转型为Dog dog = (Dog)animal;不能是Cat cat=(Cat)animal
3. 可以调用子类中的所有成员
属性的重写:
属性没有重写之说,属性的值直接看编译类型。
instanceof操作符:
用来判断对象的运行类型是否为xx类型或xx类型的子类型
动态绑定机制:
1. 当调用对象方法的时候,该方法会和该对象的内存地址(也就是运行类型)绑定
2. 当调用对象属性时,没有动态绑定机制,哪里声明,哪里使用
public class DynamicBinding{ public static void main(String[] args){ A a = new B(); System.out.println(a.sum()); //子类中没有注释sum方法,输出40 /子类中注释掉sum方法,输出30 System.out.println(a.sum1()); //子类中没有注释sum1方法,输出30 /子类中注释掉sum方法,输出20 } } calss A{ public int i = 10; public int sum(){//当子类中注释掉sum方法,会由于继承机制,调用到父类中的sum方法; return getI()+10;//在这个方法中会调用getI方法,由于动态绑定机制,该方法会和该对象的内存地址(也就是运行类型)绑定,从而调用到子类的getI,所以输出30 } public int sum1(){//当子类中注释掉sum1方法,会由于继承机制,调用到父类中的sum1方法; return i+10;//在这个方法中会使用i属性,没有动态绑定机制,所以输出20 } public int getI(){ return i; } } calss B extends A{ public int i = 20; /* public int sum(){ return getI()+20; }*/ /* public int sum1(){ return i+10; }*/ public int getI(){ return i; } }