多态和继承之间有什么区别

时间:2014-11-21 07:28:29

标签: c++ inheritance polymorphism

我对继承和多态的概念感到困惑。我的意思是,代码重用性和功能覆盖之间有什么区别?是否无法使用继承概念重用父类函数,否则无法使用Polymorphism覆盖父类变量。对我来说似乎没什么区别。

 class A
{
  public:
      int a;
      virtual void get()
      {
        cout<<"welcome";
      }
};

class B:public A
{
  a =a+1; //why it is called code reuse
  void get() //why it is called overriding
 {
    cout<<"hi";
 }
};

我怀疑代码重用和函数覆盖之间的区别。

3 个答案:

答案 0 :(得分:2)

让我们从你的例子开始。

class A
{
  public:
      int a;
      virtual void get()
      {
        cout<<"welcome";
      }
};

class B:public A
{
  a =a+1; //why it is called code reuse
  void get() //why it is called overriding
 {
    cout<<"hi";
 }
};

继承:这里你从类A派生出B类,这意味着你可以访问它的所有公共变量和方法。

a = a + 1

您正在使用a的变量class A,您正在重用a中的变量class B,从而实现代码可重用性。

多态性处理程序如何根据必须执行的操作调用方法:在您的示例中,您使用get()的{​​{1}}覆盖class A的方法get() 1}}。因此,当您创建B类实例和调用方法时,您将在控制台中获得class B而不是'hi'

答案 1 :(得分:2)

函数继承允许从“更具体”的派生类到“更抽象”的基类的行为抽象。 (这类似于基本数学和代数中的因子。)在这种情况下,更抽象只是意味着指定的细节更少。期望派生类将扩展(或添加到)基类中指定的内容。例如:

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和{{类型的对象的实例中使用1}}。所以我们在这里有继承,但我们还没有真正的多态性(将在下面解释)。

您可能希望也可能不希望实例化基类的对象,但您仍然可以使用它来收集/指定所有派生类将继承的行为(方法)和属性(字段)。因此,对于代码重用,如果您有多种类型的派生类共享某些常见行为,则可以在基类中仅指定该行为一次,然后在所有派生中“重用”该行为类而不必复制它。例如,在上面的代码中,Subtype2getCommmonProperty()的规范可以说是由每个setCommonProperty(int)类重用,因为不需要为每个方法重写这些方法。

多态性是相关的,但它意味着更多。它基本上意味着您可以以相同的方式处理碰巧来自不同类的对象,因为它们都恰好来自(扩展)公共基类。为了真正有用,该语言应该支持虚拟继承。这意味着函数签名在多个派生类中可以是相同的(即,签名是公共抽象基类的一部分),但是根据特定的对象类型将执行不同的操作。

因此修改上述示例以添加到Subtype#(但保持CommonBaseSubtype1与之前相同):

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 一个Subtype1,你可以拨打Subtype2。这将根据对象的类型执行不同的操作。这是多态性。

doSomething()

就您在问题中提供的代码示例而言,void foo(void) { CommonBase * pCB = new Subtype1; pCB->doSomething(); pCB = new Subtype2; pCB->doSomething(); // Does something different... } 被称为“覆盖”的原因是因为该方法的get()版本中指定的行为优先于(“覆盖”)如果您在B::get()对象的实例上调用A::get()(即使您是通过get()执行此操作,则在方法的B版本中指定的行为,因为方法在类A*)中声明为virtual

最后,关于“代码重用”的其他评论/问题并不像你指定的那样有效(因为它不在方法中),但我希望如果你参考我上面写的内容就会很清楚。当您从公共基类继承行为并且您只需要为该行为编写一次代码(在基类中),然后所有派生类都可以使用它,那么这可以被认为是一种“代码重用”。

答案 2 :(得分:0)

您可以在没有继承的情况下使用参数多态。在C ++中,这是使用模板实现的。维基文章:

http://en.wikipedia.org/wiki/Polymorphism_%28computer_science%29#Parametric_polymorphism