功能繼承允許行爲的抽象從一個「更具體的」派生類(ES)的「更抽象「的基類。 (這與將基本數學和代數分解相類似。)在這種情況下,更抽象的簡單意味着指定較少的細節。預計派生類將擴展爲(或添加到)基類中指定的內容。例如:
class CommonBase
{
public:
int getCommonProperty(void) const { return m_commonProperty; }
void setCommonProperty(int value) { m_commonProperty = value; }
private:
int m_commonProperty;
};
class Subtype1 : public CommonBase
{
// Add more specific stuff in addition to inherited stuff here...
public:
char getProperty(void) const { return m_specificProperty1; }
private:
char m_specificProperty1;
};
class Subtype2 : public CommonBase
{
// Add more specific stuff in addition to inherited stuff here...
public:
float getProperty(void) const { return m_specificProperty2; }
private:
float m_specificProperty2;
};
注意,在上面的例子中,getCommonProperty()
和setCommonProperty(int)
從CommonBase
類繼承,並且可以在Subtype1
類型和Subtype2
的對象的實例來使用。所以我們在這裏繼承,,但我們並沒有真正的多態性,但是(如下面將要解釋的)。
您可能想也可能不想實例化基類的對象,但仍可以使用它來收集/指定所有派生類將繼承的行爲(方法)和屬性(字段)。因此,就代碼重用而言,如果您有多個類型的共享某些常見行爲的派生類,則可以在基類中僅指定一次該行爲,然後在所有派生類中「重複使用」,而不必複製它。例如,在上面的代碼中,getCommmonProperty()
和setCommonProperty(int)
的規範可以說是由每個類重新使用,因爲這些方法不需要爲每個方法重寫。
多態性是相關的,但它意味着更多。它基本上意味着你可以用相同的方式處理碰巧來自不同類的對象,因爲它們都是從(擴展)公共基類派生的。爲了這個真的很有用,該語言應該支持虛擬繼承。這意味着函數簽名在多個派生類中可以是相同的(即簽名是公共抽象基類的一部分),但根據特定類型的對象會做不同的事情。
因此修改上面的例子添加到CommonBase
(但保持Subtype1
和Subtype2
同前):
class CommonBase
{
public:
int getCommonProperty(void) const { return m_commonProperty; }
void setCommonProperty(int value) { m_commonProperty = value; }
virtual void doSomething(void) = 0;
virtual ~CommonBase() { }
private:
int m_commonProperty;
};
注意doSomething()
在此聲明爲純虛函數在CommonBase
(這意味着你不能直接實例化一個CommonBase
對象 - 它不一定是這種方式,我只是這樣做以保持簡單)。但是現在,如果您有一個指向CommonBase
對象的指針,它可以是或者 a Subtype1
或 a Subtype2
,您可以在其上調用doSomething()
。這將根據對象的類型做一些不同的。這是多態性。
void foo(void)
{
CommonBase * pCB = new Subtype1;
pCB->doSomething();
pCB = new Subtype2;
pCB->doSomething(); // Does something different...
}
在你的問題中提供的代碼示例,原因get()
方面被稱爲「壓倒一切」,是因爲在B::get()
型式的方法中指定的行爲優先於(「覆蓋」)如果您在B
對象的實例上調用get()
(即使您通過A*
執行操作,因爲該方法在類A
中聲明爲virtual
),該方法的A::get()
版本中指定的行爲。
最後,關於「代碼重用」的其他評論/問題並不像您指定的那樣工作(因爲它不在方法中),但我希望如果您參考我上面寫的內容。當你從一個公共基類繼承行爲,並且你只需要爲這個行爲編寫代碼(在基類中),然後所有的派生類都可以使用它,那麼這可以被認爲是一種「代碼重用」。
你可以有繼承無多態性,但你不能真正擁有多態性沒有繼承。 – 2014-11-21 07:31:43
您提到多態但不顯示使用它的代碼。 – ChiefTwoPencils 2014-11-21 07:31:56
如果你不小心,這些概念可以感受到整個大學課程,並蔓延到畢業後水平。試着問一個更具體的問題。 – 2014-11-21 08:32:09