多态的两种体现:
1.方法的重载(overload)和重写(overwrite)
2.对象的多态性–可以直接应用在抽象类和接口上
Java引用变量有两种类型,编译时类型和运行时类型。编译时类型由声明该变量时使用的类型决定,运行时类型由实际付给该变量的对象决定
编译时类型和运行时类型不一致就出现多态(对象的多态)
对象的多态–在Java中子类的对象可以替代父类的对象使用
一个变量只能有一个确定的数据类型
一个引用变量可能指向(引用)多种不同类型的变量
Person p=new Person();
Person e=new Student();//Person类型的变量e,指向Student类型的对象
子类可以看做特殊的父类,所以父类类型的引用可以指向子类的对象:向上转型
一个引用类型变量如果声明为父类的类型,但实际引用的为子类的对象,那么该变量就不能再访问子类中添加的属性和方法
Student m=new Student();
m.school=“pku”;//合法,Student类有school成员变量
Person e=new Student();
e.school=“puk”;//非法,Person类没有school成员变量
属性是在编译时确定的,编译时e为Person类型,没有school成员变量,因而编译出错。
虚拟方法调用
虚拟方法调用(多态情况下)
Person e =new Student();
e.showInfo();//调用Student的showInfo()方法
编译时类型和运行时类型(编译看左边运行看右边)
编译时e为Person类型,而方法的调用是在运行时确定的,所以调用的是Student类的showInfo()方法–动态绑定
java的方法是运行在栈内存中,在运行方法时会动态进栈和出栈
当前情况showInfo()是Student对象的方法
成员方法的多态性也就是动态绑定,必须存在于方法的重写之上
若子类重写了父类方法,就意味着子类里定义的方法彻底覆盖了父类里同名的方法,系统不可能把父类里的方法转移到子类中
(如果子类没有重写父类的方法,那么子类就直接使用父类的方法,如果子类重写了父类的方法,子类就使用自己重写之后的)
对于实例变量就不存在这样的现象,即使子类里定义了与父类完全相同的实例变量这个实例变量依然不可能覆盖父类中定义的实例变量
多态性应用举例:
public class Test {
public void method(Person e){
e.showInfo();
}
public static void main(String[] args) {
Test t=new Test();
Student m=new Student();
t.method(m);
}
}