Казалось бы, простые вещи могут привести к множеству вопросов.В процессе обучения мы только «вроде бы поняли», «вроде бы так» и «должно быть хорошо» для многих понятий.На самом деле не хватает внимательного обдумывания и меньше вопросов о себе. Почему».
В Java модификатор доступа является самым базовым знанием, а модификатор protected — лишь одним из них.Если вы хотите спросить, почему бы не взять public, default и private для более глубокого изучения? Тогда, прочитав эту статью, вы поймете, почему стоит задуматься о защищенном.
В «Размышлениях на Java» название protected — это «унаследованные права доступа», которые мы помним как protected: protected должен иметь отношения наследования, чтобы иметь возможность доступа. Итак, вы думаете, что понимаете, но действительно ли вы понимаете это предложение?
Сначала рассмотрим несколько вопросов:
-
В том же пакете могут ли объекты подкласса обращаться к защищенным методам суперкласса?
-
Можно ли в разных пакетах создать объект подкласса в подклассе для доступа к защищенному методу суперкласса?
-
Можно ли в разных пакетах создать объект родительского класса в подклассе для доступа к защищенному методу родительского класса?
-
Могут ли объекты, созданные в подклассе другого подкласса, в разных пакетах обращаться к защищенным методам общедоступного суперкласса?
-
А как насчет защищенного метода родительского класса с модификатором static?
В "Thinking in Java" есть предложение: "protected также предоставляет права доступа к пакету, то есть другие классы в том же пакете могут получить доступ к protected элементам", на самом деле модификатор protected содержит разрешения модификатора по умолчанию, поэтому первый 1 вопрос, на который вы уже знаете ответ, в том же пакете обычный класс или подкласс может получить доступ к защищенному методу базового класса.
Родительский класс является нестатическим защищенным декорированным классом.
package com.protectedaccess.parentpackage;
public class Parent {
protected String protect = "protect field";
protected void getMessage(){
System.out.println("i am parent");
}
}
В разных пакетах к защищенному методу нельзя получить доступ через ссылку на родительский класс в подклассе.
Независимо от того, создаете ли вы объект Parent или создаете объект Son1 с помощью полиморфизма, пока ссылка Parent недоступна, компилятор выдаст сообщение об ошибке.
package com.protectedaccess.parentpackage.sonpackage1;
import com.protectedaccess.parentpackage.Parent;
public class Son1 extends Parent{
public static void main(String[] args) {
Parent parent1 = new Parent();
// parent1.getMessage(); 错误
Parent parent2 = new Son1();
// parent2.getMessage(); 错误
}
}
В разных пакетах к защищенному методу можно получить доступ в подклассе через ссылку подкласса.
Подкласс фактически наследует метод родительского класса, доступ к которому можно получить через объект подкласса, или непосредственно в методе подкласса, а также может вызвать метод в родительском классе через ключевое слово super.
package com.protectedaccess.parentpackage.sonpackage1;
import com.protectedaccess.parentpackage.Parent;
public class Son1 extends Parent{
public static void main(String[] args) {
Son1 son1 = new Son1();
son1.getMessage(); // 输出:i am parent,
}
private void message(){
getMessage(); // 如果子类重写了该方法, 则输出重写方法中的内容
super.getMessage(); // 输出父类该方法中的内容
}
}
В разных пакетах защищенный метод общего базового класса не может быть доступен в подклассе через ссылку на другой подкласс.
package com.protectedaccess.parentpackage.sonpackage2;
import com.protectedaccess.parentpackage.Parent;
public class Son2 extends Parent {
}
Обратите внимание, что Son2 — это еще один подкласс, и объект, созданный в Son1, не может получить доступ к защищенному методу родительского класса.
package com.protectedaccess.parentpackage.sonpackage1;
import com.protectedaccess.parentpackage.Parent;
import com.protectedaccess.parentpackage.sonpackage2.Son2;
public class Son1 extends Parent{
public static void main(String[] args) {
Son2 son2 = new Son2();
// son2.getMessage(); 错误
}
}
Родительский класс является статическим защищенным оформленным классом.
Доступ к защищенным статическим переменным можно получить непосредственно в подклассах, но не в не-подклассах других пакетов.
package com.protectedaccess.parentpackage;
public class Parent {
protected String protect = "protect field";
protected static void getMessage(){
System.out.println("i am parent");
}
}
Доступ к статическим методам осуществляется непосредственно по имени класса.
Прямой доступ в подклассах независимо от того же пакета
package com.protectedaccess.parentpackage.sonpackage1;
import com.protectedaccess.parentpackage.Parent;
public class Son3 extends Parent{
public static void main(String[] args) {
Parent.getMessage(); // 输出: i am parent
}
}
Недоступно для не-подклассов в разных пакетах
package com.protectedaccess.parentpackage.sonpackage1;
import com.protectedaccess.parentpackage.Parent;
public class Son4{
public static void main(String[] args) {
// Parent.getMessage(); 错误
}
}
Увидев это, вы должны знать, сколько существует ситуаций.Неожиданные результаты могут возникнуть в разных ситуациях, так что это все же больше практики.Просто читая функцию защищенного модификатора в книге, вы не можете найти ее тонкость.