受保护的访问修饰符-protected(在同一包中的使用和不同包中的使用)
protected
Java中protected修饰符的作用说的很模糊如:对同一包内的类和所有子类可见;
个人的理解就是分为两部分:包内可见和子类可见
定义上来说就是:
- 在同一包中时:被protected修饰后可被同一包中任何类访问
- 在不同包中时:可以由继承来访问protected方法而不能直接访问protected方法
下面是代码
在同一包中时
- 创建父类(Father)
package package1;
public class Father { //定义父类,在包1中
protected int a = 1; //protected修饰a
protected void f() { //protected修饰方法f()
System.out.println("father printf:" + a);
}
}
- 同一包中创建子类(Son1)继承父类
package package1;
public class Son1 extends Father { //继承父类
public void s1() {
System.out.println("println s1:" + a); //在方法中调用父类中的a
f(); //调用父类的f()方法
}
}
- 主函数(Test)
package package1;
public class Test {
public static void main(String[] args) {
Father fa = new Father(); //实例化Father类
System.out.println("test" + fa.a); //可调用protected修饰的a
fa.f(); //可调用protected修饰的f()
System.out.println("---------------");
Son1 so = new Son1(); //实例化Son1类
so.s1();
}
}
运行结果:
所以同一包中使用修饰符protected实例化、继承、同一类中可随意调用。
在不同包时
- 使用同样的父类(在包1中)
package package1;
public class Father {
protected int a = 1;
protected void f() {
System.out.println("father printf:" + a); //标记father的print
}
public void a() {
System.out.println(a);
}
}
- 在包2创建子类(Son2),引用包1并继承Father
package package2;
import package1.Father;
public class Son2 extends Father {
public void s2() {
System.out.println("son2 printf:" + a); //可直接调用包1中protected修饰的a;
f(); //可直接调用包1中protected修饰的f()
}
}
- 在包2中创建main函数,引用包1中的Father类
package package2;
import package1.Father;
public class Test2 {
public static void main(String[] args) {
Father father=new Father(); //实例化Father类
/System.out.println(f.a); // protected修饰的a只能由子类调用(错误)
/father.f(); //protected修饰的方法f()只能由子类调用(错误)
System.out.println("----------------");
Son2 son2=new Son2(); //实例化Son2
son2.s2(); //通过同一包中的类方法,调用不同包中使用protected修饰的方法(具体看运行结果)
}
}
运行结果:
结论:使用protected修饰后方法、变量在同一包中都为可见的(main函数中需先实例化);而在不同包中只有在子类中可见,在main函数中就算实例化后也不可见protected修饰过的成员。