MENU

Java杂记(六)理解 Java 访问修饰符 protected

June 22, 2018 • Code

前言:Java 中的「访问修饰符」是对类的访问权限进行控制的机制。当一个类被某一修饰符修饰时,就决定了该类的对外暴露程度

Java 中的访问修饰符共有四个:public、protected、friendly/package 及 private。其中以 protected 较难理解,特此学习记录之。

四种访问修饰符

来自 Java 使用手册:

图中链接:§7.3§6.6.2§7.6

简单来说,Java 中访问修饰符的作用如下:

访问修饰符 说明
public 公开,表明该数据成员对所有成员开放。
protected 表明只有本类、同类的类及子类(可不同包)才能访问该成员变量。
friendly/package 本类及同包的类才能访问。默认值
private 只有本类中数据成员可访问。

关于 protected

上面的修饰符中,public、friendly/package 及 private 都比较容易理解,但 protected 修饰符由于存在同包及子类两种关系,可能理解上容易出现偏差,下面结合栗子作进一步说明。

栗子

在包 access.access1 下有 Person

package access.access1;
    
public class Person {
    
    protected void sayHello() {
        System.out.println("Person.sayHello");
    }
}

sayHello 方法的可见范围为 access1 包及Person的子类

同包类访问 sayHello 方法

package access.access1;
    
public class CallObject {
    
    public static void main(String[] args) {
    
        Person p = new Person();
        p.sayHello();
    }
}

结果:编译通过,运行正常

异包子类访问 sayHello 方法

通过父类引用访问

在包 access.access2 下有 Man

package access.access2;
    
import access.access1.Person;
    
public class Man extends Person {
    
    public static void main(String[] args) {
        Person p = new Person();
        p.sayHello(); 
    }
}

结果:p.sayHello() 编译出错。

通过子类引用访问
package access.access2;
    
import access.access1.Person;
    
public class Man extends Person {
    
    public static void main(String[] args) {
        Man man = new Man();
        man.sayHello();
    }
}

结果:编译运行正常

分析

通过上面几个栗子的对比,可看到 protected 关键字针对同包类子类的可见性是不同的。

作用域 可见性描述
同包(含同包子类) 可通过父类引用直接调用。
异包子类 无法通过父类引用调用,可在子类中通过子类引用调用。

如上面异包子类访问的栗子:在子类 Man 中无法通过父类 Person 的引用直接调用 sayHello方法,只能用自身引用访问通过继承得到的 Person 中的 sayHello 方法。

protected 访问修饰符权限判定取决于引用类型,如在子类 Man 中有 Person p = new Man(),即便 p 指向 Man 子类实例,但依旧无法通过编译,调用 sayHello 方法,因为引用类型仍是父类,无法在子类中调用 protected 权限的方法。

特别注意:判断 protected 的访问权限时,需确定调用的方法来自哪一个类。还是以上面的 ManPerson 类为栗。当在其他类 Other(无继承关系)中通过 Man 类引用调用 sayHello 方法时:

  • sayHello 方法来自 Man 的父类 Person。

  • 故方法的范围为 Person + 同包类 + Man 类,Other 类并不在其中,故调用会出错。

小结

protected 访问修饰符权限可描述为如下:

  • 同包类可调用。

  • 异包子类可通过自身引用本类中调用。

参考

Last Modified: July 5, 2018
Archives QR Code
QR Code for this page
Tipping QR Code
Leave a Comment