繁体   English   中英

可变和不可变的类

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM