封装冗余 Setter

encapsulation redundant Setter

我最近发现有一个编码包含冗余代码。例如,如果我将 Setter 留在外面(第 18-21 行)。 sumnr,它仍然运行良好。因此该代码似乎是不必要的。 但是,如果我将 this.sumnr = sumnr;(第 11 行)留在外面,并将 Setter 留在原地,那么它就不起作用了。为什么 this.sumnr = sumnr 不能被第 18-21 行的 Setter 备份?

有人知道吗?

public class SortSums {
    private int sumnr;
    private int part1;
    private int part2;
    private int result;
    private int answer;
    private String sign;

    public SortSums(int somnr, int part1, int part2, int result, String sign)
    {
        this.sumnr = sumnr;    // LINE11  this line however, seems indispensible. 
        this.part1 = part1;    // idem
        this.part2 = part2;
        this.result = result;
        this.sign = sign;
    }

    public void setSumnr(int sumnr)  // LINE18 it seems that this 'void' method is redundant.
    {
        this.sumnr = sumnr;
    } // LINE21

    public int getSumnr()
    {
        return sumnr;
    }

//etc...

因为 Java 从不在幕后调用 setters 魔法 自动(某些语言会,或者好像)。如果您在构造函数中编写 this.sumnr = sumnr;,它不会替代对 setter 的调用。如果你有一个 setter,它不会调用它,除非你在构造函数中编写了对它的实际调用。

如果您想使用第 11 行的 setter,您需要将其替换为:

this.setSumnr(sumnr);

从构造函数中调用方法通常不是最佳实践(虽然有些人认为 setters 是该规则的豁免;其他人不认为)。

If I leave the Setter out (Line18-21) for eg. sumnr, it still works perfectly well. So that code seems unnecessary.

不一定。这完全取决于您是否希望在创建 SortSums 对象后允许更改 sumnr。如果这样做,您会想要 setter。如果你不这样做,就把它留在外面。

Andreas在中说的很好:构造函数是用来设置字段的初始值的。 setter 用于稍后根据需要将该值更改为其他值。

您在评论中说:

If I disable that void part. (Sumnr is a counter that is risen in another part of the code), That sumnr will just get changed than. No matter whether I leave the void Setter or not. It all just seems not clear to me.

没错。您不需要 setter 从 SortSums 代码中更改 sumnr 字段的值;你可以直接分配给它。 setter 的目的是允许 SortSums 的代码 outside 设置 sumnr 字段 如果你想要的话可能。如果您不希望它成为可能,请关闭 setter.

让我们简化一下。

使用 setter,class 之外的代码可以直接更改字段:

class WithSetter {
    private int value;

    public WithSetter(int value) {
        this.value = value;
    }

    public void setValue(int value) {
        this.value = value;
    }

    public void incrementValue() {
        ++this.value;
    }

    public int getValue() {
        return this.value;
    }
}

class ExampleWith {
    public static void main(String[] args) {
        var w = new WithSetter(0);
        w.incrementValue();
        System.out.println(w.getValue()); // 1
        w.setValue(7);                           // <=== Works just fine
        System.out.println(w.getValue()); // 7
    }
}

当然,这并不是 class 之外的真正代码;这是 setter 中的代码。但是可以从 class.

外部调用 setter

没有 setter,class 之外的代码无法直接设置值:

class WithoutSetter {
    private int value;

    public WithoutSetter(int value) {
        this.value = value;
    }

    public void incrementValue() {
        ++this.value;
    }

    public int getValue() {
        return this.value;
    }
}

class ExampleWithOut {
    public static void main(String[] args) {
        var w = new WithoutSetter(0);
        w.incrementValue();
        System.out.println(w.getValue()); // 1
        w.setValue(7);                           // <=== Won't compile
        w.value = 7;                             // <=== Also won't compile
        System.out.println(w.getValue());
    }
}

WithoutSetter中,只有代码在class中可以改变value。 class 之外的任何代码都可以(不使用反射,但那是另一个话题)。