![](/img/trans.png)
[英]Java 8: Better to extend class of static methods or better to call static methods directly?
[英]Better to extend a class or modify it directly?
所以我正在為Java中的數據結構創建可視化。 我已經開始實現數據結構(二進制搜索樹),但我需要為包含的節點類添加一些額外的功能。 就約定和最佳實踐而言,我是否應該使用此附加功能創建節點的子類,還是應該修改我擁有的內容並將其記錄在那里?
我知道這對我正在做的事情並不重要,所以我更多地問這個問題。
編輯:我可能應該更清楚。 我的修改實際上並沒有改變原始實現,只是添加了幾個額外的字段(x和y coords以及一個布爾值來設置是否突出顯示該節點)以及訪問/修改這些字段的函數。 我正在使用的節點類也包含在BST實現中
從閱讀你的答案看起來似乎有兩個案例的論點。 我同意創建一個單獨的類或接口可能是最好的事情。 創建另一個類似乎可能會變得棘手,因為您仍然需要一種從節點中提取數據的方法。 我正在使用的BST實現是通用的,並且在Node類或BST類中沒有任何這樣的功能只返回數據,所以至少我必須添加它。
感謝您提供豐富的回復。
要回答的問題是,當您沒有可視化數據結構時,“基本功能”是否有用,甚至是可取的?
您可能根本不想擴展該類。 沒有更多細節,在我看來,你有一個有效的數據結構。 您可以創建一個知道如何對其進行虛擬化的新類。
也就是說,代替數據結構而不是知道如何自我可視化,您有一個數據結構,另一個知道如何可視化數據結構的類。 哎呀 - 您可能會發現它會演變成另一個完整的類層次結構,因為您可能需要可視化隊列,堆棧等等。無需使用二進制搜索樹。
既然你一般都在問,這里的答案很簡短: 這實際上取決於具體情況 。
首先,假定子類與其父類具有“IS-A”關系。 如果你不能說你的新子類是一個特定類型的原始類,那你就是在問一個錯誤的問題,並且應該創建一個新的,無關的類。
在您的具體情況下,我同意n8wrl; 由於可視化與數據結構無關,因此實現一個完全獨立的Visualizable
接口可能比制作DrawableBSTNode
子類更好。
我想說,在向現有實現添加功能的一般情況下,您應該擴展現有實現而不是修改它。
這是我的推理。 如果除了二進制搜索樹實現之外的任何地方使用該節點,那么當您修改它時,您需要找到它用於確保這些位置都不與您的修改沖突的任何地方。 雖然只是以新方法的形式添加功能通常不會引起問題,但它可能會導致問題。 你永遠不知道如何使用一個對象。
其次,即使它僅用於二進制搜索樹,您仍然需要確保BST的實現與您的修改一致。
最后,如果你擴展它,你不必擔心第一點和第二點。 並且您可以獲得額外的好處,即您的修改始終與原始實施分開。 這樣可以更輕松地跟蹤您所做的事情並對其進行評論。
沒有簡單的答案,知道何時以及如何添加功能是您必須要學習的東西。
只是添加到基類似乎是簡單的解決方案,但它污染了您的基類。 如果這是一個類,你可以合理地期望使用另一個程序(甚至你的程序的一部分),你所添加的功能是否適合你班級的責任? 如果不是這可能是一個不好的舉動。 您是否添加了將基類鏈接到特定用途的依賴項? 因為如果你正在拋出代碼重用窗口。
繼承是許多工程師所傾向的解決方案,這是一條誘人的路線。 但是,隨着我成長為工程師,這是我謹慎使用的。 繼承應僅用於真正的is-a關系,並且您需要尊重行為子類型,否則您將在以后后悔。 而且由於Java只允許單繼承,這意味着你只能在子類型中獲得一次。
組合(尤其是界面)通常是一個更好的主意。 通常看起來像是一種關系的關系實際上是一種關系。 或者有時您真正需要的是一個輔助類,它有許多函數可以將原始類作為參數。
但是有了組合,有一個問題,想要在樹中存儲這些對象。 這里的解決方案是接口。 您不需要存儲節點的樹。 您希望對象具有可以為您提供節點的接口。
public interface HasNode {
public Node getNode();
}
你的節點類是一個帶有getNode的HasNode,只是返回它。 您的NodeVisualizer類也是一個HasNode,現在您也可以在樹中存儲NodeVisualizers。 當然現在你有另一個問題,你的樹可能包含NodeVisualizers和Nodes,這不會很好。 另外,當您從樹函數中獲取HasNode時,您必須將它們轉換為正確的實例,這很難看。 你會想要使用模板,但這是另一個答案。
混合邏輯上獨立的功能將導致混亂。 子類化是一種非常特殊的關系,經常被過度使用。 子類化用於Is-a-Kind關系。
如果你想要想象一下,為什么不為它創建一個完全獨立的類呢? 您可以簡單地將Node對象傳遞給它。 (或者甚至更好,使用接口。)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.