你能解释一下关于封装的事吗?

时间:2009-08-31 13:35:13

标签: language-agnostic oop encapsulation

在回答What is your longest-held programming assumption that turned out to be incorrect?问题时,其中一个错误的假设是:

  

私有成员变量是   私有的实例,而不是   类。

Link

我无法理解他正在谈论的内容,任何人都可以用一个例子来解释这是错误/正确的吗?

3 个答案:

答案 0 :(得分:35)

public class Example {
  private int a;

  public int getOtherA(Example other) {
    return other.a;
  }
}

喜欢这个。正如您所看到的,private不保护实例成员不被另一个实例访问。

顺便说一句,只要你有点小心,这并不是一件坏事。 如果private不像上面的例子那样工作,那么编写equals()和其他类似的方法会很麻烦。

答案 1 :(得分:3)

无法能够访问其他对象的私有字段时,这相当于Michael Borgwardt's answer

public class MutableInteger {
    private int value;

    // Lots of stuff goes here

    public boolean equals(Object o) {
        if(!(o instanceof MutableInteger)){ return false; }
        MutableInteger other = (MutableInteger) o;
        return other.valueEquals(this.value); // <------------
    }

    @Override // This method would probably also be declared in an interface
    public boolean valueEquals(int oValue) {
        return this.value == oValue;
    }
}

现在这对Ruby程序员来说很熟悉,但我已经在Java中做了一段时间了。我宁愿不依赖于访问另一个对象的私有字段。请记住,另一个对象可能属于一个子类,它可以将值存储在不同的对象字段中,或存储在文件或数据库等中。

答案 2 :(得分:2)

示例代码(Java):

public class MutableInteger {
    private int value;

    // Lots of stuff goes here

    public boolean equals(Object o) {
        if(!(o instanceof MutableInteger)){ return false; }
        MutableInteger other = (MutableInteger) o;
        return this.value == other.value; // <------------
    }
}

如果假设“私有成员变量对实例是私有的”是正确的,则标记的行将导致编译器错误,因为other.value字段是私有的,并且是与{{1}字段不同的对象的一部分。正在调用方法。

但是,由于在Java(以及大多数具有可见性概念的其他语言)equals()可见性是每个类,因此允许对private的所有代码访问该字段,与实例无关用来调用它。