1. 程式人生 > >由為什麼介面中只能定義靜態常量引發的介面與抽象類的區別的問答

由為什麼介面中只能定義靜態常量引發的介面與抽象類的區別的問答

1、為什麼必須是靜態的:由於介面不能例項化,非靜態成員只能使通過例項呼叫,所以必須定義為static靜態的

2、為什麼抽象類也不能被例項化,但抽象類裡面可以定義非靜態的:

由於子類與抽象類的關係中,子類繼承(extends)抽象類,

java中,子類繼承父類,子類例項化,首先要執行父類的構造器,所以抽象類裡面有構造器,有構造器就有例項化,

只是這種例項化是比較特殊的例項化,也不能通過new建立例項,但是可以通過該特殊的例項化呼叫該抽象類裡面的非靜態欄位,通過下面的程式碼可以發現


public abstract class D {
//可以被子類訪問
protected int d2 = 1;
//獲得抽象類D的例項
public D getInstance(){
//可以使用this呼叫非靜態成員屬性,說明有例項化過程,此處輸出1
System.out.println(this.d2);
return this;
}
}

public class E extends D{
//子類重寫父類屬性,不會發生多型
private int d2 = 2;
public static void main(String[] args) {
E e = new E();
//java中的多型只發生在父類引用指向子類物件、子類重寫父類的方法的情況下;
//如果同樣是父類應用指向子類物件、子類重寫父類的屬性,則不會發生多型,呼叫的屬性還是父類的屬性
System.out.println(e.getInstance().d2);//輸出1,返回的是父類D的例項,
}
}

子類與介面之間的關係式implements實現,子類實現介面,無需先執行介面的構造器,

所以介面中無需提供構造器(也沒有語句塊),也就沒有例項化的過程,對於宣告一個需要通過例項訪問的非靜態屬性也就沒有意義了



3、為什麼要用final修飾為常量:

由於介面定義了一種協議、規範,所有子類都去實現該介面,如果將Field定義為static變數,不用final修飾,

所有實現類共享該Field,一個實現類修改該變數,所有實現類都將發生改變,所以必須用final修飾



4、為什麼使用抽象類:

抽象類為子類提煉出公共的方法,並提供一個或幾個抽象方法留給子類實現;

抽象類的設計體現了模板模式的設計思想,即抽象類公共的普通方法依賴一個抽象方法,而抽象方法則推遲到子類中實現細節



5、既然抽象類中既可以定義抽象方法,也可以定義普通方法,那為什麼使用介面,而介面中只能定義抽象方法:

介面定義的一種協議、規範,體現的是規範也實現分離的鬆耦合的設計思想;

同時使用介面是implements實現,子類可以實現多個介面,卻只能繼承一個父類(java中的單繼承機制);

所以子類繼承一個完全是抽象方法的抽象類導致不能再繼承其它類就沒有什麼意義了



ps:當然,抽象類與介面還有一些其它的區別,此處不一一詳盡說明,上述闡述可能有不合理之處,不過希望給相關困惑讀者一點思路