Можете ли вы объяснить эту вещь об инкапсуляции?

17

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

  

Эти частные переменные-члены были   частный для экземпляра, а не   класс.

(

задан Moayad Mardini 31.08.2009 в 15:35
источник
  • Как это связано с инкапсуляцией? –  p4bl0 31.08.2009 в 15:41
  • Частная видимость заключается в том, как инкапсуляция реализована на таких языках, как Java, C ++ и C # –  Michael Borgwardt 31.08.2009 в 15:43
  • @ p4bl0 Как связаны инкапсуляция и переменная? Довольно принципиально. –  meagar♦ 07.10.2010 в 18:38

3 ответа

35
public class Example {
  private int a;

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

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

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

    
ответ дан Gregory Mostizky 31.08.2009 в 15:37
источник
  • Итак, частные члены являются приватными для класса, и экземпляр может получить доступ к частному члену другого экземпляра, правильно? –  Moayad Mardini 31.08.2009 в 15:42
  • Да, это правильно. –  Gregory Mostizky 31.08.2009 в 15:51
  • ОК, большое спасибо! –  Moayad Mardini 31.08.2009 в 15:53
  • Предполагается, что использование private является средством защиты внешних объектов от непосредственного доступа к реализации. Поскольку это тот же класс, предполагается, что мы знаем, что делаем, когда напрямую обращаемся к частным членам других экземпляров. Как было отмечено выше, это хорошая вещь: равно (), копия Конструкторы (мелкие копий / клоны, все, что вы хотите назвать их), все требуют глубокого знания другого экземпляра одного и того же класса, чтобы сделать свою работу. –  Matthew Scharley 31.08.2009 в 15:53
  • Я часто пишу равным образом (как если бы частные поля другого объекта были недоступны) во всяком случае. Например. класс Point2D будет иметь: public bool equals (объект другой); и public bool равно (double x, double y); Реализации равных могут стать длинными и беспорядочными, и я нахожу это хорошим способом разбить их. –  finnw 31.08.2009 в 16:01
3

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

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 некоторое время. Я предпочитаю не полагаться на доступ к частным полям другого объекта. Помните, что другой объект может принадлежать к подклассу, который может хранить значение в другом поле объекта или в файле или базе данных и т. Д.

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

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

    
ответ дан Michael Borgwardt 31.08.2009 в 15:42
источник
  • "и на всех других языках, которые имеют концепцию видимости, я думаю:« В рубине частный - для каждого объекта. –  sepp2k 31.08.2009 в 15:49
  • Спасибо за информацию, Майкл. –  Moayad Mardini 31.08.2009 в 15:53
  • В Scala вы можете добавить контекст: private [this] –  egaga 07.10.2010 в 04:48