2013-03-31 71 views
2

說我有3個班。一類是超類,另外兩類是從它繼承而來的。如果我有一個超類的實例,並且我想知道兩個子類中的哪一個,則此對象是實例。這兩種方法被認爲是最好的做法確定子類。多態性或instanceof

: 1)項目使用instanceof或的getClass()和比較,或 2)在超聲明一個抽象方法,並實現它的子類,以獲得代表類枚舉。

+3

什麼是你需要的類型?最佳做法是,您的編碼方式不要求您考慮實際的對象類型。假設你服從替代原則,除了序列化或調試之外,你很少需要它。 – Antimony

+0

如果例如我有一個抽象類Item代表一個通用項目,很高興有一種方法來知道它是哪個特定的項目,並基於此做出特定的操作。 –

+0

@ user59559:實際上,這不是「好」,這就是爲什麼你會得到答案「質疑你的動機」,可以這麼說。 – einpoklum

回答

0

大多數情況下,多態性是更好的答案。如果你不得不問哪個子類,那麼當添加新的子類時,就有可能忘記爲該問題添加新的「if」部分。

+1

另一方面,使用枚舉意味着當添加新類時,您仍然需要更新它。而且由於超類大概是開啓結果,代碼將不得不被更新。 – Antimony

+0

是的,如果您可以使用該技術,那麼啓用Java枚舉具有多態性的許多優點。 –

+0

問題是這兩者都不是理想的。最好的做法是想出一個更好的設計,首先不需要這個。 – Antimony

-2

通常最好的做法是調用布爾函數instanceOf(),這應該工作得很好。

雖然我自己發現你的第二個解決方案更容易使用,但第一個解決方案被認爲是很好的編程習慣。

+0

instanceof是一個操作符,而不是一個函數 – Antimony

+0

它使用幾乎總是表示*壞*實踐,並不好。 –

0

您應該使用instanceOf。通過枚舉的方法,你必須事先知道你將在以後檢查實例,並且類必須爲它做好準備。所以我更喜歡instanceOf。

1

這種情況下的最佳實踐是多態。在超類中創建一個抽象方法。子類將被迫提供具體的實現。不需要instanceof或getClass。

0

簡短回答:可能是這種情況,您嘗試以最好避免的方式使用類對象或類名稱;並避免它,你可能會讓你的代碼更清晰,更容易理解和擴展。

長(er)回答:在編寫面向對象的軟件代碼,特別是Java時,(Subtype) Polymorphism的原理被大量使用。在你的問題的背景下使它超簡化:如果你有一個A類的實例,而A類被B和C擴展,你只能使用它的公共方法將A視爲「一般」A成員;如果你想爲B和C做不同的事情,你可以爲A上的這個動作編寫一個方法doSomething(),通過重寫A.doSomething()(A的默認實現)在B和C中以不同的方式實現。

(如@ EvgeniyDorofeev的answer建議,如果沒有默認的動作,可以使你的默認方法是抽象的,但隨後必須是一個抽象類)。

這有幾個優點:

  • A的代碼不需要熟悉B和C.
  • 如果您以後添加其他類,比如說D擴展A和E來擴展C,則不需要修改現有代碼 - 只需覆蓋doSomething( ) 在他們中。
  • 您不必擔心使用的getClass()或人工創造的枚舉類... :-)

但有時也批評,爲的對象 - 一個更一般的批評的一部分面向方法(例如,參見The Noun Shuffle,地址爲OOP Oversold)。

PS:有時你不能避免使用getClass()(比如,用於準備包含類名的日誌消息); OP沒有具體說明他/她正面臨的確切問題,因此很難說清楚。無論如何,而不是走下去寫你自己的類的枚舉的路徑;使用getClass()(如果你真的需要它,你也可以從中獲得類名)。另外,你可能會發現有一個庫可以用來爲你處理這些事情,所以你根本不需要getClass()(記錄就是這樣,我剛剛給出了這個例子。)