鱼C论坛

 找回密码
 立即注册
查看: 1610|回复: 2

[已解决]关于C++中覆盖接口实现语法问题

[复制链接]
发表于 2023-5-6 20:43:40 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
用黄鱼的例子来说把。
Animal基类里有eat() 行为,子类Pig也有eat()行为,封装的时候
  1. void Pig::eat()
  2. {
  3.     Animal::eat();
  4.     std::cout << "我吃猪肉" <<std::endl;
  5. }
复制代码

这个基类的行为调用是否是必须的?如果是必须的请说明下原因。谢谢。
最佳答案
2023-5-6 20:46:49
在C++中,基类(如Animal)的行为在子类(如Pig)中的调用并不是必须的。这取决于你想如何设计你的类继承关系和行为。在你提供的例子中,调用基类的 eat() 函数是为了保留基类的行为,并在子类中添加额外的行为。

以下是一个用黄鱼的例子来解释这个概念:

  1. #include <iostream>

  2. class Animal {
  3. public:
  4.     virtual void eat() {
  5.         std::cout << "我是动物,我需要吃东西。" << std::endl;
  6.     }
  7. };

  8. class YellowFish : public Animal {
  9. public:
  10.     void eat() override {
  11.         Animal::eat(); // 调用基类的eat()方法
  12.         std::cout << "我是黄鱼,我吃小虫子。" << std::endl;
  13.     }
  14. };

  15. int main() {
  16.     YellowFish fish;
  17.     fish.eat();
  18.     return 0;
  19. }
复制代码


在这个例子中, YellowFish 类覆盖了基类 Animal 的 eat() 方法,并在其中调用了基类的 eat() 方法。这样,当你调用 YellowFish 的 eat() 方法时,会先输出基类的内容,然后输出子类的内容。运行结果如下:

  1. 我是动物,我需要吃东西。
  2. 我是黄鱼,我吃小虫子。
复制代码


但是,如果你不想保留基类的行为,你可以在子类中完全覆盖基类的 eat() 方法,而不调用基类的 eat() 方法,如下所示:

  1. class YellowFish : public Animal {
  2. public:
  3.     void eat() override {
  4.         // 不调用基类的eat()方法
  5.         std::cout << "我是黄鱼,我吃小虫子。" << std::endl;
  6.     }
  7. };
复制代码


总之,基类的行为在子类中的调用取决于你的设计需求。如果你希望子类在保留基类的行为的基础上添加额外的行为,那么在子类中调用基类的方法是有意义的。如果你希望子类完全覆盖基类的行为,那么就不需要调用基类的方法。
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

发表于 2023-5-6 20:44:38 | 显示全部楼层
在这个子类Pig中,调用基类Animal的eat()行为并不是必须的,但是通常建议在子类中通过此种方式调用基类的同名函数。这也是C++中实现覆盖接口时常用的一种方法。

调用基类同名函数的好处是,可以在子类的行为实现中保留和扩展基类的行为,同时还可以添加子类自己特有的行为。如果你只想实现新的行为,而不需改变原来基类仅有的行为,则可以不调用基类同名函数。

在调用基类同名函数时,需要使用作用域解析运算符 "::" 来指明是调用基类的同名函数,如:`Animal::eat()`。
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2023-5-6 20:46:49 | 显示全部楼层    本楼为最佳答案   
在C++中,基类(如Animal)的行为在子类(如Pig)中的调用并不是必须的。这取决于你想如何设计你的类继承关系和行为。在你提供的例子中,调用基类的 eat() 函数是为了保留基类的行为,并在子类中添加额外的行为。

以下是一个用黄鱼的例子来解释这个概念:

  1. #include <iostream>

  2. class Animal {
  3. public:
  4.     virtual void eat() {
  5.         std::cout << "我是动物,我需要吃东西。" << std::endl;
  6.     }
  7. };

  8. class YellowFish : public Animal {
  9. public:
  10.     void eat() override {
  11.         Animal::eat(); // 调用基类的eat()方法
  12.         std::cout << "我是黄鱼,我吃小虫子。" << std::endl;
  13.     }
  14. };

  15. int main() {
  16.     YellowFish fish;
  17.     fish.eat();
  18.     return 0;
  19. }
复制代码


在这个例子中, YellowFish 类覆盖了基类 Animal 的 eat() 方法,并在其中调用了基类的 eat() 方法。这样,当你调用 YellowFish 的 eat() 方法时,会先输出基类的内容,然后输出子类的内容。运行结果如下:

  1. 我是动物,我需要吃东西。
  2. 我是黄鱼,我吃小虫子。
复制代码


但是,如果你不想保留基类的行为,你可以在子类中完全覆盖基类的 eat() 方法,而不调用基类的 eat() 方法,如下所示:

  1. class YellowFish : public Animal {
  2. public:
  3.     void eat() override {
  4.         // 不调用基类的eat()方法
  5.         std::cout << "我是黄鱼,我吃小虫子。" << std::endl;
  6.     }
  7. };
复制代码


总之,基类的行为在子类中的调用取决于你的设计需求。如果你希望子类在保留基类的行为的基础上添加额外的行为,那么在子类中调用基类的方法是有意义的。如果你希望子类完全覆盖基类的行为,那么就不需要调用基类的方法。
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2025-6-10 12:03

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表