[英]Java abstract class implements an interface, both have the same method
在看一些OOP資料時,我想到了這個讓我有些困惑的問題:
考慮具有以下接口,抽象類和具體類:
package one;
public interface A {
void doStuff();
}
package one;
public abstract class B implements A {
public abstract void doStuff();
}
class C extends B{
public void doStuff() {
}
}
除非它提供方法doStuff()
的實現,否則C類不會編譯。 這里的問題:
1- C類中的doStuff()
方法是接口A方法的實現,還是B類中抽象方法的實現? 更具體地講:JVM如何將函數作為接口或抽象類的調用函數處理?
2-是否將抽象類B中的抽象方法doStuff()
視為接口A中 doStuff()
方法的“實現”? 因此這使得類C必須實現抽象類的doStuff()
而不是接口的版本?
對於問題1:C類中的doStuff方法是對B和C的doStuff方法聲明的實現。這是因為抽象類B和接口A中的doStuff方法聲明具有相同的簽名。 實際上,如果B實現了C,則無需再次聲明doStuff方法。
對於問題2:否,B中的doStuff只是一個聲明,而不是方法實現。 如果B沒有方法實現或附加的方法聲明,則它不需要類B。基本上,抽象類是一種模板,為方便其子類而包含高級邏輯。
例如,對於B類,C.doStuff()覆蓋B.doStuff()並實現A.doStuff()。 Java中的所有方法都是虛擬調用的。 實際上,對於C.doStuff()覆蓋B的方法還是A的方法,用戶沒有任何區別。 對於jvm,它將有所不同,因為基於接口的調用與基於類的調用不同。
UPD:這取決於您從中調用的鏈接的類型。 :不同opcoded將由javac的生成invokevirtual或invokeinterface
在接口中,所有方法都是public
和abstract
。
知道這一點,接口A的doStuff 實際上是 public abstract void doStuff()
。 哪個應該看起來很熟悉,因為Abstract Class B具有相同的方法簽名。
為了回答問題1,類B的doStuff()
與接口A的doStuff()
。 由於Java中的所有方法都是虛擬方法,因此無論您的C是聲明為A,B還是C,調用doStuff()
都是相同的。
至於問題2,不。 B的doStuff()
是實際上沒有執行任何操作的冗余代碼。 C被執行A的doStuff()
乙是否聲明doStuff()
如果刪除
public abstract void doStuff();
在您的抽象類中,繼承該類的子代必須實現此方法。
嘗試在B類中刪除此方法,然后在C類中查看結果
請參見http://docs.oracle.com/javase/tutorial/java/IandI/abstract.html中的“當抽象類實現接口時”部分。
我認為您可以在此處找到所需的解釋。
問題1:C類中的方法同時實現。 但是,由於它僅擴展B,因此僅需要實現B抽象方法和未實現的接口。
問題2:它不被視為實現。 抽象類不必實現所有接口方法。 C類的實現是強制性的(即使B類中沒有抽象的實現)。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.