Ниже приведен псевдокод, я пробовал его на Java и PHP, и оба работали:
class Test {
private int a = 5;
public static function do_test(){
var t = new Test();
t.a = 1;
print t.a // 1
}
}
Test::do_test();
Почему вы можете сделать это в парадигме ООП и какая от этого польза?
equals
, это проверка личных полей другого экземпляра. (Публикация в качестве комментария, так как это коротко, и ничего об ООП-this
, поэтому единственные объекты их собственного класса, к которым они могут получить, это те, которые они создают сами (или которые передаются в качестве параметра). Так что, если вы считаете это нарушением инкапсуляции или дырой в безопасности, это не так, как если бы она была очень большой, и, возможно, ее не стоит включать.Ответы:
В Java частные переменные видны всему классу. К ним можно получить доступ из статических методов и из других экземпляров того же класса.
Это, например, полезно в заводских методах . Фабричный метод обычно выполняет инициализацию объекта, который настолько сложен, что вы не хотите оставлять его в коде приложения. Чтобы выполнить инициализацию, методу фабрики часто требуется доступ к внутренним объектам классов, которые вы не хотите раскрывать. Возможность прямого доступа к личным переменным значительно облегчает вашу жизнь.
Однако, когда вы хотите скрыть детали реализации класса даже от статических методов или от других экземпляров этого класса, вы можете использовать шаблон данных закрытого класса . Поместите все частные переменные класса в закрытый внутренний класс и делегируйте любые методы получения или установки для получения и установки этого внутреннего класса.
Другой вариант - определить интерфейс для класса, который объявляет все открытые методы класса, а затем ссылается только на класс под этим интерфейсом везде, где это возможно. Ссылка на тип интерфейса не может использоваться для прямого доступа к чему-либо, не объявленному в интерфейсе, где бы то ни было (конечно, за исключением отражения). Когда вы используете объектно-ориентированный язык программирования, который не имеет интерфейсов (например, C ++), их можно смоделировать с помощью абстрактного базового класса, который наследуется реальным классом.
источник
Некоторые языки и среды выполнения (например, Java, .NET) предполагают, что любому, кто компилирует код для определенного класса, можно доверять, чтобы он не использовал закрытые члены любого экземпляра этого класса способами, которые могли бы нанести ущерб его правильному операция. Другие языки и структуры являются более строгими в этом отношении и не разрешают доступ к закрытым членам экземпляра, за исключением кода, выполняемого в этом экземпляре . Обе конструкции имеют свои преимущества и недостатки.
Самое большое преимущество предоставления любому коду в классе доступа к закрытым членам любого экземпляра состоит в том, что существуют случаи, когда этот уровень доступа является подходящим, и такая
private
работа устраняет необходимость либо иметь другой квалификатор доступа, доступный для этой цели, либо иначе заставьте код выставлять членов более широко, чем было бы в идеале.Преимущество запрета такого доступа (как в случае с Общей объектной моделью Microsoft (COM)) заключается в том, что он позволяет внешнему коду обрабатывать классы как интерфейсы. Если класс
ImmutableMatrix
содержит закрытое или защищенноеdouble[][]
вспомогательное поле и если код внутри класса проверяет вспомогательный массив других экземпляров, то будет невозможно определить класс без поддержки массива (напримерZeroMatrix
,IdentityMatrix
), который внешний код может использовать какImmutable2dMatrix
, без этого класса , имеющего в том числе в области подложки. Если ничто внутри неImmutable2dMatrix
использует закрытые члены какого-либо экземпляра, кромеthis
, то можно было бы переименовать класс вImmutableArrayBackedMatrix
и определить новый абстрактныйImmutableMatrix
класс, который мог бы иметьImmutableArrayBackedMatrix
так же, как и вышеупомянутые классы без поддержки массива, в качестве подтипов.Обратите внимание, что такой рефакторинг не мог бы быть предотвращен, если бы язык «позволял»
ImmutableMatrix
проверять массив резервных копий для другихthis
случаев, кроме случаев, когда язык использовал эту возможность и фактически проверял внешние экземпляры. Основной эффект ограничения языка таким использованием заключается в том, что компилятор немедленно закричит при любой попытке написать код, который не поддается такому рефакторингу.источник
Java не является строго объектно-ориентированным языком, но языком, основанным на классе - класс определяет операции и доступ к поведению, а не экземпляр.
Так что не удивляйтесь, что это позволяет вам делать вещи, которые не являются строго объектно-ориентированными.
Поскольку метод находится в той же области видимости класса, что и экземпляр, он имеет полный доступ к закрытым членам. Подобные правила управляют экземплярами внутренних классов, обращающимися к данным из экземпляров внешних классов - экземпляр внутреннего класса может обращаться к закрытым членам внешнего класса.
Это унаследовано от C ++, где это полезно для создания конструкторов копирования и перемещения. Это также полезно для сравнения или объединения двух объектов, где их значение зависит от членов, которые не являются общедоступными эффективным способом (например, получатель для массива в Java должен копировать массив, чтобы клиентский код не мог его изменить, изменяя внутреннее состояние объекта, но не нужно копировать массивы для сравнения равенства объектов)
источник