Можете ли вы объяснить эту вещь о инкапсуляции? - PullRequest
17 голосов
/ 31 августа 2009

В ответ на Какое ваше давнее предположение о программировании оказалось неверным? вопрос, одно из неправильных предположений было:

что закрытые переменные-члены были частный случай, а не класс.

( Link )

Я не мог уловить, о чем он говорит, кто-нибудь может объяснить, что в этом плохого / правильного на примере?

Ответы [ 3 ]

35 голосов
/ 31 августа 2009
public class Example {
  private int a;

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

Вот так. Как видите, private не защищает элемент экземпляра от доступа другого экземпляра.

Кстати, это не так уж и плохо, если вы немного осторожны. Если private не будет работать, как в приведенном выше примере, было бы неудобно писать equals () и другие подобные методы.

3 голосов
/ 31 августа 2009

Вот эквивалент ответа Майкла Боргвардта , когда вы не можете получить доступ к закрытым полям другого объекта:

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 голосов
/ 31 августа 2009

Пример кода (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 является закрытым и является частью объекта, отличного от того, чей метод equals() называется.

Но так как в Java (и в большинстве других языков, имеющих концепцию видимости) private видимость - для каждого класса, доступ к полю разрешен ко всему коду MutableInteger, независимо от того, какой экземпляр использовался для вызова это.

...