java中的多態體如今重寫和重載上,重載就屬於靜態分派,而重寫屬於動態分派。那咱們先來弄清楚什麼是靜態類型,什麼是動態類型。例如:java
public class Son extends Father{} Father a = new Son();
對於以上代碼:Father屬於靜態類型,Son屬於動態類型。ide
所謂靜態類型是指在程序編譯期間就徹底肯定,而動態類型則是在程序運行期間才能夠肯定。spa
下面,咱們來看看一個靜態分派的例子:code
package fenixsoft; public class StaticDispatch { //父類 static abstract class Human{ } //子類1 static class Man extends Human{ } //子類2 static class Woman extends Human{ } /* * 三個重載的方法 */ public void say(Human guy){ System.out.println("hello,guy"); } public void say(Man guy){ System.out.println("hello,guy"); } public void say(Woman guy){ System.out.println("hello,guy"); } public static void main(String[] args){ StaticDispatch sd = new StaticDispatch(); Human man = new Man(); Human woman = new Woman(); sd.say(man); sd.say(woman); } }
這是這個例子的輸出結果:對象
hello,guy hello,guy
下面咱們來分析爲何會輸出這樣的結果:編譯器
因爲動態類型在編譯期間不可知,因此編譯器在編譯程序時並不知道純金的參數的實際類型是什麼,也就是說,在上面的例子中,編譯器不知道man和woman的實際類型,因此編譯器在重載時只能經過他們的靜態類型來肯定他們的類型。因此,java中重載時是經過參數的靜態類型,而不是實際類型(動態類型)做爲判斷依據的。對於此例來講,他們的靜態類型就是Human,因此輸出了這個結果。編譯
那咱們再來看一個動態分派的例子:class
package fenixsoft; public class DynamicDispatch { static abstract class Human{ protected abstract void say(); } static class Man extends Human{ @Override protected void say() { // TODO Auto-generated method stub System.out.println("man,hello"); } } static class Woman extends Human{ @Override protected void say() { // TODO Auto-generated method stub System.out.println("woman,hello"); } } public static void main(String[] args){ Human man = new Man(); Human woman = new Woman(); man.say(); woman.say(); } }
此例的輸出以下:引用
man,hello woman,hello
和靜態分派相反,動態分派是經過對象的實際類型做爲判斷依據的。因此java中的重寫是動態分派。就是在運行期間肯定接受者的實例類型,將類方法中的符號引用解析到了不一樣的直接引用上,這就是方法重寫的本質。程序