java – 不可变的类和子类

前端之家收集整理的这篇文章主要介绍了java – 不可变的类和子类前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我正在尝试学习可变/不可变类,我遇到了 this post

提供的部分答案是:

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,...);
  }
}

猜你在找的Java相关文章