I want to create mutable and immutable node in java, both should be the same in everything except the mutable. how to implement the base class and the two derived class of mutable and immutable classes ?
5 回答
The difference between mutable and immutable classes is that immutable classes have no setters or any other methods that modify internal state. The state can only be set in the constructor.
It would be a bad idea to call the parent class Immutable because this would no longer be true when you have subclasses. The name would be misleading:
ImmutableNode node = new MutableNode();
((MutableNode)node).change();
您需要做的就是创建一个带有受保护变量的基类
public class Base{
protected int foo;
}
可变的需要能够设置变量
public class MutableBase extends Base{
public void setFoo(){}
}
不可变的只需要能够设置变量一次
public class ImmutableBase extends Base{
public ImmutableBase(int foo){
this.foo = foo;
}
}
大多数不可变类都有方法可以在不改变实例的情况下作用于内部变量。字符串这样做,你可能想要这样的东西
public ImmutableBase add(int bar){
return new ImmutableBase(this.foo+bar);
}
这样做很酷的是,您可以让您的班级的用户减少对每个实例内部的控制/担心。这使得使用起来更容易,因为在 Java 中,所有内容都是通过对象引用传递的,所以如果您传递的是 String 或 ImmutableBase,您不必担心它会被更改。
对于一个不可变的类,它必须声明为 final,并且它不能有 setter 方法。最终声明确保它不能被扩展并添加额外的可变属性。
class Base {
protected int var1;
protected int var2;
public getVar1() {return var1;}
public getVar2() {return var2;}
}
class Mutable extends Base {
public setVar1(int var1) {this.var1 = var1}
public setVar2(int var2) {this.var2 = var2}
}
final class Immutable extends Base { //final to avoid being extended and then implement the setters
}
这就是我能做的一点点吗?但是你为什么需要这样的场景呢?
另一种选择是使用与UnmodifiableList相同的策略。首先,创建一个指定类型的接口。
interface List<T>{
List<T> add(T t);
T getAt(int i);
...
}
然后你用所有的业务逻辑实现你的可变类:
public class MutableList<T> implements List<T>{
@Override
List<T> add(T t){ ... }
@Override
T getAt(int i){ ... }
...
}
最后,创建不可变类作为可变类的视图。您实现相同的接口,但将所有读取方法调用委托给查看的对象,并通过异常禁止任何写入访问。
public class UnmodifiableList<T> implements List<T>{
//This guy will do all hard work
private List delegate;
public UnmodifiableList(List<? extends T> delegate){
this.delegate = delegate;
}
//Forbidden mutable operation: throw exception!
@Override
List<T> add(T t){
throw new UnsupportedOperationException("List is unmodifiable!");
}
//Allowed read operation: delegate
@Override
T getAt(int i){
return delegate.getAt(i);
}
...
}
这种方法的好处是您只需实现一次业务逻辑,并且可以先使用自己的方法和验证检查构建一个对象,然后再将其转换为不可变对象。
不可变类是一个一旦创建,其内容就不能改变的类。不可变对象是状态不能改变的对象。
Java 中不可变类的一个常见示例是String类。