[英]mutable and immutable classes
我想在java中创建可变和不可变的节点,除了mutable之外,两者都应该是相同的。 如何实现基类和可变和不可变类的两个派生类?
可变类和不可变类之间的区别在于,不可变类没有setter或任何其他修改内部状态的方法。 状态只能在构造函数中设置。
调用父类Immutable是一个坏主意,因为当你有子类时,这将不再是真的。 该名称会产生误导:
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,则不必担心它会被更改。
不可变类是一个曾经创建过的类,它的内容无法更改。 不可变对象是其状态无法更改的对象。
Java中不可变类的一个常见示例是String类。
对于一个不可变的类,它必须被声明为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);
}
...
}
这种方法的好处是,您只需要实现一次业务逻辑,并且可以先使用自己的方法和验证检查构建一个Object,然后再将其转换为可重定义的对象。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.