You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

公共基类与派生类中的Getter和Setter是否存在差异?

基类与派生类中放置get/set方法的核心差异

你给出的两段代码运行结果一致,但从代码复用、接口设计、封装性、维护成本这些实际开发维度看,二者存在本质区别:


1. 代码复用性差异明显

  • Type1中,getS1()和setS1()是基类base的公共方法,所有public继承自base的派生类(比如后续新增的derived2、derived3)都能直接继承使用,完全不用重复编写这两个方法。
  • Type2中,这两个方法仅属于当前derived类,其他继承base的派生类如果要访问s1,必须重新实现一遍get/set,会产生大量重复代码。

2. 接口一致性与多态支持不同

  • Type1里,base对象和所有派生类对象的访问接口完全统一:不管是base b;还是derived d;,都能通过.getS1()/.setS1()操作s1。甚至可以用基类指针/引用指向派生类对象调用这些方法,完美符合里氏替换原则,方便后续扩展多态逻辑。
  • Type2中,只有derived类有这两个方法,base对象根本没法访问自己的s1(因为s1是protected),其他派生类也没有这套接口,整个类体系的访问接口是割裂的。

3. 封装性与逻辑可控性差距大

  • Type1把s1的访问逻辑完全封装在基类里:如果以后需要给setS1()加校验(比如限制字符串长度不超过10),或者给getS1()加日志,只需要修改基类的方法,所有派生类自动生效,统一控制逻辑,维护成本极低。
  • Type2中,每个派生类的get/set都是独立实现的,你没法保证所有派生类对s1的访问逻辑一致——比如某个派生类的setS1()可能直接跳过校验,破坏基类原本的设计意图,而且要修改逻辑的话,每个派生类都得改,非常麻烦。

4. 职责划分合理性不同

  • Type1遵循单一职责原则:基类base负责管理自己的成员变量s1的访问,派生类derived只需要专注于自身的功能(比如你的NotUsed成员)。
  • Type2把基类成员的访问逻辑丢给了派生类,相当于让派生类管基类的事,职责混乱,完全违背了面向对象封装的核心思想:谁的成员谁负责管理。

附上你提供的两段代码:

Type1(基类实现get/set)

#include <iostream>
using namespace std;

class base
{
    public:
    string getS1()
    {
        return s1;
    }
    void setS1(string s)
    {
        s1 = s;
    }

    protected:
    string s1;
};

class derived: public base
{
    public:
    string NotUsed;
};

int main()
{
    derived d;
    d.setS1("Test");
    cout << d.getS1() << endl;
}

Type2(派生类实现get/set)

#include <iostream>
using namespace std;

class base
{
    public:

    protected:
    string s1;
};

class derived: public base
{
    public:
    string getS1()
    {
        return s1;
    }
    void setS1(string s)
    {
        s1 = s;
    }
    
    string NotUsed;
};

int main()
{
    derived d;
    d.setS1("Test");
    cout << d.getS1() << endl;
}

内容的提问来源于stack exchange,提问作者Johnzik

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.21 08:20:22