功能继承允许行为的抽象从一个“更具体的”派生类(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