2

我阅读了继承和多态性,但我仍然无法区分它们之间的区别。

据我所知,继承是例如(从基类和方法覆盖的派生类继承方法也可以执行。)那么什么是多态性?继承和多态在某种程度上都有意义吗?

请纠正我,因为我知道我错了。谢谢

4

5 回答 5

1

多态性允许您在其继承的父类之间来回变形类。以下是合法的,如果 Dog 和 Cat 类继承自 Animal

void takes_animal(Animal &animal) { }

Dog dog;
Cat cat;
takes_animal(dog);
takes_animal(cat);
于 2013-10-16T17:25:48.130 回答
1

用农夫的话来说,多态性是指您使用“基”类(在某些情况下称为接口)而不知道实际实现的真正含义。继承可以与多态一起使用,也可以不与多态一起使用(即,当您使用继承但始终知道您正在处理的对象的特定类时,即使它是从其他东西继承的,也不是多态)。但是没有继承就不能使用多态性(它只是没有任何意义)。

于 2013-10-16T17:26:24.680 回答
1

继承是一种实现技术。多态性是您可以用它实现的事物之一的一个方面。(这不是唯一的事情。例如,继承自 std::iterator与多态无关。)

于 2013-10-16T17:33:55.940 回答
1

在这种情况下,我们有继承但没有多态性:

struct SimpleBase {
  int i;
  int get() const { return i; }
};

struct SimpleDerived: public SimpleBase {
  int get() const { return i + 7; }
};

SimpleBase 的一个实例(或指向它的引用或指针)总是如此,派生类不能改变它的行为。例如:

int foo(SimpleBase const &obj) { return obj.get(); }

将始终调用SimpleBase::get,即使我传入派生类型的实例。


相反,通过多态性,派生类可以用自己的版本覆盖基类方法:

struct PolyBase {
  int i;
  virtual int get() const { return i; }
};

struct PolyDerived {
  int get() const { return i + 7; }
};

int foo(PolyBase const &obj) { return obj.get(); }

现在 foo 根据传入的派生类型调用不同的方法,而不知道它是哪个派生类型。

因此,使用多态性,整个类型家族可以共享一个公共接口,并且您可以编写一次对接口进行操作的代码,而无需了解所有不同的派生类型。


上面显示的多态形式是运行时多态:它生成的代码确定每个虚函数在运行时要调用的实现。

还有编译类型的多态,它根本不需要继承,而是使用模板。

假设您想编写一个排序容器(如 std::map) - 您不想将其限制为存储特定的数据类型,但您确实需要一些方法来比较两个元素以查看哪个更大。

运行时方法可能会提供一个抽象基类,例如

struct LessThanComparable {
  virtual bool operator< (LessThanComparable const &) const = 0;
};

并要求您要放入容器中的每种类型,都可以从中派生并实现operator<. 然后,您可以if (a < b)在您的容器代码中编写代码,您所存储的类型的正确函数将被调用 (*)。

// requires inheritance from abstract base class,
// uses virtual call to operator<
bool less_than(LessThanComparable const &a, LessThanComparable const &b) {
    return a < b;
}

STL中实际使用的编译类型方法 (**) 是通过提供合适的operator<. 但是,这是在编译时解决的,不需要公共基类。

// doesn't require any inheritance, doesn't use virtual function call,
template <typename T>
bool less_than(T const &a, T const &b) { return a < b; }

(*) 另请注意,实现operator<并非易事,因为a < b可以在ab具有不同的派生类型时调用。在模板版本中,我们知道它们都具有相同的类型T

(**) 好的,所以默认std::less有 LessThanComparable 要求,或者您可以提供替代的 StrictWeakOrdering。

于 2013-10-16T17:44:34.243 回答
0

您对继承的看法是正确的,但并不是那么简单。重载和覆盖也是继承的重要功能。而多态性是关于创建多态数组,例如如果父类是水果而苹果是对象,那么您可以将对象定义为水果的类型并调用通用函数。同样创建纯虚函数将阻止父类使其成为实例。

于 2013-10-16T17:31:29.730 回答