多态性和遗传性有什么区别
what is the difference between polymorphism and inheritance
我对继承和多态的概念感到困惑。我的意思是,代码重用性和函数覆盖有什么区别?是不可能使用继承概念重用父类函数,还是不可能使用多态性覆盖父类变量。对我来说似乎没有什么区别。
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";
}
};
我的疑问是关于代码重用和函数覆盖之间的区别。
让我们从您的示例开始。
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
在这里,您使用的是class A
的变量a
,您将在class B
中重用变量a
,从而实现代码的可重用性。
多态性处理程序如何根据它必须执行的操作调用方法:在您的示例中,您将使用class B
的方法get()
覆盖class A
的方法get()
。因此,当您创建类 B 的实例并调用方法 get 时,您将在控制台中得到'hi'
,而不是'welcome'
函数继承允许将行为从"更具体"的派生类抽象为"更抽象"的基类。 (这类似于在基础数学和代数中分解。 在这种情况下,更抽象只是意味着指定更少的细节。 预计派生类将扩展(或添加)基类中指定的内容。 例如:
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)
的规范可以说是每个Subtype#
类重用的,因为不需要为每个类重写方法。
多态性是相关的,但它意味着更多。 这基本上意味着您可以以相同的方式处理碰巧来自不同类的对象,因为它们都恰好派生自(扩展)公共基类。 为了使这真正有用,该语言应该支持虚拟继承。 这意味着函数签名在多个派生类中可以是相同的(即,签名是通用抽象基类的一部分),但会根据特定类型的对象执行不同操作。
因此,修改上面的示例以添加到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
对象的指针,它可以是Subtype1
或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::get()
版本中指定的行为(即使您通过 A*
执行此操作, 因为该方法在类 A
中声明为virtual
)。
关于"代码重用"的其他评论/问题并没有像您指定的那样完全有效(因为它不在方法中),但我希望如果您参考我上面写的内容,它会很清楚。 当您从公共基类继承行为并且只需为该行为编写一次代码(在基类中),然后所有派生类都可以使用它时,这可以被视为一种"代码重用"。
您可以在没有继承的情况下具有参数化多态性。在C++中,这是使用模板实现的。维基文章:
http://en.wikipedia.org/wiki/Polymorphism_%28computer_science%29#Parametric_polymorphism
- 向量 <int> a {N, 0} 和 int arr a[N] = {0} 的时间复杂度有什么区别
- 在 .h 文件中的类中声明静态变量和在.cpp文件中声明"global"变量有什么区别
- 我是C++编程的新手,这些代码之间有什么区别,我应该使用哪一个
- 返回常量对象引用 (getter) 和仅返回字符串有什么区别?
- Qt:remove() 和 rmdir() 有什么区别
- 这 4 个 lambda 表达式之间有什么区别?
- 将向量作为类>(值)<向量启动和向量<类>[值]有什么区别
- typedef 枚举和枚举类有什么区别?
- &C::c 和 &(C::c) 有什么区别?
- ascii 和 unicode 在处理级别有什么区别吗?
- C 中的常量限定符和 C++ 中的常量限定符有什么区别?
- "ABC" 和 "ABC" ) 在C++中有什么区别?
- 空指针常量 (nullptr)、空指针值和空成员指针值之间有什么区别?
- 引用捕获和在 lambda 中通过引用发送参数有什么区别 (C++)
- 两种访问I2C总线的方法有什么区别?
- 两种模板示例有什么区别?
- 这两种C++语法之间有什么区别?
- lua 5.0.2 模块和 5.3.5 有什么区别?
- C++中"typedef"、"using"、"namespace"和"using namespace"有什么区别?
- std::enable_if 和 std::enable_if_t 有什么区别?