.equals()
сравнивает данные в классе (при условии, что функция реализована). ==
сравнивает местоположения указателя (расположение объекта в памяти).
==
возвращает true, если оба объекта (NOT TALKING OF PRIMITIVES) указывают на экземпляр SAME. .equals()
возвращает true, если два объекта содержат одни и те же данные equals()
Versus ==
в Java
Это может вам помочь.
Официальный учебник может вам пригодиться.
│ Class │ Package │ Subclass │ Subclass │ World │ │ │(same pkg)│(diff pkg)│ ────────────┼───────┼─────────┼──────────┼──────────┼──────── public │ + │ + │ + │ + │ + ────────────┼───────┼─────────┼──────────┼──────────┼──────── protected │ + │ + │ + │ + │ ────────────┼───────┼─────────┼──────────┼──────────┼──────── no modifier │ + │ + │ + │ │ ────────────┼───────┼─────────┼──────────┼──────────┼──────── private │ + │ │ │ │ + : accessible blank : not accessible
| highest precedence <---------> lowest precedence
*———————————————+———————————————+———————————+———————————————+———————
\ xCanBeSeenBy | this | any class | this subclass | any
\__________ | class | in same | in another | class
\ | nonsubbed | package | package |
Modifier of x \ | | | |
————————————————*———————————————+———————————+———————————————+———————
public | ✔ | ✔ | ✔ | ✔
————————————————+———————————————+———————————+———————————————+———————
protected | ✔ | ✔ | ✔ | ✘
————————————————+———————————————+———————————+———————————————+———————
package-private | | | |
(no modifier) | ✔ | ✔ | ✘ | ✘
————————————————+———————————————+———————————+———————————————+———————
private | ✔ | ✘ | ✘ | ✘
protected
делает помеченную вещь i> (класс, метод или поле) доступной для какого-либо другого класса в каком-либо другом пакете , только если f говорит, что другой класс является подкласс класса, где объявлена эта protected
- отмеченная вещь i>.
– Abdull
15 August 2016 в 18:14
Итак, давайте поговорим о Access Control and Inheritance . Следующие правила для унаследованных методов:
public
в суперклассе также должно быть общедоступным во всех подклассах. protected
в суперклассе должны быть либо protected
, либо public
в подклассах; они не могут быть частными. private
не наследуются вообще, поэтому для них нет правила. Я просто хочу обратиться к деталям, которые чрезвычайно часто ошибаются, в том числе большинством ответов на этой странице. Доступ «по умолчанию» (когда нет модификатора доступа) не всегда совпадает с пакетом-частным. Это зависит от того, что это такое.
default
был добавлен в методы интерфейса в Java 8 :)
– Tomas
29 October 2015 в 11:41
Все дело в инкапсуляции (или, как сказал Джо Филлипс, наименьшее знание ).
Начните с самого ограничительного (частного) и посмотрите, нужно ли вам менее ограничительные модификаторы позже .
Мы все используем модификаторы метода и члена, такие как private, public, ... но одна вещь, которую слишком мало разработчиков делают, это использовать пакеты для логического упорядочения кода.
Например: You могут помещать чувствительные методы защиты в пакет «безопасность». Затем поместите открытый класс, который обращается к некоторому коду безопасности, содержащемуся в этом пакете, но сохраняет другие классы классов безопасности частными. Таким образом, другие разработчики смогут использовать общедоступный класс вне этого пакета (если только они не изменят модификатор). Это не функция безопасности, но будет определять использование.
Outside world -> Package (SecurityEntryClass ---> Package private classes)
Другое дело, что классы, которые много зависят друг от друга, могут оказаться в одном пакете и в конечном итоге могут быть реорганизованы или объединены, если
Если, напротив, вы устанавливаете все как общедоступные, неясно, к чему следует или не следует обращаться, что может привести к написанию большого количества javadoc (что ничем не навязывает компилятор ...).
Методы, переменные и конструкторы, объявленные как private, могут быть доступны только в объявленном классе
Модификатор частного доступа является самым ограничивающим уровнем доступа. Класс и интерфейсы не могут быть частными.
Примечание
Переменные, объявленные как private, могут быть доступны за пределами класса, если публичный getter методы присутствуют в классе. Доступ к переменным, методам и конструкторам, которые объявлены защищенными в суперклассе, могут быть доступны только подклассами другого пакета или любого класса в пакете класса защищенных членов.
Модификатор защищенного доступа не может применяться к классу и интерфейсам.
Методы, поля могут быть объявлены защищенными, однако методы и поля в интерфейсе не могут быть объявлены защищенными.
Примечание
Защищенный доступ дает подклассу возможность использовать вспомогательный метод или переменную, предотвращая попытку использовать неродственный класс.
Доступ к классу, методу, конструктору, интерфейсу и т. д. может быть доступен из любого другого класса.
Поэтому поля, методы, блоки, объявленные внутри открытого класса, могут быть доступны из любого класса, принадлежащего Java-юнита
Однако, если публичный класс мы пытаемся доступ находится в другом пакете, тогда публичный класс все равно необходимо импортировать.
Из-за наследования класса все общедоступные методы и переменные класса наследуются его подклассами.
Модификатор по умолчанию означает, что мы явно не объявляем модификатор доступа для класса, поля, метода и т. д.
Переменная или метод, объявленный без модификатора управления доступом, доступен для любого другого класса в одном пакете. Поля в интерфейсе являются неявно публичными статическими окончательными, а методы в интерфейсе по умолчанию общедоступны.
Примечание
Мы не можем переопределить Статические поля. Если вы пытаетесь переопределить его, он не показывает никаких ошибок, но он не работает, кроме нас.
http://docs.oracle.com/javase/tutorial/java/javaOO/accesscontrol.html http://www.tutorialspoint.com/java/java_access_modifiers.htm
Самый непонятый модификатор доступа в Java - protected
. Мы знаем, что он похож на модификатор по умолчанию с одним исключением, в котором подклассы могут его видеть. Но как? Вот пример, который, надеюсь, прояснит путаницу:
Father
и Son
, каждый в своем собственном пакете: package fatherpackage;
public class Father
{
}
-------------------------------------------
package sonpackage;
public class Son extends Father
{
}
foo()
в Father
. package fatherpackage;
public class Father
{
protected void foo(){}
}
foo()
можно вызвать в 4 контекстах: внутри класса, который находится в том же пакете, где foo()
определен (fatherpackage
): package fatherpackage;
public class SomeClass
{
public void someMethod(Father f, Son s)
{
f.foo();
s.foo();
}
}
Внутри подкласса , в текущем экземпляре через this
или super
: package sonpackage;
public class Son extends Father
{
public void sonMethod()
{
this.foo();
super.foo();
}
}
В ссылке, тип которой является одним и тем же классом: package fatherpackage;
public class Father
{
public void fatherMethod(Father f)
{
f.foo(); // valid even if foo() is private
}
}
-------------------------------------------
package sonpackage;
public class Son extends Father
{
public void sonMethod(Son s)
{
s.foo();
}
}
В ссылке, тип которой является родительским классом, и внутри пакет, где foo()
определен (fatherpackage
) [Это может быть включено внутри контекста no. 1]: package fatherpackage;
public class Son extends Father
{
public void sonMethod(Father f)
{
f.foo();
}
}
fatherpackage
: package sonpackage;
public class Son extends Father
{
public void sonMethod(Father f)
{
f.foo(); // compilation error
}
}
: не подкласс внутри пакета подкласса наследует защищенные члены от своего родителя и делает их частными для не-подклассов): package sonpackage;
public class SomeClass
{
public void someMethod(Son s) throws Exception
{
s.foo(); // compilation error
}
}
super.foo()
и первой недействительной ситуацией f.foo()
?
– cst1992
28 October 2017 в 09:18
protected
. К сожалению, все остальные ответы на этой странице, которые определяют protected
, немного ошибочны.
– Dawood ibn Kareem
11 July 2018 в 06:20
Часто я осознавал, что запоминание основных понятий любого языка может быть сделано путем создания реальных аналогов. Вот моя аналогия для понимания модификаторов доступа в Java:
Предположим, что вы студент в университете, и у вас есть друг, который приезжает к вам в выходные. Предположим, что в центре кампуса существует большая статуя основателя университета.
Надеюсь, что это поможет!
Разницу можно найти в уже упомянутых ссылках, но тот, который используется, обычно сводится к «Принципу наименьшего знания». Разрешите только минимальную видимость.
Легкое правило. Начните с объявления всех частных. И затем продвигаться к общественности по мере возникновения потребностей, и дизайн ее оправдывает.
Когда выставлять участников, спросите себя, подвергаете ли вы выбор выбора или выбор абстракции. Первое - это то, чего вы хотите избежать, поскольку оно будет вводить слишком много зависимостей от фактического представления, а не от его наблюдаемого поведения.
Как правило, я стараюсь избегать переопределения реализации метода путем подкласса; слишком легко испортить логику. Объявляйте абстрактные защищенные методы, если вы намерены переопределить его.
Кроме того, используйте аннотацию @Override при переопределении, чтобы препятствовать тому, чтобы что-то было нарушено при рефакторе.
Как правило:
В результате, если мы разделим права доступа на три права:
g9]
, тогда у нас есть эта простая таблица:
+—-———————————————+————————————+———————————+
| | Same | Different |
| | Package | Packages |
+—————————————————+————————————+———————————+
| private | D | |
+—————————————————+————————————+———————————+
| package-private | | |
| (no modifier) | D R I | |
+—————————————————+————————————+———————————+
| protected | D R I | I |
+—————————————————+————————————+———————————+
| public | D R I | R I |
+—————————————————+————————————+———————————+
Ответ Дэвида дает смысл каждого модификатора доступа. Что касается использования каждого из них, я бы предложил публиковать все классы и методы каждого класса, предназначенные для внешнего использования (его API), и все остальное частное.
Со временем вы будете развивать смысл для того, чтобы сделать некоторые классы private-private и когда объявлять определенные методы, защищенные для использования в подклассах.
Когда вы думаете о модификаторах доступа, просто подумайте об этом таким образом (применительно к обеим переменным и методам):
public
-> доступно из любого места private
-> доступно только в том же классе, где он объявлен
. Теперь возникает путаница, когда дело доходит до default
и protected
default
-> Нет ключевого слова модификатора доступа , Это означает, что он доступен строго в пакете класса. Нигде за пределами этого пакета он доступен.
protected
-> Чуть менее строже, чем default
, и кроме тех же классов пакетов, к ним могут обращаться под-классы вне пакета / g0] объявлено.
Очень короткий
public
: доступный извне. protected
: доступно классами одного и того же пакета и подклассами, находящимися в любом пакете. private
: доступно только в одном классе. Public Protected Default и private - модификаторы доступа.
Они предназначены для инкапсуляции или скрытия и отображения содержимого класса.
Частный недоступен вне класса. По умолчанию доступен только в пакете. Защищен в пакете, а также в любом классе, который его расширяет. Публикация открыта для всех.
Обычно переменные-члены определяются частными, но методы-члены являются общедоступными.
Default
не является модификатором доступа, а два других - с ошибкой.
– user207421
24 September 2016 в 03:13
(Caveat: Я не программист на Java, я программист Perl. Perl не имеет формальных защит, и, возможно, поэтому я так хорошо понимаю проблему :))
Как вы думаете, это может увидеть только класс, в котором он был объявлен.
Может отображаться и использоваться только пакетом, в котором он был объявлен , Это значение по умолчанию в Java (которое некоторые считают ошибкой).
Пакет Private + можно увидеть подклассами или членами пакета.
Каждый может видеть это.
Видимый вне кода, который я контролирую. (Хотя это не синтаксис Java, это важно для этого обсуждения).
C ++ определяет дополнительный уровень, называемый «friend», и чем меньше вы знаете, тем лучше.
Когда вы должны использовать что? Вся идея заключается в инкапсуляции, чтобы скрыть информацию. Насколько это возможно, вы хотите скрыть детали того, как что-то делается от ваших пользователей. Зачем? Потому что тогда вы можете изменить их позже и не нарушать чей-то код. Это позволяет оптимизировать, реорганизовывать, реорганизовывать и исправлять ошибки, не опасаясь, что кто-то использует этот код, который вы только что пересмотрели.
Итак, эмпирическое правило - сделать вещи такими же видимыми, как и должно быть. Начните с частных и только добавьте больше видимости по мере необходимости. Публикуйте только то, что абсолютно необходимо знать пользователю, каждая деталь, которую вы делаете публичными судорогами, позволяет вам редизайн системы.
Если вы хотите, чтобы пользователи могли настраивать поведение, а не делать внутренние сообщения общедоступными поэтому они могут переопределить их, часто лучше перетащить эти кишки в объект и сделать этот интерфейс общедоступным. Таким образом, они могут просто подключить новый объект. Например, если вы пишете проигрыватель компакт-дисков и хотите, чтобы бит «идти найти информацию об этом компакт-диске» настраивался, а не публиковать эти методы, вы включили бы все эти функции в свой собственный объект и сделали бы свой объект getter / setter общедоступным , Таким образом, скупость о том, чтобы разоблачить ваши кишки, поощряет хороший состав и разделение проблем
Лично я придерживаюсь только «частных» и «публичных». У многих языков OO есть это. «Защищенный» может пригодиться, но это действительно чит. Когда интерфейс более чем частный, он находится вне вашего контроля, и вам нужно искать в коде других людей, чтобы найти его.
Здесь возникает идея «опубликования». Изменение интерфейса (рефакторинг он) требует, чтобы вы нашли весь код, который его использует, и измените это. Если интерфейс частный, то проблем нет. Если он защищен, вам нужно найти все ваши подклассы. Если это общедоступно, вам нужно найти весь код, который использует ваш код. Иногда это возможно, например, если вы работаете с корпоративным кодом, который используется только для внутреннего использования, не имеет значения, открыт ли интерфейс. Вы можете извлечь весь код из корпоративного репозитория. Но если интерфейс «опубликован», если есть код, использующий его вне вашего контроля, тогда вы будете закрыты. Вы должны поддерживать этот интерфейс или код нарушения риска. Даже защищенные интерфейсы можно считать опубликованными (поэтому я не беспокоюсь о защите).
Многие языки считают, что иерархический характер public / protected / private слишком ограничен и не соответствует действительности. С этой целью существует понятие класса trait , но это еще одно шоу.
friend
хорош для определения особых отношений между классами. Он позволяет во многих случаях обеспечить превосходную инкапсуляцию при правильном использовании. Например, он может использоваться привилегированным заводским классом для ввода внутренних зависимостей в построенный тип. У него плохое имя, потому что люди, которые не заботятся о правильном поддержании хорошо продуманной объектной модели, могут злоупотреблять им, чтобы облегчить их рабочую нагрузку.
– Dennis
8 December 2014 в 11:05
Примечание: Это просто дополнение для принятого ответа.
Это связано с Java модификаторами доступа .
Из Модификаторы доступа Java :
Модификатор доступа Java указывает, какие классы могут получить доступ к данному классу и его полям, конструкторам и методам. Модификаторы доступа могут быть указаны отдельно для класса, его конструкторов, полей и методов. Модификаторы доступа Java иногда также упоминаются в ежедневной речи как спецификаторы доступа Java, но правильное имя - модификаторы доступа Java. Классы, поля, конструкторы и методы могут иметь один из четырех различных модификаторов доступа Java:
- Элемент списка
- private
- default (package)
- protected
- public
Из Управление доступом к членам класса :
Модификаторы уровня доступа определяют, могут ли другие классы использовать определенное поле или вызвать конкретный метод. Существует два уровня контроля доступа:
- На верхнем уровне - public или package-private (без явного модификатора).
- На уровне участника - общедоступный, закрытый , protected или package-private (без явного модификатора).
Класс может быть объявлен публичным модификатором, и в этом случае этот класс будет виден всем классам. Если класс не имеет модификатора (по умолчанию, также известного как private-package), он виден только в его собственном пакете
В следующей таблице показан доступ к членам, разрешенным каждым модификатором.
╔═════════════╦═══════╦═════════╦══════════╦═══════╗ ║ Modifier ║ Class ║ Package ║ Subclass ║ World ║ ╠═════════════╬═══════╬═════════╬══════════╬═══════╣ ║ public ║ Y ║ Y ║ Y ║ Y ║ ║ protected ║ Y ║ Y ║ Y ║ N ║ ║ no modifier ║ Y ║ Y ║ N ║ N ║ ║ private ║ Y ║ N ║ N ║ N ║ ╚═════════════╩═══════╩═════════╩══════════╩═══════╝
Первый столбец данных указывает, имеет ли сам класс доступ к члену, определенному уровнем доступа. Как вы можете видеть, у класса всегда есть доступ к своим членам. Во втором столбце указано, имеют ли классы в том же пакете, что и класс (независимо от их происхождения), доступ к члену. Третий столбец указывает, имеют ли подклассы класса, объявленного вне этого пакета, доступ к элементу. Четвертый столбец указывает, имеют ли все классы доступ к члену.
Уровни доступа влияют на вас двумя способами. Во-первых, когда вы используете классы, которые поступают из другого источника, например классы на платформе Java, уровни доступа определяют, какие члены этих классов могут использовать ваши собственные классы. Во-вторых, когда вы пишете класс, вам нужно решить, какой уровень доступа должен иметь каждая переменная-член и каждый метод в вашем классе.
Это на самом деле немного сложнее, чем простые сетки. В сетке указано, разрешен ли доступ, но что именно представляет собой доступ? Кроме того, уровни доступа взаимодействуют с вложенными классами и наследованием сложными способами.
Доступ по умолчанию (указанный отсутствием ключевого слова) также называется package-private . Исключение: в интерфейсе никакой модификатор не означает открытый доступ; модификаторы, отличные от общедоступных, запрещены.
Доступен ли доступ к члену с указанным спецификатором доступа?
private
: Только если член определен в том же классе, что и вызывающий код. protected
: Тот же пакет, или если член определен в суперклассе класса, содержащего вызывающий код. public
: Да. Локальные переменные и формальные параметры не могут принимать спецификаторы доступа. Поскольку они по своей сути недоступны снаружи в соответствии с правилами съемки, они фактически закрыты.
Для классов в верхней области допускаются только public
и private-package. Предполагается, что этот выбор дизайна из-за того, что protected
и private
будут избыточными на уровне пакета (нет наследования пакетов).
Все возможности доступа доступны для членов класса (конструкторы, методы и статические функции-члены, вложенные классы).
Связано: Доступность класса Java
Спецификаторы доступа могут быть строго упорядочены
public> protected> package-private> private
, что означает, что
public
обеспечивает наибольший доступ,private
наименее. Любая ссылка, доступная для частного члена, также действительна для члена пакета-частного; любая ссылка на член пакета-частного действительна для защищенного члена и так далее. (Предоставление доступа к защищенным членам другим классам в одном пакете считалось ошибкой.)Примечания
- Методам класса разрешен доступ к закрытым членам другие объекты одного и того же класса. Точнее, метод класса C может обращаться к частным членам C на объектах любого подкласса C. Java не поддерживает ограничение доступа экземпляром только по классу. (Сравните с Scala, который поддерживает его с помощью
private[this]
.)- Вам нужен доступ к конструктору для построения объекта. Таким образом, если все конструкторы являются частными, класс может быть создан только кодом, живущим внутри класса (обычно статические фабричные методы или инициализаторы статической переменной). Аналогично для конструкторов private-private или protected. Только наличие частных конструкторов также означает, что класс не может быть подклассифицирован извне, поскольку Java требует, чтобы конструкторы подкласса неявно или явно вызывали конструктор суперкласса. (Он может, однако, содержать вложенный класс, который подклассифицирует его.)
Внутренние классы
Вам также необходимо рассмотреть вложенные области таких как внутренние классы. Примером сложности является то, что внутренние классы имеют члены, которые сами могут использовать модификаторы доступа. Таким образом, вы можете иметь частный внутренний класс с открытым членом; может ли доступ к члену? (См. Ниже.) Общее правило состоит в том, чтобы взглянуть на область действия и подумать рекурсивно, чтобы узнать, можете ли вы получить доступ к каждому уровню.
Однако это довольно сложно, и для получения полной информации обратитесь к Java Спецификация языка . (Да, в прошлом были ошибки компилятора.)
Чтобы понять, как они взаимодействуют, рассмотрим этот пример. Возможно «утечка» частных внутренних классов; это обычно предупреждение:
class Test { public static void main(final String ... args) { System.out.println(Example.leakPrivateClass()); // OK Example.leakPrivateClass().secretMethod(); // error } } class Example { private static class NestedClass { public void secretMethod() { System.out.println("Hello"); } } public static NestedClass leakPrivateClass() { return new NestedClass(); } }
Выход компилятора:
Test.java:4: secretMethod() in Example.NestedClass is defined in an inaccessible class or interface Example.leakPrivateClass().secretMethod(); // error ^ 1 error
Некоторые связанные вопросы:
Эта страница хорошо пишет о защищенном & amp; модификатор доступа по умолчанию
.... Защищено: Модификатор защищенного доступа немного сложнее, и вы можете сказать, что это надмножество модификатора доступа по умолчанию. Защищенные члены такие же, как и члены по умолчанию, в отношении доступа в одном пакете. Разница в том, что защищенные члены также доступны для подклассов класса, в которых объявлен член, который находится вне пакета, в котором присутствует родительский класс.
Но эти защищенные члены являются «доступными вне пакета только через наследование ». т. е. вы можете получить доступ к защищенному элементу класса в своем подклассе, присутствующем в каком-либо другом пакете, как если бы этот член присутствовал в самом подклассе. Но этот защищенный член не будет доступен в подклассе вне пакета, используя ссылку родительского класса. ....