Java 访问权限修饰词

概述:Java的访问权限修饰词一共有4个,先来看一下整理后的Java访问权限修饰词有哪些及对应的可见范围,用表格的形式更直观一些。其中protected比较特殊,protected后面会进行详细的讲解。

java intenal修饰 java的修饰词_访问权限


java intenal修饰 java的修饰词_父类_02

一、private

private:私有构造。

含义:被private修饰的类成员仅本类中可见,同时不能被子类继承;

理解:private 体现了Java面向对象思想的三大特性之一——封装。对于类中关键成员的保护,可以有效提高代码的安全性。


二、无

无:包访问权限。

含义:当不加修饰词时,类成员对本包中的所有类可见,只可以被本包中的子类继承;

理解:顾名思义,当成员不添加修饰词时,仅限本package内的所有类均可以对该成员进行访问。


三、protected

protected:继承访问权限。

含义:被protected修饰的类成员对本包及其子类可见,允许被本包或其他包的子类继承;

理解:protected有些特殊,他的访问权限在特定情况下允许跨包,个人理解总结为以下两点:

1、被protected修饰的类成员对本包内所有类可见;
  2、若父类和子类不在同一包中,那么在子类中,父类中被protected修饰的类成员对子类、子类实例可见,对父类实例不可见。

第1点很好理解,意思就是protected的权限 ≥ 包访问权限;

第2点有点绕口,你觉得你理解了,但是我不要你觉得,我要我觉得。结合 protected 的名字——继承访问权限,可以先思考以下4个问题:

① 当父类和子类在同一个包中时,子类对象能否访问父类的protected成员?

② 当父类和子类不在同一个包中时,子类中创建的子类对象能否访问父类的protected成员?

③ 当父类和子类不在同一个包中时,子类中创建的父类对象能否访问父类的protected成员?

④ 当父类和子类不在同一个包中时,子类A中,创建的子类B对象能否访问父类的protected成员?

接下来当然是实践出真知啦~

问题①:当父类和子类在同一个包中时,子类对象能否访问父类的protected成员?

package p1;
//父类
public class Person {
    protected int age;

    protected void testMethod(){
        System.out.println("继承访问权限");
    }
}
//子类
public class Student extends Person {
    public static void main(String[] args) {
        Student stu = new Student();
        stu.age = 18;
        stu.testMethod();
    }
}
//编译成功
//控制台输出:继承访问权限

没啥毛病,因为protected的权限 ≥ 包访问权限,同包中,是不是子类都可以访问;

问题②:当父类和子类不在同一个包中时,子类中创建的子类对象能否访问父类的protected成员?

//包p1的父类Person
package p1;

public class Person {
    protected int age;
    protected void testMethod(){
        System.out.println("继承访问权限");
    }
}
//包p2的类Student跨包继承了包p1的类Pserson
package p2;
import p1.Person;

public class Student extends Person {
    public static void main(String[] args) {
        Student stu = new Student();
        stu.age = 18;
        stu.testMethod();
    }
}
//编译成功
//控制台输出:继承访问权限

跟咱想得一样,说明protected权限是名副其实的“继承访问权限”,子类跨包继承时,子类中创建的对象也可以访问父类的protected成员。别着急,很多人看到这里就觉得自己理解了,我们继续往下看。

问题③:当父类和子类不在同一个包中时,子类中创建的父类对象能否访问父类的protected成员?

//包p1的父类Person
package p1;

public class Person {
    protected int age;

    protected void testMethod(){
        System.out.println("继承访问权限");
    }
}
//包p2的类Student跨包继承了包p1的类Pserson
package p2;
import p1.Person;

public class Student extends Person {
    public static void main(String[] args) {
        Person per = new Person();
        per.age = 18;//报错提示:age是p1.Person中是protected访问控制
        per.testMethod();//报错提示:testMethod()是p1.Person中是protected访问控制

        Person per2 = new Student();//报错提示:testMethod()是p1.Person中是protected访问控制
        stu.age = 18;//报错提示:age是p1.Person中是protected访问控制
        per.testMethod();
    }
}
//编译失败

也就是说,跨包的情况下,子类中创建的父类对象是无法访问父类的protected对象的。行吧,毕竟 protected 说的是子类有访问权限,也能理解,再往下看。

问题④:当父类和子类不在同一个包中时,子类A中,创建的子类B对象能否访问父类的protected成员?

//包p1的父类Person
package p1;

public class Person {
    protected int age;

    protected void testMethod(){
        System.out.println("继承访问权限");
    }
}
//包2
package p2;
import p1.Person;
//类Teacher跨包继承了类Person
class Teacher extends Person{
}
//类Student跨包继承了类Person
public class Student extends Person {
    public static void main(String[] args) {
        Teacher tea = new Teacher();
        tea.age = 18;//报错提示:age是p1.Person中是protected访问控制
        tea.testMethod();//报错提示:testMethod()是p1.Person中是protected访问控制
    }
}
//编译失败

开始怀疑自己了吗?不是叫“继承访问权限”吗?为什么子类Teacher的实例不能访问父类的protected成员了?

所以,在这里,我们得出结论,protected 在跨包情况下对子类对象可见是有前提条件的,即子类对象只有在该子类中创建时才能访问父类的 protected 成员。

我们最后总结一下 protected 的范围:

1、protected(继承访问权限)≥ 包访问权限;

2、跨包时,子类可以访问父类 protected 成员;

3、跨包时,子类对象只有在该子类中创建时才能访问父类的 protected 成员(参见问题2中的代码)。


四、public

public:接口访问权限。

含义:被public修饰的类成员对所有的类可见,允许跨包被子类继承;

理解:很好理解,public 指对该成员的访问不做限制。

五、参考