1.Java多态——编译看左边,运行看右边
成员变量、静态方法看左边;非静态方法,编译看左边,运行看右边。
当父类变量引用子类对象的时候,即Fu f = new Zi();在这个引用变量f指向的对象中,它的成员变量和静态方法与父类是一致的;它的非静态方法,在编译的时候与父类是一致的,运行时与子类是一致的(发生了复写)。
Fu
package com.itcast_06;
public class Fu {
int num = 5;
static void method1(){
System.out.println("fu类中的method1");
}
void method2(){
System.out.println("fu类中的method2");
}
}
zi
package com.itcast_06;
public class Zi extends Fu{
int num = 8 ;
static void method1(){
System.out.println("zi method1");
}
void method2(){
System.out.println("zi method2");
}
}
DuoTaiDemo
package com.itcast_06;
public class DuoTaiDemo {
public static void main(String[] args){
Fu f = new Zi();
System.out.println(f.num);//5,与父类一致
f.method1();//fu类中的method1,与父类一致
f.method2();//zi method2,编译时与父类一致,运行时与子类一致
Zi z = new Zi();
System.out.println(z.num);//8,与zi类中的method一致
z.method1();//zi method1
z.method2();//zi method2
}
}
输出结果
5
fu类中的method1
zi method2
8
zi method1
zi method2
2.分析
Fu f =new Zi();
首先了解变量Fu到底是什么,把这句话分两段:Fu f;这是声明一个变量f为Fu这个类,知道了f肯定为Fu类。然后我们f = new Zi();中创建一个子类对象赋值给了f,结果是什么?结果是拥有了被Zi类函数覆盖后的Fu类对象f。
也就是说只有子类函数覆盖了父类函数这一个变化,但是肯定是Fu这个类,也就是说f不可能变成其他比如Zi这个类等等。所以f代表的是函数被复写后(多态的意义)的一个Fu类,而父类原有的成员变量没有任何变化。即成员变量编译和运行都看Fu。
但是对于f的Fu类函数被复写了,非静态方法编译看Fu,运行看Zi。
对于静态方法:编译和运行都看Fu。因为对静态变量而言,Fu类的所有函数都跟随Fu类加载而加载了。也就是Fu类的函数是先于对象的创建之前就已经存在了,无法被后出现的Zi类对象所复写,所以没有发生复写现象。