2014-11-21 34 views
1

我对遗传和多态性的概念感到困惑。我的意思是,代码重用性和函数重写有什么区别?使用继承概念重用父类函数是不可能的,否则使用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"; 
} 
}; 

我的疑问是关于代码重用和函数重写之间的区别。

+1

你可以有继承无多态性,但你不能真正拥有多态性没有继承。 – 2014-11-21 07:31:43

+0

您提到多态但不显示使用它的代码。 – ChiefTwoPencils 2014-11-21 07:31:56

+0

如果你不小心,这些概念可以感受到整个大学课程,并蔓延到毕业后水平。试着问一个更具体的问题。 – 2014-11-21 08:32:09

回答

2

让我们从你的例子开始。继承:在此,您从类A派生类B,这意味着您可以访问其所有公共变量和方法。

a = a + 1 

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

与程序是如何调用取决于它必须完成的事情的方法多态性的交易:在您的示例您正在使用的class B方法get()覆盖的class A方法get()。所以,当你创建B类和呼叫方法得到的实例,你会在控制台中看到'hi''welcome'

2

功能继承允许行为的抽象从一个“更具体的”派生类(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(但保持Subtype1Subtype2同前):

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()版本中指定的行为。

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

+0

虽然我试图在这里回答这个问题,但我相信在这里有几个*其他答案可以解决您的问题。请查看其中一些以了解更多详情。 – Turix 2014-11-21 08:27:19

相关问题