当前位置: 首页 > 面试题库 >

不可变的类和子类

佴涵蓄
2023-03-14
问题内容

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

提供的部分答案是:

如果要强制不变性,则不能有子类。例如,请参见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, ...);
  }
}


 类似资料:
  • 本文向大家介绍Python的可变类型和不可变类型?相关面试题,主要包含被问及Python的可变类型和不可变类型?时的应答技巧和注意事项,需要的朋友参考一下 可变数据类型:列表、字典、可变集合 不可变数据类型:数字、字符串、元组、不可变集合    

  • 问题内容: 我有以下课程: 这可以按预期工作(使用字符串的单词而不是字母来初始化集合)。但是,当我想对set的不可变版本执行相同操作时,该方法似乎被忽略: 我可以达到类似的目的吗? 问题答案: 是的,您需要重写特殊方法: 输出为:

  • 问题内容: 我对什么是不可变类型感到困惑。我知道该float对象被认为是不可变的,在我的书中有这样的例子: 由于类的结构/层次结构,这是否被认为是不可变的?意思float是在类的顶部,是它自己的方法调用。类似于此类示例(即使我的书说的dict是可变的): 可变的东西在类内部具有方法,例如以下类型: 另外,对于最后一个,如果我将这种类型的set传递给它: 不调用该example方法,它返回一个字典。

  • 问题内容: 我找到了一篇有趣的代码文章: 我真的很好奇了解创建此类的优势。我知道这里的此类对象是不可变的,因为一旦初始化就无法更改其变量值。我以前从未做过这样的事情,而且我真的不了解它的优势。 为什么是个好习惯? 您能说出可以使用这种方法的情况吗? 常量或只读变量呢?那不是很相似吗? 在文章中说,这不利于应用程序的性能。 但是为什么 呢? 问题答案: 您提到的示例是不可变对象。它在编程语言中被广泛

  • 问题内容: 通过遵循所有Java标准,我的班级变得一成不变 这些是我在定义不可变类时所做的主要检查点。 但是还有一个问题,我的对象仍然可以通过java反射进行修改,对吗?还是我在课堂上错过了任何一点? 提前致谢。 问题答案: 没有什么可以躲藏的-即使是不可变的类也不能幸免。但是,您对此无能为力,因此“无法通过反射进行修改”不是不变性的标准之一。

  • 我正在寻找一种在python中构建类的方法: setter在赋值前检查值的类型 暂时我找到了那两个装修师: 和 但我很难加入这两种方法。你能帮助我吗?你有什么想法吗?谢谢