简体   繁体   English

可变和不可变的类

[英]mutable and immutable classes

I want to create mutable and immutable node in java, both should be the same in everything except the mutable. 我想在java中创建可变和不可变的节点,除了mutable之外,两者都应该是相同的。 how to implement the base class and the two derived class of mutable and immutable classes ? 如何实现基类和可变和不可变类的两个派生类?

The difference between mutable and immutable classes is that immutable classes have no setters or any other methods that modify internal state. 可变类和不可变类之间的区别在于,不可变类没有setter或任何其他修改内部状态的方法。 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. 调用父类Immutable是一个坏主意,因为当你有子类时,这将不再是真的。 The name would be misleading: 该名称会产生误导:

ImmutableNode node = new MutableNode();
((MutableNode)node).change();

All you need to do is create a single base class with protected variables 您需要做的就是创建一个带有受保护变量的基类

public class Base{
     protected int foo;
}

The mutable one needs to be able to set the variable 可变的需要能够设置变量

public class MutableBase extends Base{
     public void setFoo(){}
}

The immmutable one needs to be able to set the variable only once 不可改变的只需要能够设置变量一次

public class ImmutableBase extends Base{
     public ImmutableBase(int foo){
          this.foo = foo;
     }
}

Most immutable classes, have methods to act on the variable inside without mutating the instance. 大多数不可变类都有方法在改变实例的情况下对变量进行操作 String does this, you might want something like this 字符串执行此操作,您可能需要这样的东西

public ImmutableBase add(int bar){
     return new ImmutableBase(this.foo+bar);
}

The cool thing about this is that you give the users of your class less control/worry over the internals of each instance. 关于这一点很酷的是,你给你的班级用户减少了对每个实例内部的控制/担心。 This makes it easier to work with, because in Java everything is passed by object reference, so if you're passing around a String or an ImmutableBase, you don't have to worry about it being changed. 这使得它更容易使用,因为在Java中,所有内容都通过对象引用传递,因此如果您传递String或ImmutableBase,则不必担心它会被更改。

Immutable class is a class which once created, it's contents can not be changed. 不可变类是一个曾经创建过的类,它的内容无法更改。 Immutable objects are the objects whose state can not be changed. 不可变对象是其状态无法更改的对象。

A common example of immutable class in Java is String class . Java中不可变类的一个常见示例是String类。

for a class to be immutable it must be declared final, and it must not haver setter methods. 对于一个不可变的类,它必须被声明为final,并且它不能使用setter方法。 the final declaration ensures that it cannot be extended and additional mutable properties added. 最终声明确保无法扩展它并添加其他可变属性。

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

    }

Thats the little i can do? 多数民众赞成我可以做的一点点? But why would you need such a scenario? 但为什么你需要这样的场景呢?

Another option is to use the same strategy as the UnmodifiableList . 另一种选择是使用与UnmodifiableList相同的策略。 First, create an interface specifying the type. 首先,创建指定类型的接口。

interface List<T>{
    List<T> add(T t);
    T getAt(int i);
    ...
}

Then you implement your mutable class with all the business logic: 然后使用所有业务逻辑实现可变类:

public class MutableList<T> implements List<T>{
    @Override
    List<T> add(T t){ ... }

    @Override
    T getAt(int i){ ... }

    ...
}

And finally, create your immutable class to be a view of the mutable one. 最后,创建不可变类以成为可变类的视图。 You implement the same interface but delegate all read method calls to the viewed object, and forbid any write access with an Exception. 您实现相同的接口,但将所有读取方法调用委托给查看的对象,并禁止任何带有异常的写入访问。

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);
    }

    ...
}

This approach has the benefit that you implement the business logic only once, and can first build an Object using its own methods and validation checks before turning it into an imutable object. 这种方法的好处是,您只需要实现一次业务逻辑,并且可以先使用自己的方法和验证检查构建一个Object,然后再将其转换为可重定义的对象。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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