编译时的多态性和运行时的多态性在实现方法上有何不同

编译时的多态性和运行时的多态性在实现方法上有何不同,第1张

我不知道你哪本书上看到的,但是,只要不是后绑定就不能称为多态,前绑定只能称为代码重用,比如函数的重载、覆盖以及一般的类继承。

多态的关键特点就是:在运行时虚基类指针指向派生类对象地址,而将派生类对象地址赋值给基类指针,这就是所谓的后绑定,编译时绑定称为前绑定,因此多态另一个特点就是“动态“。换句话说,如果是后绑定,编译器事先是不知道在运行时指针将指向哪一种派生类的对象,因此基类指针必须是“虚“的,虚基类中不能有任何实现只有定义,此时虚基类的作用就是一个类接口,这样才能在编译时“模糊”掉类型匹配原则,基类的作用只是个约定,定义了函数调用格式,而只在运行时才确定指针具体指向哪一个对象。

而所谓编译时的多态性根本不存在,如果编译器能确定基类指针指向哪一个派生类对象地址,就不是多态,哪怕你采用重载覆盖或者继承,这些编译器已经可以预知的事情,一旦编译完成就固定了,运行时无法更改的,比如你不能在不重新编译的情况下增加一个重载,这就制约了程序运行时的灵活性以及可扩充性。而多态完全可以实现“热“更新,更多的是便于程序的可扩充性。你完全可以将派生类编译在DLL中,每当更新程序时,只要替换掉DLL而不用重新编译全部代码。

编译时的多态性可以通过使用()获得。

A重载函数和析构函数

B虚函数和指针

C虚函数和对象

D虚函数和引用

正确答案:B

面试官:什么是多态呢?

猪队友:多种形态,气体,液体,固体~

面试官:go out! now!

到底什么是多态呢?

允许将子类类型的指针赋值给父类类型的指针,把不同的子类对象都当作父类来看。比如你家有亲属结婚了,让你们家派个人来参加婚礼,邀请函写的是让你爸来,但是实际上你去了,或者你妹妹去了,这都是可以的,因为你们代表的是你爸,但是在你们去之前他们也不知道谁会去,只知道是你们家的人。可能是你爸爸,可能是你们家的其他人代表你爸参加。这就是多态。

多态又分为 编译时多态和运行时多态。

编译时多态:比如重载

运行时多态:比如重写

简单版本:

原理也很简单,父类或者接口定义的引用变量可以指向子类或者具体实现类的实例对象,由于程序调用方法是在运行期才动态绑定的,那么引用变量所指向的具体实例对象在运行期才确定。所以这个对象的方法是运行期正在内存运行的这个对象的方法而不是引用变量的类型中定义的方法。

术语版本:

我们将引入Java静态分派和动态分派这个概念。

如果想深入的同学可以参考可以参考《深入理解Java虚拟机》。

参考:

https://blogcsdnnet/sunxianghuang/article/details/52280002

静态联编支持的多态性称为编译时的多态性,也称静态多态性,它是通过函数重载和运算符重载实现的。

动态联编支持的多态性称为运行时的多态性,也称动态多态性,它是通过继承和虚函数实现的。

多态按字面的意思就是“多种状态”。在面向对象语言中,接口的多种不同的实现方式即为多态。

多态性是允许你将父对象设置成为和一个或更多的他的子对象相等的技术,赋值之后,父对象就可以根据当前赋值给它的子对象的特性以不同的方式运作。

把不同的子类对象都当作父类来看,可以屏蔽不同子类对象之间的差异,写出通用的代码,做出通用的编程,以适应需求的不断变化。

赋值之后,父对象就可以根据当前赋值给它的子对象的特性以不同的方式运作。也就是说,父亲的行为像儿子,而不是儿子的行为像父亲。

举个例子:例如ATM机。世界上有非常多的银行,每个银行都有好多种卡。如果ATM需要为每一种卡写一种方法去调用,例如getMoney(CCBCard card),getMoney(BBCard card)就会非常的麻烦。而且维护起来就是灾难性的。因为每时每刻都可能会有新的卡出现。所以我们可以采用多态

getMoney(Card card),所有的yhk都继承Card这个类。这样就可以避免为每一种卡写一个方法。但是每一种卡的使用方法,作用都不一样,Card如何调用每一种卡不同的内容呢?

这就需要多态。让你看起来像是 *** 作的父类,但是实际的运行内容却是子类的内容。

下面有一段代码,你可以参考一下。

用父类的指针或者引用指向子类对象,来实现多态的作用

class A {

public:

  A() {}

  virtual void foo() {

  cout << "This is A" << endl;

}

};

class B : public A {

public:

  B() {}

  void foo() {

  cout << "This is B" << endl;

  }

};

int main(int argc, char argv[]) {

  A a = new B();

  a->foo();

  if(a != NULL)

  delete a;

  return 0;

}

这将显示:

This is B

如果把virtual去掉,将显示:

This is A

前面的多态实现使用抽象类,并定义了虚方法

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/langs/12156215.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-05-21
下一篇 2023-05-21

发表评论

登录后才能评论

评论列表(0条)

保存