2008-11-05 82 views
11

我從一個名爲ILogin的通用接口開始。這些接口要求您實現兩個屬性:UserID和Password。我有許多實現此接口的登錄類類。隨着我的項目不斷壯大,我發現許多類重複了UserID和Password代碼。現在我決定我需要一個基本的登錄類。同時擁有抽象類和接口是否有好處?

創建一個實現ILogin接口的抽象基類Login類並且讓我所有的具體類只是從抽象類繼承並在必要時被重寫是否合適?原本我認爲這不會有問題。然後我開始認爲ILogin可能不需要,因爲它可能只會被我的抽象類實現。

保持抽象類和接口都有好處嗎?

謝謝!

回答

15

當然。我們來看一個具體的例子。

假設我們有一個抽象類Animal。 說,我們做一些小類Cat,Dog,MosquitoEagle。我們可以實現其抽象類AnimalEat(),Breathe(),Sleep()方法。

到目前爲止,這麼好。現在,假設我們想爲MosquitoEagle類使用Fly()方法。由於這兩種生物並不是真正相關的(一個是鳥,另一個是昆蟲),爲這兩個人提供一個共同的祖先並不容易,因爲我們可以把它們看作一個抽象類。這最好通過接口IFly來實現。

IFly接口可以有一個Fly()方法來實現。既MosquitoEagle類都可以是抽象類Animal的子類,並實現接口IFly並能夠Eat()Breathe()Sleep()Fly()無需某種類型的兩個類之間奇數ancenstral關係。

1

如果抽象類具有功能,保留它是明智的。但是如果它只包含抽象方法而沒有字段。我認爲兩方面都沒有用。

編輯:我使用大量抽象類來處理遺留代碼。如果我有時間,我會添加接口,(可能刪除空的摘要)。因爲使用接口極大地增強了可能性。他們通過準確定義界面來尊重他們的名字。

4

我通常在對抽象類進行編碼並且在每個類(抽象或非抽象)中實現(並在外部合約彙編/庫中創建)接口時,我可以更輕鬆地實現Windows Communication Foundation或在必要時實現Windows Communication Foundation或inversion of control (這幾乎總是嘲笑)。這已成爲我的第二天性。

+0

+1:沒有絕對(即使是這種說法!)。 – 2008-11-06 00:24:00

2

絕對。接口總是正確的方式 - 這種方式可以實現它(包括已經有父母的東西)。

抽象類傾向於使它,所以你不必重新實現一些功能的一部分。 Swing使用它一點,他們將有一個接口,然後默認實現爲你重寫5個方法中的一個,或者它可能會爲你添加監聽器,但是你不必使用那個基類不想。

2

如果你的抽象類是只有類將永遠實現接口,那麼你總是可以檢查抽象類的實例,你不需要接口。但是,如果您希望與尚未編寫的新類未來兼容,這些類將不會擴展抽象類,但可以使用該接口,請立即繼續使用該接口。

1

我同意cfeduke。我總是從接口入手,過去曾使用抽象類來實現接口,並提供基本的功能來促進繼承自抽象類的類之間的代碼重用。嘲笑和國際奧委會通常都是依賴於接口的,因爲這個原因,我會在我的設計中使用接口。

0

我總是建議你使用接口。抽象類的優點是可以添加默認功能,但要求用戶使用他們的單一繼承是非常積極的。

在很多情況下,Microsoft類庫都傾向於接口上的抽象類,因爲它允許它們修改底層類。向抽象類中添加方法很少會破壞從中繼承的某個方法。向接口添加一個方法總是會破壞它的實現者。但是,這提供了使用接口的最佳理由之一:微軟可能已經用完了你的一個繼承的可能性很大。

但是,我會建議,在您的具體情況下,您可能希望重溫您使用的設計模式。有很多「登錄類」類似乎很少見。

+0

所有登錄類都有用戶名和密碼。更具體的登錄類型(如sqllogin)將擴展這個類型,並具有數據庫,批准,批准,可信連接等。有許多類型。 – 2008-11-05 23:21:05

0

我認爲保持接口的好處是未來的類能夠實現多個接口,而一個類只能從一個抽象類繼承。

您可以通過使用不同的方法集創建新接口來擴展子類的功能。

1

您的接口定義了要接受的對象必須滿足的合同;您的抽象類定義了必須履行的合同並定義了一些具體的實現細節。

想想這樣;如果你認爲任何人都希望以不同於抽象類繪製出來的方式(例如,使用不同的支持數據類型實現)完成契約,那麼你應該同時擁有接口和抽象類實現這一點。

抽象類和接口幾乎沒有任何開銷;這種方法面臨的風險主要涉及後來的編碼器,而不是意識到有一個抽象類實現了接口,並從零開始創建了一個完全不需要的實現。我會說,這可以通過在接口文檔中指定在抽象類中有一個「默認」接口實現來實現;雖然有些編碼標準可能會對這種做法感到不滿,但我沒有看到任何實際問題。

0

假設您具體詢問接口和抽象類是否具有相同的簽名...

...(如果界面的成員與抽象類的成員有任何不同,當然答案是肯定的,可能需要兩者)

...但假設成員是相同的,那麼我能想到的唯一理由就是如果你在一個不允許多重實現繼承的系統中編碼,系統中有兩個類需要多態相似,但必須從不同的基類繼承。