簡體   English   中英

標記界面與空抽象類

[英]Marker interface vs empty abstract class

我在使用標記接口或空抽象類之間做出決定時遇到困難。

我有兩個類BrokerResponseNotification ,它們沒有結構相似性。 連接它們的唯一方法是需要訂閱。

void register(Receivable receivable, BrokerObserver observer)

我不喜歡使用Marker Interface ,因為它違反了Interface的基本定義。 另一方面,使用abstract super類會讓我感到不舒服,因為這兩個類彼此沒有關系。

在這種情況下,通常更可取的方法是什么?為什么?

編輯1

我忘了提到, BrokerResponse本身就是一個抽象類,它有幾個子類來確定各自的類型。

抽象類與標記接口:

標記界面沒有任何問題,並且有一些用例。 選擇這兩者之間,標記界面具有更大的靈活性。

如果您確實要定義類型,請使用接口。

抽象類的目的是提供一個適當的超類,其他類可以從中繼承並共享一個共同的設計 - 您的類沒有共同的設計,也沒有什么可以共享。 此外,如果你將來需要為他們添加一個真正不同的父母,你會把它們都粘在一些有限的設計上並且不會那么靈活。

抽象類的用例列表:

  • 在幾個密切相關的類之間共享代碼。

  • 擴展抽象類的類具有許多常用方法或字段,或者需要除公共之外的訪問修飾符(例如protected和private)。

  • 聲明非靜態或非最終字段,使您能夠定義可以訪問和修改它們所屬對象的狀態的方法。

接口用例:

  • 不相關的類將實現您的接口。

  • 指定特定數據類型的行為,而不考慮誰實現其行為。

  • 多重遺產的優勢。

所有列出的參數都是用於接口的。 由於BrokerResponse本身就是抽象的並且擁有自己的層次結構,因此這些類沒有共同點的事實更加強大。

作為替代方案,您可以使用標記注釋。 我會考慮堅持這兩種方法中的一種而不是抽象類。

標記界面與標記注釋:

根據Joshua Bloch的' Effective java ':

標記接口與標記注釋相比具有兩個優點。 首先,標記接口定義由標記類的實例實現的類型; 標記注釋沒有。 如果使用標記注釋,則此類型的存在允許您在編譯時捕獲錯誤,直到運行時才能捕獲這些錯誤。 標記接口相對於標記注釋的另一個優點是它們可以更精確地定位。

什么時候應該使用標記注釋?

如果標記適用於除類或接口之外的任何程序元素,則必須使用注釋,因為只能使用類和接口來實現或擴展接口。

什么時候應該使用標記界面?

問問自己這個問題, 我想寫一個或多個只接受具有此標記的對象的方法嗎? 如果是這樣,您應該使用標記接口而不是注釋。 這將使您可以將接口用作相關方法的參數類型,這將帶來編譯時類型檢查的真正好處。

摘要:

如果要定義一個沒有與之關聯的新方法的類型,則可以使用標記接口。

如果要標記類和接口以外的程序元素,以便將來可以向標記添加更多信息,或者將標記放入已經大量使用注釋類型的框架中,那么標記注釋是正確的選擇。

在這種情況下使用空抽象類沒有任何意義,因為Java沒有多重繼承。 使您的類實現一些標記接口不會改變您的類層次結構,它只是用一些額外的元數據標記您的類。

如果已經標記為Subscribable類也應該是Writable 如果使用空的抽象類,則需要重新設計整個層次結構。 使用標記接口,將Writable添加到實現列表就很容易了。

注釋它們怎么樣? 你得到的答案是,如果你必須選擇,使用標記界面是這里的方法,但根據你可能需要做的事情使用注釋會更清晰。

事實上,你說你需要讓它們以某種方式“相同”談論一個調用instanceof並根據它做一些事情。 同樣的事情可以通過isAnnotationPresent等來實現。

但是,如果你添加一個標記界面,那么如何使它不是一個標記界面 - 只有你需要測試有限數量的類? MyInterface {boolean isSubscribable();}一些東西MyInterface {boolean isSubscribable();}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM