Java 访问权限修饰词
概述:Java的访问权限修饰词一共有4个,先来看一下整理后的Java访问权限修饰词有哪些及对应的可见范围,用表格的形式更直观一些。其中protected比较特殊,protected后面会进行详细的讲解。
一、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 指对该成员的访问不做限制。
五、参考