为何在OOP中选择继承基类而非创建基类实例?
在面向对象编程里,用实例化基类(比如示例中B里创建A的实例)来代替继承实现复用,会带来以下几个关键问题:
破坏多态性,无法参与基类的替换场景
继承的核心价值之一是支持多态:如果B继承A,那么B的实例可以被当作A类型来使用(比如传入接收A类型参数的方法),还能重写A的方法实现自定义逻辑。但如果只是在B里实例化A,B和A完全是两个独立的类,既没法替换A的角色,也没法修改A的行为,彻底失去了多态带来的灵活性。无法访问基类的protected成员,复用范围受限
基类A里的protected方法/属性是专门给子类预留的扩展点,但B作为外部类实例化A后,只能调用A的public成员,完全没法利用这些protected的内容,相当于浪费了基类设计好的扩展能力,能复用的代码范围被大幅缩小。代码耦合度更高,维护成本上升
B直接依赖A的具体实现细节:比如A的构造函数参数变化、public方法签名修改,B里new A()以及调用A实例方法的代码都得跟着改。而继承的话,只要基类对外的接口(public/protected的约定)不变,子类的代码基本不用调整,耦合度更低。违背OOP的语义约定,降低代码可读性
继承表达的是**"is-a"(是一种)的关系(比如Dog extends Animal表示狗是动物的一种),而实例化是"has-a"(拥有一个)**的关系。如果业务逻辑里B本来应该是A的子类,却用实例化的方式,会让其他开发者误解两者的关系,代码的语义清晰度大打折扣。
举个简单对比:
如果用继承,写法是:
class A { protected void doSomething() { /* ... */ } } class B extends A { @Override protected void doSomething() { super.doSomething(); // 自定义逻辑 } }
这种情况下B既复用了A的逻辑,又能扩展,还能作为A类型参与多态。而示例中的写法完全做不到这些。
内容的提问来源于stack exchange,提问作者mestu

