2013-05-29 30 views

回答

2

這裏的關鍵原因繼承不是在這種情況下是一個好主意:

Vector is like Array with random access and Stack is the one without 

從廣義上講,繼承是有你提供額外的行爲;沒有合理的辦法* 刪除的行爲。

所以,如果Stack擴展Vector它將繼承由Vector類,這是你不想要的東西提供的隨機訪問行爲(與合同)。

想想的繼承是-a **。說一個Stackis-aVector是否有意義?如果不是,那麼它不應該延伸Vector

您可以使用Vector實現Stack的事實與Stack接口無關。正如@Patashu指出的那樣,如果你需要在不改變合同的情況下,你希望能夠改變實現。例如,也許你想使用鏈表實現而不是Vector。如果你延伸Vector這是不可能的;如果你使用組合,它是非常微不足道的。

*當然,您可以重寫方法來刪除您不想要的行爲,但這會破壞合同,並會讓用戶感到非常困惑。這就是爲什麼這樣做通常是不合理的。

* *是-A都有自己的缺陷,就像在軟件架構別的:看到Circle-Ellipse problem對於爲什麼你需要決定哪些類是從什麼時候繼承要額外小心,一個很好的例子。

+0

我已經改變了孩子和家長,現在好嗎?我認爲'vector'應該有'stack'中的所有方法。 – mko

+0

不,這仍然不能通過'is-a'測試。 'Stack'是一個FIFO(先進先出)結構。 「Vector」是一個隨機訪問結構。它們根本不同,也不應該從另一個繼承。 –

+0

我的意思是一個LIFO(後進先出),當然。隊列是一個FIFO。 –

1

它有助於去想它在被其他人寫的代碼庫方面,所以必須支持其他人的使用情況,或者如果你的代碼是用說,其他的代碼庫。當它只是您的代碼時,您可以輕鬆地進行更改,因爲您可以控制所有內容,但是如果必須支持其他人,則必須知道哪些更改會導致其他人的代碼中斷。

1)如果您從一個類繼承,您必須支持與該類相同的合同。通過合同,我的意思是面向公衆的方法形成了一套班級可以實施的承諾。如果a)它的合同對你的班級不利,b)你從合同中繼承的班級從你下面改變。

2)通過編寫而不是繼承,您可以更改您的類實現的用途,而不會進行任何公開更改,從而更快更便宜,就像您決定'我不想使用Vector對於我的堆棧實現,我想使用DifferentVector來代替'它會破壞代碼,假設你的堆棧是Vector的子類。 3)另外,即使你沒有爲你的堆棧使用繼承,那麼你仍然可以使Stack和Vector實現ICollection接口(例如),以允許它們被使用互換性和多態性,這是做繼承的主要優勢。