提供的部分答案是:
If you want to enforce immutability,you cannot have subclasses. See
for example java.lang.String,which is a final class for this reason:
To prevent people from subclassing String to make it mutable.
好吧,我明白了,但是,你将如何处理这个问题.假设您被赋予了创建3个Employee类,Accountant,ITDepartment和QualityAssurance的任务.现在,您可以创建一个名为Employee的抽象类,其中包含所有人共享的常用方法(员工ID,姓名,工资等),您的类不再是不可变的.
使用Java,那你怎么解决这个问题呢?你会创建3个类,使它们成为最终类,并且不实现抽象方法吗? (所以,没有任何子类)或者你会使用一个接口,并只提供getter?
解决方法
If you want to enforce immutability,you cannot have subclasses.
这几乎是正确的,但并非完全如此.重申一下:
If you want to enforce immutability,you must ensure that all sub-classes are immutable.
允许子类化的问题在于,通常任何可以创建类的人都可以子类化任何公共非final类.
但是所有子类都必须调用其超类的构造函数之一.包私有构造函数只能由同一包中的子类调用.
如果您使用seal packages以便控制包中的哪些类,则可以限制子类化.首先定义一个你想要子类的类:
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,...) { super(id,name,...); // Call to super works from same package. } } public final class ITWorker extends Employee { // Ditto. public ITWorker(Id id,...); } }