不可变的类和子类

用户名

我正在尝试学习可变/不可变的类,而我遇到了这篇文章

提供的部分答案是:

如果要强制不变性,则不能有子类。例如,请参见java.lang.String,由于这个原因,它是最终类:为了防止人们将String子类化以使其可变。

好的,我了解,但是,您将如何处理此问题。假设您的任务是创建3个Employee类,Accountant,ITDepartment和QualityAssurance。现在,您可以创建一个名为Employee的抽象类,该类具有可以由所有人(雇员ID,姓名,薪水等)共享的通用方法,但是,您的类不再是不可变的。

使用Java,您将如何解决此问题?您会创建3个类,使其成为最终类,并且不实现抽象方法吗?(因此,没有任何子类化)还是您将使用接口并仅提供getters?

迈克·塞缪尔(Mike Samuel)

如果要强制不变性,则不能有子类。

这几乎是正确的,但并非完全如此。要重述:

如果要强制不变性,则必须确保所有子类都是不变的。

允许子类化的问题在于,通常任何可以编写类的人都可以将任何公共非最终类子类化。

但是所有子类都必须调用其超类的构造函数之一。包私有的构造函数只能由同一包中的子类调用。

如果密封包以控制中的类,则可以约束子类。首先定义您要子类化的类:

public abstract class ImmutableBaseClass {
  ImmutableBaseClass(...) {
    ...
  }
}

由于所有子类都必须具有超级构造函数的访问权限,因此您可以确保定义的包中的所有子类都遵循不变的准则。

public final class ImmutableConcreteClass extends ImmutableBaseClass {
  public ImmutableConcreteClass(...) {
    super(...);
  }
}

要将其应用于您的示例,

public abstract class Employee {
  private final Id id;
  private final Name name;

  // Package private constructor in sub-classable class.
  Employee(Id id, Name name, ...) {
    // Defensively copy as necessary.
  }
}

public final class Accountant extends Employee {
  // Public constructos allowed in final sub-classes.
  public Accountant(Id id, Name name, ...) {
    super(id, name, ...);  // Call to super works from same package.
  }
}

public final class ITWorker extends Employee {
  // Ditto.
  public ITWorker(Id id, Name name, ...) {
    super(id, name, ...);
  }
}

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章