2009-08-31 3 views
17

В ответ на What is your longest-held programming assumption that turned out to be incorrect? вопрос, один из ошибочных предположений был:Можете ли вы объяснить эту вещь об инкапсуляции?

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

(Link)

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

+0

Как это связано с инкапсуляцией? – p4bl0

+6

Частная видимость заключается в том, как инкапсуляция реализована на таких языках, как Java, C++ и C# –

+1

@ p4bl0 Как связаны инкапсуляция и область видимости переменной? Довольно принципиально. – meagar

ответ

35
public class Example { 
    private int a; 

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

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

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

+3

Так что частные члены являются закрытыми для класса, и экземпляр может получить доступ к частному члену другого экземпляра, правильно? –

+0

Да, это правильно. –

+0

ОК, большое спасибо! –

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, не относящегося к какому экземпляру для его вызова.

+2

"и на всех других языках, имеющих концепцию видимости, я думаю:« В рубине личное - для каждого объекта. – sepp2k

+0

Спасибо за информацию, Майкл. –

+0

В Scala вы можете добавить контекст: private [this] – egaga

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; 
    } 
} 

В настоящее время это знакомо Руби программистов, но я делал это в Java для какое-то время. Я предпочитаю не полагаться на доступ к частным полям другого объекта. Помните, что другой объект может принадлежать подклассу, который может хранить значение в другом поле объекта или в файле или базе данных и т. Д.

Смежные вопросы