鱼C论坛

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

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

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

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

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

x
用黄鱼的例子来说把。
Animal基类里有eat() 行为,子类Pig也有eat()行为,封装的时候
void Pig::eat()
{
    Animal::eat();
    std::cout << "我吃猪肉" <<std::endl;
}
这个基类的行为调用是否是必须的?如果是必须的请说明下原因。谢谢。
最佳答案
2023-5-6 20:46:49
在C++中,基类(如Animal)的行为在子类(如Pig)中的调用并不是必须的。这取决于你想如何设计你的类继承关系和行为。在你提供的例子中,调用基类的 eat() 函数是为了保留基类的行为,并在子类中添加额外的行为。

以下是一个用黄鱼的例子来解释这个概念:
#include <iostream>

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

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

int main() {
    YellowFish fish;
    fish.eat();
    return 0;
}

在这个例子中, YellowFish 类覆盖了基类 Animal 的 eat() 方法,并在其中调用了基类的 eat() 方法。这样,当你调用 YellowFish 的 eat() 方法时,会先输出基类的内容,然后输出子类的内容。运行结果如下:
我是动物,我需要吃东西。
我是黄鱼,我吃小虫子。

但是,如果你不想保留基类的行为,你可以在子类中完全覆盖基类的 eat() 方法,而不调用基类的 eat() 方法,如下所示:
class YellowFish : public Animal {
public:
    void eat() override {
        // 不调用基类的eat()方法
        std::cout << "我是黄鱼,我吃小虫子。" << std::endl;
    }
};

总之,基类的行为在子类中的调用取决于你的设计需求。如果你希望子类在保留基类的行为的基础上添加额外的行为,那么在子类中调用基类的方法是有意义的。如果你希望子类完全覆盖基类的行为,那么就不需要调用基类的方法。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

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

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

在调用基类同名函数时,需要使用作用域解析运算符 "::" 来指明是调用基类的同名函数,如:`Animal::eat()`。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

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

以下是一个用黄鱼的例子来解释这个概念:
#include <iostream>

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

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

int main() {
    YellowFish fish;
    fish.eat();
    return 0;
}

在这个例子中, YellowFish 类覆盖了基类 Animal 的 eat() 方法,并在其中调用了基类的 eat() 方法。这样,当你调用 YellowFish 的 eat() 方法时,会先输出基类的内容,然后输出子类的内容。运行结果如下:
我是动物,我需要吃东西。
我是黄鱼,我吃小虫子。

但是,如果你不想保留基类的行为,你可以在子类中完全覆盖基类的 eat() 方法,而不调用基类的 eat() 方法,如下所示:
class YellowFish : public Animal {
public:
    void eat() override {
        // 不调用基类的eat()方法
        std::cout << "我是黄鱼,我吃小虫子。" << std::endl;
    }
};

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

使用道具 举报

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

本版积分规则

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

GMT+8, 2024-9-28 01:22

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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