我想在Java中创建可变和不可变节点,除了可变性之外,两者应该完全相同。如何实现基类和可变和不可变类的两个派生类?
我想在Java中创建可变和不可变节点,除了可变性之外,两者应该完全相同。如何实现基类和可变和不可变类的两个派生类?
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;
}
}
大多数不可变类都具有在不改变实例的情况下操作变量的方法。String类就是这样做的,你可能需要像这样的东西。
public ImmutableBase add(int bar){
return new ImmutableBase(this.foo+bar);
}
foo
就不能是私有的。 - Stephen C为了使一个类成为不可变的,它必须被声明为final,并且不能有setter方法。final声明确保它不能被扩展和添加额外的可变属性。
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
}
这是我所能做的,但你为什么需要这样的场景呢?
final
类Foo
可以“保证”Foo
的实例不会真正成为某个邪恶可变派生Foo
的实例,但有时候拥有一个可继承的、甚至是抽象的类被指定为不可变的(意味着任何可变的派生类都将被视为“损坏”)可能是有帮助的。例如,在某些情况下,定义一个ImmutableMatrix
抽象类可能是有用的,其派生包括ImmutableArrayMatrix
(由与矩阵大小相同的数组支持)、ImmutableConstantMatrix
(由... - supercatImmutableMergedMatrix
(其中将保存对两个或多个ImmutableMatrix
实例的引用,并且对于每个实例,一些整数定义应该应用于最终矩阵的部分)。 如果特定的应用程序将使用内容符合不匹配任何预先存在的实现的某种模式的矩阵,则定义新类可能是有用的。确保,违反不可变性的派生类会破坏事情,但故障... - supercatinterface 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);
}
...
}
这种方法的好处是您只需实现一次业务逻辑,然后可以使用其自身的方法和验证检查来构建对象,然后将其转换为不可变对象。