1. 程式人生 > >【面試加分項】執行時多型與編譯時多型

【面試加分項】執行時多型與編譯時多型

相信大部分人都聽說過多型,對多型有過一些瞭解都知道多型的定義:指允許不同類的物件對同一訊息做出響應。即同一訊息可以根據傳送物件的不同而採用多種不同的行為方式。(傳送訊息就是函式呼叫)。但是很少有人會深入研究他,更少人會知道多型分為執行時多型和編譯時多型,如果在面試時你能答出這一點肯定可以然你的面試官對你刮目相看。下面就讓我們一起來學習一下多型這個磨人的小妖精。

1.多型基礎知識:

什麼是多型
面向物件的三大特性:封裝、繼承、多型。從一定角度來看,封裝和繼承幾乎都是為多型而準備的。這是我們最後一個概念,也是最重要的知識點。

多型的定義:指允許不同類的物件對同一訊息做出響應。即同一訊息可以根據傳送物件的不同而採用多種不同的行為方式。(傳送訊息就是函式呼叫)

實現多型的技術稱為:動態繫結(dynamic binding)

多型存在的三個必要條件
一、要有繼承;
二、要有重寫;
三、父類引用指向子類物件。

多型的好處:

1.可替換性(substitutability)。多型對已存在程式碼具有可替換性。例如,draw函式對圓Circle類工作,對其他任何圓形幾何體,如圓環,也同樣工作。
2.可擴充性(extensibility)。多型對程式碼具有可擴充性。增加新的子類不影響已存在類的多型性、繼承性,以及其他特性的執行和操作。實際上新加子類更容易獲得多型功能。例如,在實現了圓錐、半圓錐以及半球體的多型基礎上,很容易增添球體類的多型性。
3.介面性(interface-ability)。多型是超類通過方法簽名,向子類提供了一個共同介面,由子類來完善或者覆蓋它而實現的。如圖8.3 所示。圖中超類Shape規定了兩個實現多型的介面方法,computeArea()以及computeVolume()。子類,如Circle和Sphere為了實現多型,完善或者覆蓋這兩個介面方法。
4.靈活性(flexibility)。它在應用中體現了靈活多樣的操作,提高了使用效率。
5.簡化性(simplicity)。多型簡化對應用軟體的程式碼編寫和修改過程,尤其在處理大量物件的運算和操作時,這個特點尤為突出和重要。

2.執行時多型與編譯時多型

ps:其實從java多型的定義來說編譯多型並不能真正算做多型,有時候我們也叫他靜態多型性。ok,讓我們進入正題。
編譯時多型主要指的是函式的過載,例如有一個類這個C有一個方法F,但是同時存在F(int),和F(String),當我們的程式碼中有c.F(param)時,編譯器會將C類中說有名為F的方法和父類中屬性為public且名為F的方法。
接下來編譯器會檢視param的型別,比如c.F(“hello”)就會挑選F(String)而不是F(int),如果呼叫c.F(1),編對應的譯器就會選擇F(int)。如果挑選不到對應的方法或者多個方法對應就會報錯。
接下來我們看執行時多型性。
執行時多型性主要運用到動態繫結。就是在執行時動態的確定呼叫的是哪一個函式。比如:如果A有多個之類,每個子類都有f(Stirng)方法,當我們宣告一個A的物件a,對它用不同的子類進行不同的例項化。這樣這個方法可以產生不同的效果,也就是實現了多型。接下來讓我們看個具體的例子:


public class test {

    public static void main(String[] args) {
        A b=new B();
        A c=new C();
        A d=new D();
        D d2=new D();
        b.say();
        c.say();
        d.say();
        d2.say(1);
        d2.say(""); 
    }
}
abstract class A{
    public  abstract void say();
}
class B extends A{

    @Override
    public void say() {
        System.out.println("this is class b");

    }

}
class C extends A{

    @Override
    public void say() {
        System.out.println("this is class c");

    }
    public void say(boolean b){
        System.out.println("this is class c boolean");
    }

}
class D extends B{

    @Override
    public void say() {
        System.out.println("this is class d");

    }
    public void say(int i){
        System.out.println("this is class d int");
    }
    public void say(String string){
        System.out.println("this is class d string");
    }

}

執行結果
this is class b
this is class c
this is class d
this is class d int
this is class d string

大家可以對照之前的說明自行理解為什麼結果是這個,又不理解的可以評論中提出,我會盡快答覆。