不可变的类和子类 [英] Immutable Classes and Subclasses

查看:83
本文介绍了不可变的类和子类的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试了解可变/不可变类,并且遇到了这篇文章

I'm trying to learn about mutable/immutable classes and I came across this post

提供的部分答案是:

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

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,姓名,薪水等)共享的通用方法.但是,您的类不再是不可变的.

Alright, I understand it, but, how would you handle this issue. Let's say you were given the task of creating 3 Employee classes, Accountant, ITDepartment, and QualityAssurance. Now, you could create an abstract class called Employee with common methods that would be shared by all (employee ID, name, salary etc..), however, your classes are no longer immutable.

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

Using Java, How then would you solve this problem ? Would you create the 3 classes, make them final, and don't implement an abstract method? (So, no subclassing whatsoever) or would you use an interface, and provide only the getters?

推荐答案

如果要强制执行不变性,则不能有子类.

If you want to enforce immutability, you cannot have subclasses.

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

This is almost true, but not entirely. To restate it:

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

If you want to enforce immutability, you must ensure that all sub-classes are immutable.

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

The problem with allowing subclassing is that normally anyone who can author a class can subclass any public non-final class.

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

But all subclasses must invoke one of their super-class's constructors. Package-private constructors can only be invoked by subclasses in the same package.

如果您密封包装,以便您控制哪些类在包中,您可以约束子类化.首先定义您要子类化的类:

If you seal packages so that you control which classes are in your package, you can constrain subclassing. First define a class you want to subclass:

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

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

Since all sub-classes have to have access to the super-constructor, you can ensure all the sub-classes in the package you define follow immutable discipline.

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


要将其应用于您的示例,


To apply this to your example,

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

这篇关于不可变的类和子类的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆