0%

protected 访问控制符的理解

protected 访问控制符的理解

首先要记住:protected 的属性和方法可以在本包和子类访问

在这里重点强调子类访问:

  • 只要有继承关系,并且在子类中,就可以用super去访问父类中定义的protected修饰的方法或属性,不管子类和父类是不是在同一个包中,并且如果子类中没有重写父类中的方法和属性的话,用this关键字访问的和用super关键字访问是一样的。
  • 只要是在子类中,也可以通过new出一个子类本身的实例,通过引用变量.属性或方法的形式进行访问。
  • 但是,如果在其他类(包括子类)中,就不允许通过实例化父类或者子类(其他子类,非这个子类本身)对象之后,利用引用变量.属性或方法的形式进行访问。

具体例子
父类:

1
2
3
4
5
6
package test1;
public class ProtectedTest {
protected void say(){
System.out.println("ProtectedTest");
}
}

子类A例子:
在子类中直接调用父类protected属性和方法。

1
2
3
4
5
6
7
8
9
10
package test2;
import test1.ProtectedTest;
public class A extends ProtectedTest {
public void speak(){
say();//ok,等价于this.say(),子对象this可以调用父类方法(属性也一样)
}
public static void main(String[] args) {
A a = new A();
a.say();//ok,子对象a可以调用父类方法
}

子类B的例子:
在其他(子)类(B)中创建非自身子类(A)的实例,调用父类protected方法报错。但是,通过a.speak()可以间接调用父类protected方法。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
package test2;
import test1.ProtectedTest;
public class B extends ProtectedTest{
public void speak(){
say();////ok,等价于this.say(),可以调用父类方法
A a = new A();
a.say();
//此处报错,不允许a调用:The method say() from the type ProtectedTest is not visible
//当父类放到其他包下面的时候,这里报错,因为say方法是protected可见性,跨包不可见,因此不可访问
a.speak(); //同样可以调用say(),但是这里是没有问题的,因为是调用的speak()方法,它不是protected方法,但是此方法在定义时调用了say()
}
public static void main(String[] args) {
B b = new B();
b.say();//ok,子对象b可以调用父类方法
}
}

从上面这个例子可以知道,如果想在其他类中调用父类的protected方法,有两种情况:
1、这个类是拥有protected方法父类的子类
2、先在子类中定义了一个非protected的方法,但是在这个方法中调用了该父类的protected方法,在其他类中通过实例化此子类对象,调用这个方法也能间接达到调用父类protected方法的效果。如果这个子类和这个方法是public的,那么当然跨包的其他类也能调用