2012-08-07 77 views
0

我有一個抽象類說CTest其中只包含抽象方法f1()而沒有別的。同樣,我有一個接口ITest與唯一的方法f1()。在這裏CTest抽象類和ITest接口都做同樣的事情。在這裏使用什麼,抽象類或接口?

一個區別是,,接口提供了靈活性,它可以在任何已經從其他類派生的類中實現,但抽象類不能。

除了上述差異之外,這兩者之間的實際區別是什麼?哪一個在這裏有效(CTest或ITest)?當我應該使用什麼? OO設計中的任何特定場景以及對此的任何一般暗示都很有幫助

+0

你一定很好奇_efficiency_?在Java中,接口方法調用在內部使用['invokeinterface'](http://docs.oracle.com/javase/specs/jvms/se7/html/jvms-6.html#jvms-6.5.invokeinterface)指令,它是[相對昂貴](http://stackoverflow.com/a/1505476/591495)到['invokevirtual'](http://docs.oracle.com/javase/specs/jvms/se7/html/jvms-6。 HTML#的JVM-6.5.invokevirtual)。 – oldrinb 2012-08-07 05:39:09

+0

看看這可能會幫助你..http://stackoverflow.com/questions/1913098/what-is-the-difference-between-an-interface-and-abstract-class – 2012-08-07 05:42:39

回答

0

對於我來說,最好在這裏使用的界面。當你可以在那裏提取一些代碼時(你可以實現方法或者有其他想調用它的東西),就應該使用抽象類。

0

在這種情況下,假設您的抽象類只包含抽象方法,在我看來,您應該使用接口。具有抽象方法和接口的抽象類可以達到同樣的目的,但是,只能擴展一個類,但實現的數量可以任意多,因此,如果您決定繼承某些其他類的某些功能,則會使代碼不易發生重大更改。

關於你的問題:但這兩者之間的實際區別是什麼?哪一個在這裏有效(CTest或ITest)?當我應該使用什麼? OO設計中的任何特定場景以及對此的任何一般暗示都是有幫助的

接口與契約類似,當類實現接口時,它保證了實現。當有人想提供功能但不想泄露內部代碼時,這通常會很有幫助,因此開發人員只會拋出接口,以便在不知道每種方法如何實現的情況下進行調用。你可以明顯地實現儘可能多的接口,只要你喜歡。

抽象類允許您創建一個具有某些特定行爲的類,這些行爲是指定的,還有一些類將在未來實現。然而,與接口不同,每個類只能擴展一個類,所以您應該從這個角度謹慎地擴展類。抽象類還允許您將行爲注入到一個類,並讓它自動通過其子類傳播。這通常使開發/維護的某些部分更容易。

+0

另一方面,您可以在不破壞現有代碼的情況下對抽象類進行更改。 MSFT的C#最佳實踐建議儘可能在設計系統時使用抽象類,以儘量減少未來突破性變化的需求。 – 2012-08-07 05:32:15

+0

@MichaelGraczyk:我同意,因此我在第一行中做了假設:*假定您的抽象類只包含抽象方法*。我將它添加到我的迴應的最後一部分,雖然 – npinti 2012-08-07 05:37:15

+0

@ Michael/npinti:我知道我們可以在不改變更改的情況下對抽象類進行更改,但在Interface中不可能。但是,如果你在現有的抽象類中添加一個抽象方法,它仍然會作爲接口斷開......它是否在這裏有任何差異或靈活性? – smhnkmr 2012-08-07 05:41:19

1

Java優選InterfacesAbstract Classes。請參閱第18項中有效的Java

enter image description here

要點

  • 現有的類可以retroffited實現一個新的接口。

  • 接口是定義mixin的理想選擇。

  • 接口允許構建非熱循環類型的框架。

  • 接口支持安全,強大的功能增強。

2

除繼承之外,它取決於場景。檢查this code project article是一個很好的例子。

[從文章]

讓我們假設你需要三類,首先是汽車,第二是 城域網,第三是女人。現在你需要在他們每個人中定義一個函數來定義 他們如何移動。現在,所有三個人都可以移動,但CAR完全以 不同於MAN和WOMAN的方式移動。所以在這裏我們使用一個接口 IMOVEMENT並在其中聲明一個函數MOVE。現在所有三個類都可以繼承這個接口 。所以班級就是這樣。

public interface IMovement 
{ 
    void Move(); 
} 

public class Car : IMovement 
{ 
    public void Move() 
    { 
     //Provide Implementation 
    } 
} 

public class Man : IMovement 
{ 
    public void Move() 
    { 
     //Provide Implementation 
    } 
} 

public class Woman : IMovement 
{ 
    public void Move() 
    { 
     //Provide Implementation 
    } 
} 

但是,因爲男人和一個女人走在類似的方式,因此提供相同 行爲在兩種不同的方法將代碼冗餘,在簡單的 字碼不重複使用。所以我們現在可以定義一個人類運動的抽象類,所以這個類可以是人類移動修改。同樣 相同可以適用於CAR類,因爲有很多 汽車製造商和所有汽車以類似的方式移動,所以我們也可以 定義汽車運動的抽象類可以CARSMOVEMENT。 所以我們重構的代碼將會是。

public interface IMovement 
{ 
    void Move(); 
} 

public abstract class CarsMovement : IMovement 
{ 

    public virtual void Move() 
    { 
     //default behavior for cars movement 
    } 
} 

public class SuzukiCar : CarsMovement 
{ 
    public override void Move() 
    { 
     //Provide Implementation 
    } 
} 

public abstract class HumanBeingMovement : IMovement 
{ 

    public virtual void Move() 
    { 
     //default behavior for human being movement 
    } 
} 

public class Man : HumanBeingMovement 
{ 
    public override void Move() 
    { 
     //Provide Implementation 
    } 
} 

public class Woman : HumanBeingMovement 
{ 
    public override void Move() 
    { 
     //Provide Implementation 
    } 
} 
+0

如果有人想知道,那些冒號用於替換「implements」關鍵字。 – edwga 2012-08-07 05:33:59

+0

@hamad:這個例子很好地解釋了接口和抽象類的用法。但就我而言,這兩者的實際區別是什麼?我應該使用哪一個? – smhnkmr 2012-08-07 05:46:16

+0

@mhn如果你想爲所有的派生類實現一些常用的功能,那麼你應該在你的情況下使用一個抽象類,如f1()。如果你讓f1虛擬,那麼這也可以被子類覆蓋。另一方面,接口描述了一組可以屬於任何類或結構的相關功能。如果沒有共同的功能,那麼你應該使用接口,因爲它通常被理解爲如果存在抽象類,那麼將會有一些虛擬方法。 – ABH 2012-08-07 07:13:52

0

在這種情況下沒有區別,但CTEST類有可能被繼承作爲一類的唯一類。但是ITest接口可以同時被其他類和接口繼承。

0

在你提到的場景中,只有一個方法,它沒有定義,最好的方法是界面。

接口在Java中提供的主要優勢是可以實現多個接口,但只能擴展一個類。所以,如果你已經擴展了一個抽象類,那麼你就沒有擴展任何其他類的選項。

黃金法則:接口比抽象類更好,如果我們只需要 定義方法,而不是申報。

話雖如此,接口在你的情況下更好,程序員也應該從未來的角度考慮他的代碼。你覺得你正在創建的類/接口將來會有更多的方法嗎?你想定義這些方法還是隻聲明?回答這些問題會讓你知道一個接口是否足夠或者需要一個抽象類。

0

優勢:

抽象類的實現比界面更好,因爲方法查找抽象類是不是接口快。如果你修改你的接口,你必須更新你的實現類,但對抽象類進行任何修改,對實現類沒有影響。

缺點:

If you want to implement more than one parent class method , it is not possible. 
But regarding to interface you can implement more than one.