簡體   English   中英

應用繼承和代碼重用的最佳方式

[英]Best way to apply inheritance and code reuse

在基類中的某些方法在繼承類中沒有意義的情況下,我有一個關於構建代碼以使用繼承重用的最佳方法的問題。 我認為這是一個普遍的 OOP 問題,而不僅僅是 TypeScript 的特有問題......

所以基本上,在某種形式的偽代碼中,問題類似於:

類 BaseClass 使SenseForA 使SsenseForA .... doesnotMakeSenseForA doesnotMakeSenseForA ....

那么如何讓Class A繼承BaseClass 只是直接繼承意味着Class A將具有沒有真正意義的成員方法。

不使用繼承意味着代碼會在BaseClassClass A重復

makesSenseForA方法移動到一個外部類並且讓BaseClass和它的子類都依賴於這個提取的類(即使用組合)在這個特定場景中不起作用,因為提取的類實際上應該被視為A BaseClass

處理這種 OOP 建模情況的最佳方法到底是什么?

編輯:由於缺乏更好的例子,這就像試圖模擬HumanCyborg - 這兩個將共享大量類似的實現,因此首先想到的可能是讓Cyborg擴展Human ......

但也會有大量的實現, Human擁有而Cyborg不應該擁有的。

取消繼承意味着必須在Human和 Cyborg 中復制那些類似的功能。

並且組合也不起作用,因為如果您將那些相似的實現提取到一個單獨的對象中,該對象及其方法將具有Human屬性,因此在我們的建模中應該被視為一個Human

是的,這確實是一個普遍的問題。 但是您的示例並不是對繼承的非常准確的引用。 我們主要使用繼承而不是因為公共功能。 為了重用它們,公共函數可以編寫為實用程序/實用程序類。 當一個類基本上是父類的子類型時,您會繼承它,並且我們為不是實際對象而是類型的事物創建接口。 例如:

  • 界面:動物
  • 類別:老虎實現動物
  • 類:山羊實現動物

注意, Animal本身不能被客觀化。 現在,即使GoatTiger兩個類的許多功能都是通用的,但兩者都不應該擴展另一個,因為hunt()方法對 Goat 類沒有意義,而graze()對 Goat 類沒有意義Tiger 為此,我們使用接口。 現在,要在同一個類中移動通用函數,您可以進一步打破這種模塊化:

  • 類食肉動物擴展動物
  • 類草食動物擴展動物

猜測GoatTiger現在將實施什么沒有布朗尼積分。 萬一有一些常見的函數,由於某種原因你不能寫在Animal類中,你可以把它們寫成一個實用程序。 假設您有一只機器山羊,它具有許多與實際山羊相同的通用功能,您不extend Goat ,而是將通用功能作為實用程序移動,例如GoatUtilities

編輯:有人指出實用程序類不完全是面向對象編程,而是程序化的......但它們絕對可以贊美您的類,以幫助他們以正確的方式遵循面向對象編程。 這就是為什么它們是“實用程序”類。 所以,這是被遺漏的一點,我試圖指出的基本上是在給定的例子中繼承是如何被誤解/誤用的,這在某種程度上導致了有點違反 OOP 原則的問題。 擁有可行的面向對象設計並不意味着您不應該使用實用程序類,因為目標是應用繼承和代碼重用。

如果您將方法設為私有,則只能在該類中使用。 如果你讓它受保護,它也可以在所有子類中使用。 所以在Class A沒有意義的方法應該是私有的,其他的應該是受保護的或公共的。

在 Java 中,您可以在此處進一步了解這一點

暫無
暫無

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

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