为什么不允许子类覆盖方法会导致创建不可变对象?
Why not allowing subclasses to override methods can lead to creation of immutable objects?
我是 Java 的新手,正在尝试学习定义不可变对象的概念。我在 Java 教程 oracle 中读到,创建不可变对象的方法之一是
Don't allow subclasses to override methods. The simplest way to do this is to declare the class as final.
我的问题是,为什么不允许子类覆盖方法会导致创建不可变对象?我很难理解这里的联系。
假设 String 的方法可以被另一个 class 扩展。不能保证另一个 class 会像 String 一样不可变。
所以如果你调用一些库方法并得到一个字符串,那个字符串会不会改变?是 String base class 还是扩展它的可变的东西?字符串是最终的 class,所以我们不必担心。
我在下面做了一个混淆的例子:
public class WhyImmutableClassesShouldBeFinal {
/*
* This is an immutable class
*/
private static class ImmutableClass {
private final String data;
public ImmutableClass(String data) {
this.data = data;
}
public String getData() {
return data;
}
}
/*
* This extends an immutable class, but is not immutable.
*/
private static class NotSoImmutableClass extends ImmutableClass {
private int oops;
public NotSoImmutableClass() {
super("WHATEVER");
}
public String getData() {
return Integer.toString(oops++);
}
}
/*
* Here's some function that looks like it returns an immutable class but
* doesn't.
*/
private static ImmutableClass immutableClassProducer() {
return new NotSoImmutableClass();
}
public static void main(String[] args) {
/*
* I called a method and got an ImmutableClass back.
*/
ImmutableClass c = immutableClassProducer();
/*
* But why is the value changing?
*/
System.out.println(c.getData());
System.out.println(c.getData());
System.out.println(c.getData());
System.out.println(c.getData());
}
}
我是 Java 的新手,正在尝试学习定义不可变对象的概念。我在 Java 教程 oracle 中读到,创建不可变对象的方法之一是
Don't allow subclasses to override methods. The simplest way to do this is to declare the class as final.
我的问题是,为什么不允许子类覆盖方法会导致创建不可变对象?我很难理解这里的联系。
假设 String 的方法可以被另一个 class 扩展。不能保证另一个 class 会像 String 一样不可变。
所以如果你调用一些库方法并得到一个字符串,那个字符串会不会改变?是 String base class 还是扩展它的可变的东西?字符串是最终的 class,所以我们不必担心。
我在下面做了一个混淆的例子:
public class WhyImmutableClassesShouldBeFinal {
/*
* This is an immutable class
*/
private static class ImmutableClass {
private final String data;
public ImmutableClass(String data) {
this.data = data;
}
public String getData() {
return data;
}
}
/*
* This extends an immutable class, but is not immutable.
*/
private static class NotSoImmutableClass extends ImmutableClass {
private int oops;
public NotSoImmutableClass() {
super("WHATEVER");
}
public String getData() {
return Integer.toString(oops++);
}
}
/*
* Here's some function that looks like it returns an immutable class but
* doesn't.
*/
private static ImmutableClass immutableClassProducer() {
return new NotSoImmutableClass();
}
public static void main(String[] args) {
/*
* I called a method and got an ImmutableClass back.
*/
ImmutableClass c = immutableClassProducer();
/*
* But why is the value changing?
*/
System.out.println(c.getData());
System.out.println(c.getData());
System.out.println(c.getData());
System.out.println(c.getData());
}
}