继承:理解

0 inheritance

例如,假设程序要处理由实部和虚部组成的复数.在复数中,实部和虚部的行为类似于实数,因此所有的操作(+, - ,/,*,sqrt,sin,cos等)都可以从称为REAL的对象类继承而不是必须用代码写的.

子类Complex不需要编写任何代码的断言似乎是合理的吗?

这对于每个类必须维护的数据成员是否有意义?为什么或者为什么不?

它在方法方面有意义吗?使用现有类Real创建类Complex是否有更好的方法?

cle*_*tus 6

复杂并没有真正扩展Real.实数只是Complex的一个特例(虚部为0).如果Complex扩展Real并且依赖于Real的算术运算,那么它们将是不正确的.例如,Add操作将添加实部并返回Real.

学习OOP时常见的错误是在任何地方看到继承关系,而事实上它们并不常见.问题的一部分是书籍和坏课程通过给你一个可怕的例子(在90年代更多,但现在仍然如此)延续了这一点.成分更为常见.

为了给你一个Java示例(因为你没有提到语言和实际代码通常比伪代码描述更有用),这可能更合适:

public class Complex {
  private final double real;
  private final double imaginary;

  private Complex(double real) {
    this(real, 0.0d);
  }

  private Complex(double real, double imaginary) {
    this.real = real;
    this.imaginary = imaginary;
  }

  public static Complex makeReal(double real) {
    return new Complex(real);
  }

  public static Complex makeComplex(double real, double imaginary) {
    return new Complex(real, imaginary);
  }

  public Complex add(Complex other) {
    return makeComplex(real + other.real, imaginary + other.imaginary);
  }

  ...
}
Run Code Online (Sandbox Code Playgroud)

注意:这演示了另外两个有用的概念:

  1. 不变性.创建后无法修改复合体.这非常有用;
  2. 工厂方法.注意构造函数是私有的.这是故意的,允许您控制对象的实例化方式.例如,如果某人两次调用makeReal(3.0d),则可以使其返回相同的实例,而不是每次都创建一个新实例.

  • +1用于提倡组合而不是继承.如果我们认为Java原语`double`(或盒装等效的`Double`)是一个`Real`类,那么你的`Complex`类实际上是两个`Real`实例的*composition*.`Complex`根本不需要*从`Double`继承*. (3认同)