![](/img/trans.png)
[英]Best way to maximize code reuse while avoiding implementation inheritance and maintaining internalization
[英]Best way to apply inheritance and code reuse
在基類中的某些方法在繼承類中沒有意義的情況下,我有一個關於構建代碼以使用繼承重用的最佳方法的問題。 我認為這是一個普遍的 OOP 問題,而不僅僅是 TypeScript 的特有問題......
所以基本上,在某種形式的偽代碼中,問題類似於:
類 BaseClass 使SenseForA 使SsenseForA .... doesnotMakeSenseForA doesnotMakeSenseForA ....
那么如何讓Class A
繼承BaseClass
。 只是直接繼承意味着Class A
將具有沒有真正意義的成員方法。
不使用繼承意味着代碼會在BaseClass
和Class A
重復
將makesSenseForA
方法移動到一個外部類並且讓BaseClass
和它的子類都依賴於這個提取的類(即使用組合)在這個特定場景中不起作用,因為提取的類實際上應該被視為A BaseClass
。
處理這種 OOP 建模情況的最佳方法到底是什么?
編輯:由於缺乏更好的例子,這就像試圖模擬Human
和Cyborg
- 這兩個將共享大量類似的實現,因此首先想到的可能是讓Cyborg
擴展Human
......
但也會有大量的實現, Human
擁有而Cyborg
不應該擁有的。
取消繼承意味着必須在Human
和 Cyborg 中復制那些類似的功能。
並且組合也不起作用,因為如果您將那些相似的實現提取到一個單獨的對象中,該對象及其方法將具有Human
屬性,因此在我們的建模中應該被視為一個Human
。
是的,這確實是一個普遍的問題。 但是您的示例並不是對繼承的非常准確的引用。 我們主要使用繼承而不是因為公共功能。 為了重用它們,公共函數可以編寫為實用程序/實用程序類。 當一個類基本上是父類的子類型時,您會繼承它,並且我們為不是實際對象而是類型的事物創建接口。 例如:
注意, Animal
本身不能被客觀化。 現在,即使Goat
和Tiger
兩個類的許多功能都是通用的,但兩者都不應該擴展另一個,因為hunt()
方法對 Goat 類沒有意義,而graze()
對 Goat 類沒有意義Tiger
。 為此,我們使用接口。 現在,要在同一個類中移動通用函數,您可以進一步打破這種模塊化:
猜測Goat
和Tiger
現在將實施什么沒有布朗尼積分。 萬一有一些常見的函數,由於某種原因你不能寫在Animal
類中,你可以把它們寫成一個實用程序。 假設您有一只機器山羊,它具有許多與實際山羊相同的通用功能,您不extend Goat
,而是將通用功能作為實用程序移動,例如GoatUtilities
。
編輯:有人指出實用程序類不完全是面向對象編程,而是程序化的......但它們絕對可以贊美您的類,以幫助他們以正確的方式遵循面向對象編程。 這就是為什么它們是“實用程序”類。 所以,這是被遺漏的一點,我試圖指出的基本上是在給定的例子中繼承是如何被誤解/誤用的,這在某種程度上導致了有點違反 OOP 原則的問題。 擁有可行的面向對象設計並不意味着您不應該使用實用程序類,因為目標是應用繼承和代碼重用。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.