我想在java中创建可变且不可变的节点,除了mutable之外,两者都应该是相同的。如何实现基类和可变和不可变类的两个派生类?
答案 0 :(得分:4)
可变类和不可变类之间的区别在于,不可变类没有setter或任何其他修改内部状态的方法。状态只能在构造函数中设置。
调用父类Immutable是一个坏主意,因为当你有子类时,这将不再是真的。该名称会产生误导:
ImmutableNode node = new MutableNode();
((MutableNode)node).change();
答案 1 :(得分:4)
您需要做的就是创建一个带有受保护变量的基类
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);
}
关于这一点很酷的是,您可以为您的班级用户 少 控制/担心每个实例的内部。这使得它更容易使用,因为在Java中,所有内容都通过对象引用传递,因此如果您传递String或ImmutableBase,则不必担心它会被更改。
答案 2 :(得分:1)
不可变类是一个曾经创建过的类,它的内容无法更改。不可变对象是其状态无法更改的对象。
Java中不可变类的一个常见示例是String类。
答案 3 :(得分:1)
对于一个不可变的类,它必须被声明为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
}
多数民众赞成我可以做的一点点?但为什么你需要这样的场景?
答案 4 :(得分:1)
另一种选择是使用与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);
}
...
}
这种方法的好处是,您只需要实现一次业务逻辑,并且可以先使用自己的方法和验证检查构建一个Object,然后再将其转换为可重定义的对象。