class Person
{
private BankAccount account;
Person(BankAccount account)
{
this.account = account;
}
public Person someMethod(Person person)
{
//Why accessing private field is possible?
BankAccount a = person.account;
}
}
Забудьте о дизайне. Я знаю, что ООП указывает, что частные объекты являются частными для класса. У меня вопрос: почему ООП было разработано таким образом, чтобы частные поля имели доступ на уровне класса, а не на уровне объекта ?
someMethod
Не действует. Он ничего не возвращает. Так должно бытьvoid
.Ответы:
Мне тоже немного любопытен ответ.
Наиболее удовлетворительный ответ, который я нашел, получен от Artemix в другом сообщении здесь (я переименовал AClass в класс Person): Почему модификаторы доступа на уровне класса вместо уровня объекта?
РЕДАКТИРОВАТЬ: Пожалуйста, проголосуйте за ответ Артемикса. Я просто копирую это.
источник
Person
классаPerson
, не должен знать реализацию всего класса. Хорошая практика - использовать средство доступа, не зная, какие операции выполняет средство доступа.equals(Object)
метод в классе Java, чтобы проверить равенствоPerson
объекта другому экземпляруPerson
. Вы можете разрешить внешнему миру проверять, равны ли два экземпляра, но вы можете не захотеть открывать все закрытые поля класса, необходимые для проверки равенства, внешнему миру с использованием общедоступных методов доступа. Доступ кprivate
полям на уровне класса позволяет реализовать такой метод без вынужденной необходимости реализовывать такие общедоступные методы.equals
).equals
может быть выполнена путем вызова частных средств доступа.private
должен предоставлять доступ на уровне класса. Я согласен с тем, что использование аксессуаров - это вообще хорошая привычка, хотя в данном случае это в основном вопрос контекста и личного стиля. Обратите внимание, что и Джошуа Блох в Эффективной Java (элемент 8), и Тал Коэн в этой статье доктора Доббса напрямую обращаются к закрытым полям в своих листингах кода при обсуждении того, как реализоватьequals
.См. Спецификацию языка Java, раздел 6.6.1. Определение доступности
Здесь утверждается
Щелкните ссылку выше для получения более подробной информации. Итак, ответ таков: потому что Джеймс Гослинг и другие авторы Java решили, что это так.
источник
Хороший вопрос. Похоже, что модификатор доступа на уровне объекта еще больше усилит принцип инкапсуляции.
Но на самом деле все наоборот. Возьмем пример. Предположим, вы хотите глубоко скопировать объект в конструкторе, если у вас нет доступа к закрытым членам этого объекта. Тогда единственный возможный способ - добавить несколько открытых методов доступа ко всем закрытым членам. Это сделает ваши объекты открытыми для всех остальных частей системы.
Таким образом, инкапсуляция не означает закрытие для всего остального мира. Это означает избирательность в отношении того, кому вы хотите быть открытыми.
источник
o.deepCopy()
или что-то еще.Это работает, потому что вы находитесь в
class Person
- классе разрешено тыкать внутрь своего собственного типа класса. Это действительно помогает, когда вы хотите написать конструктор копирования, например:class A { private: int x; int y; public: A(int a, int b) x(a), y(b) {} A(A a) { x = a.x; y = y.x; } };
Или, если мы хотим писать
operator+
иoperator-
для нашего класса больших чисел.источник
Только мои 2 цента на вопрос, почему семантика частной видимости в Java - это уровень класса, а не уровня объекта.
Я бы сказал, что ключевым моментом здесь является удобство . Фактически, частная видимость на уровне объекта вынудила бы предоставить методы другим классам (например, в том же пакете) в сценарии, показанном OP.
По правде говоря, я не смог ни придумать, ни найти пример, показывающий, что видимость на уровне частных классов (например, предлагаемая Java) создает какие-либо проблемы по сравнению с видимостью на уровне частных объектов.
Тем не менее, языки программирования с более детальной системой политик видимости могут обеспечить видимость объектов как на уровне объекта, так и на уровне класса.
Например, Eiffel предлагает выборочный экспорт: вы можете экспортировать любую функцию класса в любой класс по вашему выбору, от {NONE} (объектно-частный) до {ANY} (эквивалент общедоступного, а также значение по умолчанию) до {PERSON} (class-private, см. пример OP), для определенных групп классов {PERSON, BANK}.
Также интересно отметить, что в Eiffel вам не нужно делать атрибут закрытым и писать геттер, чтобы предотвратить его присвоение другими классами. Публичные атрибуты в Eiffel по умолчанию доступны в режиме только для чтения, поэтому вам не нужен геттер только для возврата их значения.
Конечно, вам по-прежнему нужен установщик для установки атрибута, но вы можете скрыть его, определив его как «назначитель» для этого атрибута. Это позволяет вам, если хотите, использовать более удобный оператор присваивания вместо вызова установщика.
источник
Поскольку
private
модификатор доступа делает его видимым только внутри класса . Этот метод все еще находится в классе .источник
private
поле доступно в классе / объект , в котором объявлено поле. Он является частным для других классов / объектов за пределами того, в котором он находится.источник
Первое, что здесь мы должны понять, это все, что нам нужно сделать, это следовать принципам oops, поэтому инкапсуляция означает, что данные обертываются внутри пакета (т.е. класса), а затем все данные представляются как объект и легко доступны. поэтому, если мы сделаем поле не приватным, то доступ к нему будет осуществляться индивидуально. и это приводит к плохому параличу.
источник
С концепцией отражения в Java можно изменять поля и методы.
Изменение методов и частных лиц с Refleccion en Java
источник