函数的重写

我在OOP方面的知识一直都使用后再看理论的,因为之前的理论大多都没有吸收,也缺乏深入理解。最近又重新学习了继承体系中关于类中方法的重写(override)。先通过在C++下的例子来阐述这一机制。

#include<iostream> #include<string> using namespace std; class People{ public: People(string name){ this->name = name; } // void display(){ //不加virtual是普通成员函数 virtual void display(){ //加virtual变成虚函数 cout << "I am a people, name: " + name << endl; }; protected: string name; }; class Man : public People{ public: Man(string name, string wife):People(name){ this->wife = wife; } void display(){ cout << "I am a man, name: " + name + " wife: " + wife << endl;; }; protected: string wife; }; int main(){ // People p("baobei"); // p.diplay(); //输出:I am a people, name: baobei // Man m("baobei", "mbaobei"); // m.diplay(); //输出:I am a people, name: baobei wife: mbaobei People *p; p = new Man("baobei", "mbaobei"); p->display(); //输出:I am a people, name: baobei wife: mbaobei return 0; }


在上例中,函数display()不加virtual只是普通的成员函数,那么即使在Man继承People后重写了display(),那么在主函数中父类指针p指向子类对象,并调用其函数display(),并没有执行子类对象的display()函数,而是执行了基类的方法。而在基类People中display()函数前加上virtual后,程序则调用了子类的display()方法。

这就是虚函数在动态绑定中的作用。一个基类指针指向他的任何子类对象,都能够非常智慧的执行子类的方法,而不会被父类的方法所覆盖。这种需求在OOP中是非常普遍的。几乎每个程序员每天都在用吧。


疑问一:很多人都会问,在基类中不加virtual,子类依旧可以重写,而且编译没错,程序也能执行啊?

回答:那是你没读上面那个程序,如果不加virtual,子类方法肯定就被父类方法覆盖了,除非你专门弄一个对子类对象的直接引用。


疑问二:java程序员又会说,java中子类就可以任意重写父类实现著名的父类引用指向子类对象,调用子类方法,实现动态绑定。还不用什么virtual关键字?

回答:那还是你对java语言不熟悉,java中对应的关键字是"@override",呵呵,现在知道"@override"的作用了吧,以前一直都不管那个关键字。你试着将"@override"去掉看看,父类方法必然覆盖掉子类方法,也就是父类引用只能掉父类的方法,即使他指向子类对象。


疑问三:override是重写,那么overload是什么?两者有关系么?很多人容易混?

回答:override是子类重写父类的方法实现动态绑定。是继承体系中纵向的,而overload是函数重载,横向的,类体内部的。没什么关系。但都是多态的体现!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值