защищен
Давайте поговорим о вопросах защищенных прав доступа. См. Пример 1 ниже:
Тест. Ява
класс myobject {} public class test {public static void main (string [] args) {myObject obj = new myObject (); obj.clone (); // Скомпилируйте ошибку. }} Клон метода из объекта типа не виден.
Мы уже поняли, что Object.Clone () является защищенным методом. Это показывает, что метод можно получить с помощью подклассов того же пакета (java.lang) и IT (java.lang.object). Вот класс MyObject (наследование по умолчанию java.lang.object).
Точно так же тест также является подклассом java.lang.object. Однако защищенный метод другого подкласса не может быть доступен в одном подклассе, хотя два подкласса наследуют от одного и того же родительского класса.
Давайте снова посмотрим на пример 2:
Тест2.java
класс myObject2 {защищенный объект клон () бросает clonenotsupportedException {return super.clone (); }} public class test2 {public static void main (string [] args) бросает clonenotsupportedException {myobject2 obj = new myobject2 (); obj.clone (); // Скомпилируйте ОК. }} Здесь мы переопределяем метод клона () родительского класса в классе MyObject2, вызовут метод клона () в другом классе Test2, а также компилируется и проходит.
Причина компиляции очевидна. Когда вы переопределяете метод Clone () в классе MyObject2, класс MyObject2 и класс Test2 находятся в одном и том же пакете, поэтому этот защищенный метод виден в классе Test2.
На этом этапе мы вспоминаем заявления в главе 2.2 в стаях неглубоких и глубоких копий в Java, ② перезаписывают метод клона () базового класса в полученном классе и объявляем его публичным. Теперь я понимаю причину этого предложения (чтобы позволить другим классам вызвать метод клона () этого класса после перегрузки, атрибут метода клона () должен быть установлен для публичного).
Давайте посмотрим на пример 3:
Test3.java
Пакет 1class myobject3 {защищенный объект Clone () бросает ClonenotSupportedException {return super.clone (); }} пакет 2Public Class Test3 Extens MyObject3 {public static void main (String args []) {myObject3 obj = new myObject3 (); obj.clone (); // Скомпилируйте ошибку. Test3 tobj = new Test3 (); tobj.clone (); // chogle ok. }} Здесь я использую класс Test3, чтобы наследовать MyObject3. Обратите внимание, что эти два класса имеют разные пакеты, в противном случае это случай примера 2. В классе Test3 вызовите метод клона () экземпляра Tobj класса Test3 и компиляции и прохождения. А также вызов метода клона () экземпляра obj класса MyObject3, и ошибка компиляции!
Неожиданные результаты, разве не подходит к защищенному методу с помощью наследственных классов?
Должно быть ясно, что Class Test3 наследует класс MyObject3 (включая его метод клона), поэтому вы можете вызвать свой собственный метод клона в Test3 Class3. Тем не менее, защищенный метод класса MyObject3 невидим для его различного подкласса BUN.
Вот еще один отрывок из "Java в суть":
Защищенный доступ требует немного больше лаборатории. Предположим, что класс A объявляет защищенное поле X и расширяется классом B, который определяется в другом пакете (эта последняя точка важна). Класс B наследует защищенное поле X, и его код может получить доступ к этому полю в текущем экземпляре B или в любых других случаях B, на которые может ссылаться код. Это не означает, однако, что код класса B может начать читать защищенные поля произвольных экземпляров A! Если объект является экземпляром A, но не является экземпляром B, его поля, очевидно, не унаследованы B, а код класса B не может их прочитать.
Кстати, многие книги Java в Китае обычно описываются таким образом при введении разрешений на доступ (различные формы и последовательное содержание):
Контроль доступа к методу:
статический
1. Ключевое слово статичное (запомните их сначала, затем прочитайте его)
1) Статические методы и статические переменные - это объекты, которые принадлежат определенному классу, но не к классу.
2) Ссылки на статические методы и статические переменные непосредственно ссылаются через имена классов.
3) Нестатические методы и нестатические переменные-члены не могут быть вызваны статическими методами. В противном случае все в порядке.
4) Статические переменные аналогичны глобальным переменным в других языках в некоторых программах и могут быть доступны вне класса, если они не являются частными.
2. Когда использовать статический
Когда мы создаем экземпляр класса (объект), мы обычно используем новый метод, чтобы было создано пространство данных этого класса, и его методы могут быть вызваны.
Однако иногда мы надеемся, что, хотя класс может быть создан с помощью n объектов (очевидно, пространство данных этих N -объектов отличается), некоторые данные этих n объектов одинаковы, то есть независимо от того, сколько экземпляров имеет класс, данные имеют копию памяти этих экземпляров (см. Пример 1). Это так со статическими переменными.
Другой сценарий заключается в том, что вы хотите, чтобы метод не был связан с каким -либо объектом класса, который его содержит. То есть этот метод можно вызвать, даже если объект не создан. Важным использованием статического метода является вызвать его без создания какого -либо объекта (см. Пример 2). Это так со статическим методом.
Существует также особое использование во внутренних классах. Обычно нормальный класс не разрешается объявлять статичным, только внутренний класс может сделать это. В настоящее время этот внутренний класс, объявленный как статический, может использоваться непосредственно в качестве обычного класса без необходимости экземпляра внешнего класса (см. Пример 3). Это так со статическими классами.
Пример 1
открытый класс tstatic {static int i; public tstatic () {i = 4; } public tstatic (int j) {i = j; } public static void main (string args []) {System.out.println (tstatic.i); TSTATIC T = новый TSTATIC (5); // Объявит ссылку на объект и создайте его. В это время i = 5 System.out.println (ti); Tstatic tt = new tstatic (); // Объявит ссылку на объект и создайте его. В это время i = 4 System.out.println (ti); System.out.println (tt.i); System.out.println (ti); }}
результат:
05444
Статическая переменная создается при загрузке класса. Пока класс существует, статическая переменная существует. Они должны быть инициализированы при определении. В приведенном выше примере я не инициализирован, поэтому будет получено начальное значение по умолчанию 0. Статическая переменная может быть инициализирована только один раз, а статическая переменная принимает только последнюю инициализацию.
На самом деле, это все еще является проблемой с несколькими экземплярами, разделяющими статическую переменную.
Пример 2
Не объявляется статичным
класс Classa {int b; public void ex1 () {} class classb {void ex2 () {int i; Classa a = new Classa (); i = ab; // Здесь доступ к переменной элемента b a.ex1 () через ссылку на объект; // Здесь доступ к функции члена EX1 через ссылку на объект}}}
Объявляется статичным
класс Classa {static int b; static void ex1 () {}} class classb {void ex2 () {int i; i = classa.b; // здесь доступ к переменной члена b classa.ex1 () через имя класса; // здесь доступ к функции члена EX1 через имя класса}} При использовании статических методов будьте осторожны с тем, что нестатические методы не могут быть вызваны статическими методами и контрольными нестатическими переменными членами (это или супер не могут быть упомянуты каким-либо образом в статических методах). Причина очень проста. Для статических вещей, когда JVM загружает класс, он открывает эти статические пространства в памяти (так что на него можно непосредственно упоминаться через имя класса), и в настоящее время класс, на котором расположены нестатические методы и переменные элемента, не были созданы.
Таким образом, если вы хотите использовать нестатические методы и переменные-члены, вы можете напрямую создавать класс, в котором метод или переменная-член расположена в статическом методе. Вот как это делает Public Static Void Main.
Пример 3
открытый класс staticcls {public static void main (string [] args) {outtercls.innercls oi = new outtercls.innercls (); // нет необходимости в новых Overcls до этого}} класса outtercls {public Static innerCls {innercls () {System.out.out.println ("innerCls"); }}}
результат:
Innercls
3. Статическая инициализация
Переменные, определенные Static, будут иметь приоритет над любыми другими нестатическими переменными, независимо от того, в котором они появляются. Статический кодовый блок (затем кусок кода) используется для выполнения явной инициализации статической переменной. Этот код будет инициализирован только один раз, а когда класс будет загружен в первый раз. См. Пример ниже.
Значение класса {static int c = 0; Value () {c = 15; } Value (int i) {c = i; } static void inc () {c ++; }} class count {public static void prt (string s) {system.out.println (s); } Значение v = новое значение (10); Статическое значение v1, V2; static {prt ("в статическом блоке Cals count v1.c =" + v1.c + "v2.c =" + v2.c); v1 = новое значение (27); prt ("в статическом блоке Cals count v1.c =" + v1.c + "v2.c =" + v2.c); v2 = новое значение (); prt ("в статическом блоке Cals count v1.c =" + v1.c + "v2.c =" + v2.c); }} открытый класс tstaticblock {public static void main (string [] args) {count ct = new count (); Count.prt ("в главном:"); Count.prt ("ct.c =" + ct.vc); Count.prt ("v1.c =" + count.v1.c + "v2.c =" + count.v2.c); Count.v1.inc (); Count.prt ("v1.c =" + count.v1.c + "v2.c =" + count.v2.c); Count.prt ("ct.c =" + ct.vc); }}
результат:
В статическом блоке CALSS COUNT V1.C = 0 V2.C = 0IN Статический блок CALSS COUNT V1.C = 27 V2.C = 27 в статическом блоке CALSS COUNT V1.C = 15 V2.C = 15 в основном: CT.C = 10V1.C = 10 V2.C = 10V1.C = 11 V2.C = 11CT.C = 11.
Будь то V, V1 или V2, переменные элемента, на которых они работают, являются одинаковой статической переменной c.
В количестве классов V1 и V2 (статическое значение v1, v2;), затем инициализируйте статический кодовый блок (static {}) и, наконец, инициализируйте v.