我正在尝试学习可变/不可变的类,而我遇到了这篇文章
提供的部分答案是:
如果要强制不变性,则不能有子类。例如,请参见java.lang.String,由于这个原因,它是最终类:为了防止人们将String子类化以使其可变。
好的,我了解,但是,您将如何处理此问题。假设您的任务是创建3个Employee类,Accountant,ITDepartment和QualityAssurance。现在,您可以创建一个名为Employee的抽象类,该类具有可以由所有人(雇员ID,姓名,薪水等)共享的通用方法,但是,您的类不再是不可变的。
使用Java,您将如何解决此问题?您会创建3个类,使其成为最终类,并且不实现抽象方法吗?(因此,没有任何子类化)还是您将使用接口并仅提供getters?
如果要强制不变性,则不能有子类。
这几乎是正确的,但并非完全如此。要重述:
如果要强制不变性,则必须确保所有子类都是不变的。
允许子类化的问题在于,通常任何可以编写类的人都可以将任何公共非最终类子类化。
但是所有子类都必须调用其超类的构造函数之一。包私有的构造函数只能由同一包中的子类调用。
如果密封包以控制包中的类,则可以约束子类。首先定义您要子类化的类:
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] 删除。
我来说两句