衆所周知,java的多態有三種實現形式。一種是經過方法重載,一種是實現藉口,一種是繼承父類。固然這只是簡便說法,好比繼承裏面要有多態,必須有方法重寫,且有父類對象指向子類實例。下面就是我作的測試java
public class ExtendTest { public static void main(String[] args) { Father father = new Child();//Java polymorphism father.fatherMethod(); father.publicMethod(); // father.childMethod();//error, parent class can not access child method "childMethod". Child.staticMethod();//render static method using class name directly. Father.staticMethod();//render static method using class name directly. } } class Father { //1, before initialize. static { System.out.println("father pre static method."); } //3, constructor method. public Father() { System.out.println("father constructor initialized."); } private void privateMethod() { System.out.println("father private method."); } public void fatherMethod() { privateMethod();//this is the way to render private method in parent class System.out.println("father self method."); } public void publicMethod() { System.out.println("father public method."); } public static void staticMethod() { System.out.println("father static method."); } } class Child extends Father { //2, before initialize. static { System.out.println("child pre static method."); } //4, constructor method. public Child() { System.out.println("child constructor initilized."); } public void childMethod() { System.out.println("child slef mehtod."); } @Override public void publicMethod() { System.out.println("child public method."); } //@Override //error, static method can not be overrided. public static void staticMethod() { System.out.println("child static method."); } }
輸出結果以下:ide
father pre static method. child pre static method. father constructor initialized. child constructor initilized. father private method. father self method. child public method. child static method. father static method.
想必這仍是比較好理解的。測試
下面是一個略微有些妖的關於繼承的問題:this
public class ExtendTestPro { public static void main(String[] args) { A a1 = new A(); A a2 = new B(); B b = new B(); C c = new C(); D d = new D(); System.out.println(a1.show(b));//A and A System.out.println(a1.show(c));//A and A System.out.println(a1.show(d));//A and D System.out.println(a2.show(b));//B and A System.out.println(a2.show(c));//B and A System.out.println(a2.show(d));//A and D System.out.println(b.show(b));//B and B System.out.println(b.show(c));//B and B System.out.println(b.show(d));//A and D } } class A { public String show(D obj) { return ("A and D"); } public String show(A obj) { return ("A and A"); } } class B extends A { public String show(B obj) { return ("B and B"); } public String show(A obj ){ return ("B and A"); } } class C extends B {} class D extends B {}
第一個輸出其實就體現了java的多態了。a1.show(b)輸出的是"A and A",由於A類裏面沒有public String show(B obj){}這樣的方法,因此這裏把b類強轉成了A類,相似這樣:A a = (A)b; 因此調用的是public String show(A obj){}方法。spa
第四個a2.show(b)爲何輸出"B and A"?這應該就是最妖的一個了。首先要理解A a2 = new B(); 這句話作了什麼。其實它是建立了兩個對象,一個A對象a2,一個B對象,而a2是指向B對象的。因此歸根結底a2仍是個A(父類)對象,不能調用子類新定義的方法。因此當走到a2.show(b)的時候,它其實去調用的是public String show(A obj){}方法,而剛好這個方法被子類B重寫了,因此輸出"B and A"。code
第八個之因此輸出"B and B" 而不是 "B and A",是由於它只會去找它最近的父類來強轉它。好比這裏的c對象,就會用B類來轉,而不是A類。對象