创建后不应更改属性

Attribute should not be changed after creation

鉴于问题 - "All game objects provide the ability for external code to obtain their size. However, they do not provide the ability to have their size changed once it is created."

如果我有一个 parent class 和这样的私有字段 GameObject class:

public abstract class GameObject {
     private int size;

     public void setSize(int size) {
          this.size = size;
     }
}

和child任class等

public class Dinosaur extends GameObject {
     public Dinosaur() {
           this.setSize(100);
     }
}

public class Jeep extends GameObject {
     public Jeep() {
          this.setSize(10);
     }
 }      

如何保证object创建后尺寸不变? 我很困惑,因为如果我将大小的 setter 方法设为私有,那么我无法在创建时单独设置每个 GameObject 的大小。

编辑:为清楚起见,添加了第二个 child class。

(注意:我假设您打算让 Dinosaur 扩展 GameObject。)

您可以覆盖 setSize() 方法并抛出异常:

public class Dinosaur extends GameObject {
    ...

    @Override
    public void setSize(int size) {
        throw new UnsupportedOperationException("can't change dinosaur size");
    }
}

size 可以是 final 和构造函数中传递的大小值。你也不需要 setter。您可以只制作必要的 getter.

public abstract class GameObject {
    private final int size;

    public GameObject(int size) {
        this.size = size;
    }

     public int getSize() {
         return this.size;
     }
}

您的代码有些问题。

首先,如果 class 不应该在创建后设置大小,为什么要首先提供 setter?

其次,subclass 可以覆盖 abstract class 中的 setSize method 并为所欲为。如果你想要 inheritance 这样做:

public abstract class GameObject {

    private final size;

    public GameObject(int size){
        this.size = size;
    }
}

public class Dinosaur extends GameObject {

    public Dinosaur(int size){
        super(size)
    }
}

未提供 setter,尺寸必须在施工时提供。如果你想要一个方法来做它,使方法final。像这样:

public final setSize(int size){
   this.size = size;
}

通过使其成为 final,子 classes 必须按原样除外方法,不能覆盖。

另一种方法是,使这个 class immutable。您不使用 setters,但您可以使用 getters,并且 class 将变为 final,因此没有 subclassing。

public final Dinosaur {

   private final int size;

   pubilc Dinosaur(int size){
       this.size = size;
   }

   public int getSize(){
       return this.size;
   }
}

如果您需要使 size 变量不可更改,那么您应该使用 final 修饰符。 有两种方法可以为这种变量设置值:1)构造函数 2)内联。只要您希望可以选择在客户端代码中为每个对象设置自定义值,就应该使用构造函数:

public abstract class GameObject {

     private final int size;

     public GameObject(int size) {
         this.size = size;
     }
}

public Dinosaur extends GameObject {

   pubilc Dinosaur(int size){
       super(size);
   }
}

在那种情况下 setter 方法就没有必要了。

Given the question - "All game objects provide the ability for external code to obtain their size. However, they do not provide the ability to have their size changed once it is created."

完成此操作的通常方法是让 parent class 的构造函数接受一个大小参数。此参数设置不可变大小字段的值。 Subclasses 可以很容易地访问这个值,但是一旦设置后他们就无法更改它。这是满足所列要求的最object-oriented方式。

例如:

public abstract class GameObject {
    private final int size;

    public GameObject(int size) {
        this.size = size;
    }

    public int size() { return this.size; }
    :
    :
}

和一个child class:

public class Dinosaur extends GameObject {

    public Dinosaur() {
        super(100);
    }
    :
    :
}

尽管此线程中有一些关于子classes 可能如何动态更改大小字段的讨论,但更好的设计是使用不可变设计,如此处介绍的那样,并让客户端代码请求一个如果需要,使用不同大小的新 object(例如,使用 copyOf() 方法)。与可变设计相比,不可变设计有几个优点,通常是规划价值 classes.

的方法