10

這還不是關於抽象類和接口之間區別的另一個問題,所以在投票結束前請三思。接口是多餘的繼承?

我知道,接口在那些不支持多繼承的OOP語言中很重要 - 比如C#和Java。但那些多重繼承呢?在一個具有多重繼承的語言中,接口的概念(作爲一種特定的語言特徵)是多餘的嗎?我猜想,類之間的OOP「契約」可以使用抽象類來建立。

或者,更明確地說,C#和Java中的接口只是它們不支持多重繼承的結果嗎?

+0

不確定你在這裏釣魚什麼:正如Bozho所說,接口是一個語言級別的對衝對象,通過爲過去抽象的方法提供一個實現來改變一個類的行爲,這是意想不到的。 – 2010-12-10 16:19:58

+0

問題是MI語言確實需要對衝或不對衝(例如,參見Ken的評論),我也希望能夠從Java/C#陣營以外得到另一種意見 – 2010-12-10 16:32:44

回答

7

...缺少多重繼承 強迫我們添加的 接口的概念...

所以是的,我相信在多重繼承下接口是多餘的。您可以在支持多重繼承或混合的語言中使用純粹的抽象基類。

這就是說,大部分時間我都很滿意單一遺傳。 Eric Lippert在同一卷(第10頁)中提到了單點繼承的選擇「......一次性消除了許多複雜的角落案例......「

8

根本不是。接口定義契約而不指定實現。

即使存在多重繼承,也需要它們 - 繼承關於實現。

從技術上講,您可以在多繼承中使用抽象類來模擬接口。但是,人們可能傾向於在那裏寫一些實現,這會造成很大的混亂。

+1

我不明白,如果有文件證明它是並且應該仍然是一個接口,爲什麼會傾向於添加一個實現?如果聲明是今天有可能在語義上做出正確的事情,然後有人可能稍後修改它,使得一個大混亂,是不是真的每種語言功能? – Ken 2010-12-02 16:13:35

+0

它是否意味着,例如,C++患有沒有接口? – 2010-12-02 16:29:30

+2

關於C++ - 這是主觀的。我沒有經驗來判斷它是否受損。 @肯 - 濫用東西越難,越好。 – Bozho 2010-12-02 16:35:59

1

接口是優選多重繼承自繼承根據「有效的Java」項目16,Favor composition over inheritance.

8

取決於測試冗餘違反了封裝。

如果測試是「這個任務可以在沒有語言特徵的情況下實現」,那麼類本身就是多餘的,因爲沒有類的圖靈競爭性語言。或者,從工程基礎來看,超出機器代碼的任何東西都是多餘的。

實際上,測試是語法和語義的更微妙的組合。如果它不改善語言的語法或語義,那麼在合理數量的用途中,它是多餘的。

在進行區分的語言中,支持接口聲明一個類知道如何以某種方式進行交談。從另一個類繼承(並且可能擴展或修改)另一個類的功能。

由於這兩項任務在邏輯上並不相同,我認爲接口不是多餘的。區分這兩者可以改進大量程序的語義,因爲它可以更具體地指示程序員的意圖。

2

好吧,如果你這樣做,你可以說C和C++,C#和其他高級語言都是多餘的,因爲你可以使用程序集編寫任何你想要的代碼。當然,你不需要絕對需要這些高級語言,但是,他們幫助...很多。

所有這些語言都附帶有各種實用程序。對於其中的一些,界面概念就是其中的一個。所以,是的,在C++中,你可以避免使用接口而不用實現的抽象類。事實上,如果你想用C編寫微軟的COM程序,儘管C不知道接口的概念,但你可以這樣做,因爲它們都是。.h文件定義接口是這樣的:

#if defined(__cplusplus) && !defined(CINTERFACE) 
    MIDL_INTERFACE("ABCDE000-0000-0000-0000-000000000000") 
    IMyInterface : public IUnknown 
    { 
    ... 
    } 
#else /* C style interface */ 
    typedef struct IMyInterfaceVtbl 
    { 
     BEGIN_INTERFACE 

     HRESULT (STDMETHODCALLTYPE *SomMethod)(... ...); 

     END_INTERFACE 
    } IMyInterfaceVtbl; 

    interface IMyInterface 
    { 
     CONST_VTBL struct IMyInterfaceVtbl *lpVtbl; 
    }; 
#endif 

某種類型的另一個語法糖...

而且它確實可以說,在C#中,如果我沒有接口的概念,我不知道我真的可以編碼:)。在C#中,我們絕對需要接口。

4

是在C#和Java接口只是一個事實,即他們根本不 支持多重繼承 後果是什麼?

是的,他們是。至少在Java中。作爲一種簡單的語言,Java的創建者需要一種大多數開發人員無需廣泛培訓就能掌握的語言。爲此,他們努力使語言儘可能與C++類似(熟悉),而不必承擔C++不必要的複雜性(簡單)。 Java的設計人員選擇通過使用接口來允許多接口繼承,這是從Objective C的協議中借用的一個想法。 See there for details

而且,是的,我相信就像在C++中的接口是多餘的,如果你有多重繼承。如果你有更強大的功能,爲什麼要保留更少的?

5

有些支持多繼承的語言不包含Java接口的並行概念。艾菲爾就是其中之一。伯特蘭梅耶沒有看到他們的需要,因爲有能力定義一個延期的類(這是大多數人稱之爲抽象類的東西)與一個充實的合同。

缺乏多重繼承可能會導致程序員需要創建實用程序類或類似程序的情況,以防止在實現相同接口的對象中編寫重複代碼。

這可能是合同的存在是一個重大貢獻,缺乏一個完全實現自由的接口概念....合同是很難寫沒有一些實施細節來測試。

因此,技術上接口在支持MI的語言中是冗餘的。

但是,正如其他人指出的......多次繼承可能是一個非常棘手的事情,使用正確,所有的時間。我知道我不能......而我在爲Meyer工作時,他正在起草面向對象軟件構建第2版。