Java学习笔记10---访问权限修饰符如何控制成员变量、成员方法及类的访问范围
1.Java有三种访问权限修饰符,分别为public、protected、private,还有一种为缺省权限修饰符的情况,记为default。其中,可以由public和default来修饰类;这四种修饰符都可以修饰成员变量和成员方法。每一种修饰符对应不同的访问范围,下面以下图为例详细说明。
图1
- private只可以覆盖圆1,即只有本类可以访问;
- default可以覆盖到圆3,即本类、同包子类、同包其他类都可以访问,简单说就是与本类同包的所有类都可以访问;
- protected可以覆盖到圆4,即本类、同包子类、同包其他类、其他包中的子类都可以访问,简单说就是与本类同包的类及其他包中的子类都可以访问;
- public可以覆盖到圆5,即本类、同包子类、同包其他类、其他包子类、其他包其他类都可以访问,简单说就是所有类都可以访问;
注:在与父类不同包的子类中,如果通过子类对象访问和调用父类中由protected修饰的变量和方法,确实可以;但如果通过父类的对象访问和调用的话,则不可以访问protected修饰的变量和方法,具体见下文的(6)和(7)。具体原因还未了解。
2.下面以简单的程序验证上述结论。
前提:
- 包human中定义了类Person,Student,DustMan;其中,Student是Person的子类,DustMan不是Person的子类。
- 包teacher中定义了类Teacher,GateMan;其中,Teacher是Person的子类,GateMan不是Person的子类。
- Person中定义了四个成员变量和四个成员方法,分别以public,protected,缺省,private修饰,详见下面代码:
- String name;
- public String education;
- private String hobby;
- protected String residence;
- public void testModifierPublic() {
- System.out.println("Public");
- }
- protected void testModifierProtected() {
- System.out.println("Protected");
- }
- void testModifierDefault() {
- System.out.println("Default");
- }
- private void testModifierPrivate() {
- System.out.println("Private");
- }
(1),在Person类中定义Person类对象pOwn,分别访问和调用这些成员变量和成员方法,详见下面的代码:
- public static void main(String[] args) {
- Person pOwn = new Person("xi",20,"female","bachelor","recite","NJ");
- System.out.println("public education: " + pOwn.education);
- System.out.println("protected residence: " + pOwn.residence);
- System.out.println("default name: " + pOwn.name);
- System.out.println("private hobby: "+ pOwn.hobby);
- pOwn.testModifierPublic();
- pOwn.testModifierProtected();
- pOwn.testModifierDefault();
- pOwn.testModifierPrivate();
- }
输出结果为:
- public education: bachelor
- protected residence: NJ
- default name: xi
- private hobby: recite
- Public
- Protected
- Default
- Private
结果分析:Person类对象可以在本类中访问和调用由public、protected、default、private修饰的成员变量和成员方法。
(2).在Student类中分别定义Student类对象sSamePackChild和Person类对象pSamePackChild,并分别访问和调用这些成员变量和成员方法,详见下面的代码:
- public static void main(String[] args) {
- Student sSamePackChild = new Student("xi",20,"female","bachelor","recite","NJ");
- Person pSamePackChild = new Person("xi",20,"female","bachelor","recite","NJ");
- System.out.println("public education: " + sSamePackChild.education);
- System.out.println("protected residence: " + sSamePackChild.residence);
- System.out.println("default name: " + sSamePackChild.name);
- System.out.println("private hobby: "+ sSamePackChild.hobby);
- sSamePackChild.testModifierPublic();
- sSamePackChild.testModifierProtected();
- sSamePackChild.testModifierDefault();
- sSamePackChild.testModifierPrivate();
- System.out.println("public education: " + pSamePackChild.education);
- System.out.println("protected residence: " + pSamePackChild.residence);
- System.out.println("default name: " + pSamePackChild.name);
- System.out.println("private hobby: "+ pSamePackChild.hobby);
- pSamePackChild.testModifierPublic();
- pSamePackChild.testModifierProtected();
- pSamePackChild.testModifierDefault();
- pSamePackChild.testModifierPrivate();
- }
输出结果为:
- Exception in thread "main" java.lang.Error: Unresolved compilation problems:
- The field Person.hobby is not visible
- The method testModifierPrivate() from the type Person is not visible
- The field Person.hobby is not visible
- The method testModifierPrivate() from the type Person is not visible
- at human.Student.main(Student.java:108)
结果分析:出现编译错误,提示private修饰的hobby和testModifierPrivate()不可见。
(3).根据(2)提示的错误,注释掉相关的行,再次执行,详见代码:
- public static void main(String[] args) {
- Student sSamePackChild = new Student("xi",20,"female","bachelor","recite","NJ");
- Person pSamePackChild = new Person("xi",20,"female","bachelor","recite","NJ");
- System.out.println("public education: " + sSamePackChild.education);
- System.out.println("protected residence: " + sSamePackChild.residence);
- System.out.println("default name: " + sSamePackChild.name);
- // System.out.println("private hobby: "+ sSamePackChild.hobby);
- sSamePackChild.testModifierPublic();
- sSamePackChild.testModifierProtected();
- sSamePackChild.testModifierDefault();
- // sSamePackChild.testModifierPrivate();
- System.out.println("public education: " + pSamePackChild.education);
- System.out.println("protected residence: " + pSamePackChild.residence);
- System.out.println("default name: " + pSamePackChild.name);
- // System.out.println("private hobby: "+ pSamePackChild.hobby);
- pSamePackChild.testModifierPublic();
- pSamePackChild.testModifierProtected();
- pSamePackChild.testModifierDefault();
- // pSamePackChild.testModifierPrivate();
- }
输出结果为:
- public education: bachelor
- protected residence: NJ
- default name: xi
- Public
- Protected
- Default
- public education: bachelor
- protected residence: NJ
- default name: xi
- Public
- Protected
- Default
结果分析:
注释掉private修饰的行后,成功执行;
Person类对象可以在与父类同包的子类Student中访问和调用由public、protected、default修饰的成员变量和成员方法,不能访问由private修饰的变量和方法;
在子类中定义的Student类对象也拥有同样的访问权限。
(4).在DustMan类中定义Person类对象pSamePackNonChild,分别访问和调用这些成员变量和成员方法,详见下面的代码:
- package human;
- public class DustMan {
- public static void main(String[] args) {
- Person pSamePackNonChild = new Person("xi",20,"female","bachelor","recite","NJ");
- System.out.println("public education: " + pSamePackNonChild.education);
- System.out.println("protected residence: " + pSamePackNonChild.residence);
- System.out.println("default name: " + pSamePackNonChild.name);
- System.out.println("private hobby: "+ pSamePackNonChild.hobby);
- pSamePackNonChild.testModifierPublic();
- pSamePackNonChild.testModifierProtected();
- pSamePackNonChild.testModifierDefault();
- pSamePackNonChild.testModifierPrivate();
- }
- }
输出结果为:
- Exception in thread "main" java.lang.Error: Unresolved compilation problems:
- The field Person.hobby is not visible
- The method testModifierPrivate() from the type Person is not visible
- at human.DustMan.main(DustMan.java:19)
结果分析:出现编译错误,提示private修饰的hobby和testModifierPrivate()不可见。
(5).根据(4)提示的错误,注释掉相关的行,再次执行,详见代码:
- package human;
- public class DustMan {
- public static void main(String[] args) {
- Person pSamePackNonChild = new Person("xi",20,"female","bachelor","recite","NJ");
- System.out.println("public education: " + pSamePackNonChild.education);
- System.out.println("protected residence: " + pSamePackNonChild.residence);
- System.out.println("default name: " + pSamePackNonChild.name);
- // System.out.println("private hobby: "+ pSamePackNonChild.hobby);
- pSamePackNonChild.testModifierPublic();
- pSamePackNonChild.testModifierProtected();
- pSamePackNonChild.testModifierDefault();
- // pSamePackNonChild.testModifierPrivate();
- }
- }
输出结果为:
- public education: bachelor
- protected residence: NJ
- default name: xi
- Public
- Protected
- Default
结果分析:
注释掉private修饰的行后,成功执行;
Person类对象可以在与Person同包的非子类中访问和调用由public、protected、default修饰的成员变量和成员方法,不能访问由private修饰的变量和方法。
(6).在Teacher类中定义Teacher类对象tDiffPackChild和Person类对象pDiffPackChild,并分别访问和调用这些成员变量和成员方法,详见下面的代码:
- package teacher;
- import human.Person;
- public class Teacher extends human.Person {
- String duty;
- public Teacher() {
- }
- public Teacher(String d) {
- super();
- this.duty = d;
- }
- public Teacher(String n, int a, String g, String e, String h, String r) {
- super(n,a,g,e,h,r);
- }
- public static void main(String[] args) {
- Teacher tDiffPackChild = new Teacher("xi",20,"female","bachelor","recite","NJ");
- Person pDiffPackChild = new Person("xi",20,"female","bachelor","recite","NJ");
- System.out.println("public education: " + tDiffPackChild.education);
- System.out.println("protected residence: " + tDiffPackChild.residence);
- System.out.println("default name: " + tDiffPackChild.name);
- System.out.println("private hobby: "+ tDiffPackChild.hobby);
- tDiffPackChild.testModifierPublic();
- tDiffPackChild.testModifierProtected();
- tDiffPackChild.testModifierDefault();
- tDiffPackChild.testModifierPrivate();
- System.out.println("public education: " + pDiffPackChild.education);
- System.out.println("protected residence: " + pDiffPackChild.residence);
- System.out.println("default name: " + pDiffPackChild.name);
- System.out.println("private hobby: "+ pDiffPackChild.hobby);
- pDiffPackChild.testModifierPublic();
- pDiffPackChild.testModifierProtected();
- pDiffPackChild.testModifierDefault();
- pDiffPackChild.testModifierPrivate();
- }
- }
输出结果为:
- Exception in thread "main" java.lang.Error: Unresolved compilation problems:
- The field Person.name is not visible
- The field Person.hobby is not visible
- The method testModifierDefault() from the type Person is not visible
- The method testModifierPrivate() from the type Person is not visible
- The field Person.residence is not visible
- The field Person.name is not visible
- The field Person.hobby is not visible
- The method testModifierProtected() from the type Person is not visible
- The method testModifierDefault() from the type Person is not visible
- The method testModifierPrivate() from the type Person is not visible
- at teacher.Teacher.main(Teacher.java:39)
结果分析:
出现编译错误,对于定义的Teacher类对象tDiffPackChild而言,对其的变量访问和方法调用提示,default修饰的name和testModifierDefault()、private修饰的hobby和testModifierPrivate()不可见;
对于定义的Person类对象pDiffPackChild而言,对其的变量访问和方法调用提示,protected修饰的residence和testModifierProtected()、default修饰的name和testModifierDefault()、private修饰的hobby和testModifierPrivate()不可见。
(7).根据(6)提示的错误,注释掉相关的行,再次执行,详见代码:
- package teacher;
- import human.Person;
- public class Teacher extends human.Person {
- String duty;
- public Teacher() {
- }
- public Teacher(String d) {
- super();
- this.duty = d;
- }
- public Teacher(String n, int a, String g, String e, String h, String r) {
- super(n,a,g,e,h,r);
- }
- public static void main(String[] args) {
- Teacher tDiffPackChild = new Teacher("xi",20,"female","bachelor","recite","NJ");
- Person pDiffPackChild = new Person("xi",20,"female","bachelor","recite","NJ");
- System.out.println("public education: " + tDiffPackChild.education);
- System.out.println("protected residence: " + tDiffPackChild.residence);
- // System.out.println("default name: " + tDiffPackChild.name);
- // System.out.println("private hobby: "+ tDiffPackChild.hobby);
- tDiffPackChild.testModifierPublic();
- tDiffPackChild.testModifierProtected();
- // tDiffPackChild.testModifierDefault();
- // tDiffPackChild.testModifierPrivate();
- System.out.println("public education: " + pDiffPackChild.education);
- // System.out.println("protected residence: " + pDiffPackChild.residence);
- // System.out.println("default name: " + pDiffPackChild.name);
- // System.out.println("private hobby: "+ pDiffPackChild.hobby);
- pDiffPackChild.testModifierPublic();
- // pDiffPackChild.testModifierProtected();
- // pDiffPackChild.testModifierDefault();
- // pDiffPackChild.testModifierPrivate();
- }
- }
输出结果为:
- public education: bachelor
- protected residence: NJ
- Public
- Protected
- public education: bachelor
- Public
结果分析:
注释掉相关的行后,成功执行;
如果在与Person不同包的子类Teacher中定义了Teacher类对象,则通过该对象可以访问和调用Person中public和protected修饰的成员变量和成员方法,default、private修饰的成员变量和成员方法都不可以访问或调用;
如果定义了Person类对象,则通过该对象只可以访问和调用Person中public修饰的成员变量和成员方法,protected、default、private修饰的成员变量和成员方法都不可以访问或调用。
疑问:不明白为什么会有这样的差异。
(8).在GateMan类中定义定义Person类对象pDiffPackNonChild,分别访问和调用这些成员变量和成员方法,详见下面的代码:
- package teacher;
- import human.Person;
- public final class GateMan {
- int gateNumber;
- public GateMan() {
- }
- public GateMan(int g) {
- this.gateNumber = g;
- }
- public static void main(String[] args) {
- Person pDiffPackNonChild = new Person("xi",20,"female","bachelor","recite","NJ");
- System.out.println("public education: " + pDiffPackNonChild.education);
- System.out.println("protected residence: " + pDiffPackNonChild.residence);
- System.out.println("default name: " + pDiffPackNonChild.name);
- System.out.println("private hobby: "+ pDiffPackNonChild.hobby);
- pDiffPackNonChild.testModifierPublic();
- pDiffPackNonChild.testModifierProtected();
- pDiffPackNonChild.testModifierDefault();
- pDiffPackNonChild.testModifierPrivate();
- }
- }
输出结果为:
- Exception in thread "main" java.lang.Error: Unresolved compilation problems:
- The field Person.residence is not visible
- The field Person.name is not visible
- The field Person.hobby is not visible
- The method testModifierProtected() from the type Person is not visible
- The method testModifierDefault() from the type Person is not visible
- The method testModifierPrivate() from the type Person is not visible
- at teacher.GateMan.main(GateMan.java:29)
结果分析:出现编译错误,提示protected修饰的residence和testModifierProtected()、default修饰的name和testModifierDefault()、private修饰的hobby和testModifierPrivate()不可见。
(9).根据(8)提示的错误,注释掉相关的行,再次执行,详见代码:
- package teacher;
- import human.Person;
- public final class GateMan {
- int gateNumber;
- public GateMan() {
- }
- public GateMan(int g) {
- this.gateNumber = g;
- }
- public static void main(String[] args) {
- Person pDiffPackNonChild = new Person("xi",20,"female","bachelor","recite","NJ");
- System.out.println("public education: " + pDiffPackNonChild.education);
- // System.out.println("protected residence: " + pDiffPackNonChild.residence);
- // System.out.println("default name: " + pDiffPackNonChild.name);
- // System.out.println("private hobby: "+ pDiffPackNonChild.hobby);
- pDiffPackNonChild.testModifierPublic();
- // pDiffPackNonChild.testModifierProtected();
- // pDiffPackNonChild.testModifierDefault();
- // pDiffPackNonChild.testModifierPrivate();
- }
- }
输出结果为:
- public education: bachelor
- Public
结果分析:
注释掉protected、default、private修饰的行后,成功执行;
Person类对象可以在与Person不同包的非子类中访问和调用由public修饰的成员变量和成员方法,不能访问由protected、default、private修饰的变量和方法。
(10).把Person类定义为缺省访问权限修饰的类,即class Person{,,,,}。在teacher包里的Teacher类和GateMan类都出现编译错误,如下所示:
- Exception in thread "main" java.lang.IllegalAccessError: class teacher.Teacher cannot access its superclass human.Person
- at java.lang.ClassLoader.defineClass1(Native Method)
- at java.lang.ClassLoader.defineClass(ClassLoader.java:763)
- at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:142)
- at java.net.URLClassLoader.defineClass(URLClassLoader.java:467)
- at java.net.URLClassLoader.access$100(URLClassLoader.java:73)
- at java.net.URLClassLoader$1.run(URLClassLoader.java:368)
- at java.net.URLClassLoader$1.run(URLClassLoader.java:362)
- at java.security.AccessController.doPrivileged(Native Method)
- at java.net.URLClassLoader.findClass(URLClassLoader.java:361)
- at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
- at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:335)
- at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
- at sun.launcher.LauncherHelper.checkAndLoadMain(LauncherHelper.java:495)
结果分析:说明缺省访问权限修饰符的类只能由本包中的类访问,其他包中的类都不可以访问。
Java学习笔记10---访问权限修饰符如何控制成员变量、成员方法及类的访问范围的更多相关文章
- 包和访问权限修饰符,.单例设计模式,.Object类常用方法,.内部类
1.包和访问权限修饰符 1.1 包 为什么要导包? 将字节码文件(.class)文件进行分类存放 --->包 其实就是文件夹 import java.util.Arrays; 包的划分规则 方案 ...
- 【java学习笔记2】访问控制修饰符 public、protected、默认、private
先写了一个User()类: package chapter01; public class User { // 私有的 private int id; // 受保护的 protected int ag ...
- Java中的四种权限修饰符及六种非访问修饰符(简识)
一.是哪四种访问权限修饰符呢? public > protected > [default] > private (公共的 ) (受保护的) (默认的) (私有的) 二.简单认识四种 ...
- java访问权限修饰符
作用域 当前类 同一package 子孙类 其他package public √ √ √ √ protected √ √ √ × friendly √ √ × × private √ × × × ja ...
- Java访问权限修饰符public protected friendly private用法总结(转载好文Mark)
首先声明:Java中,friendly这个修饰符并没有显式的声明,在成员变量和方法前什么修饰符也不用,默认的就是friendly.为了条理清晰,分三种不同情况来总结. 一 访问权限修饰符修饰成员变量和 ...
- Java 访问权限修饰符以及protected修饰符的理解
2017-11-04 22:28:39 访问权限修饰符的权限 访问修饰符protected的权限理解 在Core Java中有这样一段话“在Object类中,clone方法被声明为protected, ...
- java四种访问权限修饰符
java中四个访问权限修饰符: public(公开的).protected(受保护的).default(默认的).private(私有的). 它们决定了紧跟其后被定义的东西的使用范围. 适用范围< ...
- Java语言中的访问权限修饰符
一个Java应用有很多类,但是有些类,并不希望被其他类使用.每个类中都有数据成员和方法成员,但是并不是每个数据和方法,都允许在其他类中调用.如何能做到访问控制呢?就需要使用访问权限修饰符. Java语 ...
- Java的访问权限修饰符
default或者friendly表示默认的访问权限修饰符.
随机推荐
- 错误代码: 1054 Unknown column 't.createUsrId' in 'group statement'
1.错误描写叙述 1 queries executed, 0 success, 1 errors, 0 warnings 查询:select count(t.id),t.`createUserId` ...
- OSChinaclient源代码学习(1)--Android与Server的交互
这里主要针对"综合"这个选项卡下的"资讯"模块为样例.对核心代码进行解读. 准备工作:參考我的另外一篇博客 http://blog.csdn.net/csp27 ...
- hibernate5(9)注解映射[1]多对一单向关联
在博客站点中,我们可能须要从某一篇文章找到其所关联的作者.这就须要从文章方建立起对用户的关联,即是多对一的映射关系. 如今先看一个配置实例:我们的文章实体类 package com.zeng.mode ...
- 【cogs 597】【dp】交错匹配
597. 交错匹配 ★☆ 输入文件:crossa.in 输出文件:crossa.out 简单对照 时间限制:1 s 内存限制:128 MB [问题描写叙述] 有两行自然数. UP[1..N] . DO ...
- ASP.NET Core 使用 Redis 客户端
Mac OS 安装 Redis(用于连 Redis 服务器,方便查看数据):https://redis.io/topics/quickstart wget http://download.redis. ...
- make工程管理器
1.概述 大型程序中,人们希望工具自动识别修改的文件,而且不需要输入冗长的命令,就可以进行编译链接等操作,于是make工程管理器应运而生. make可以自动识别文件时间戳,只处理修改的文件: make ...
- 转:Natas Wargame Level28 Writeup(EBC加密破解)
From:http://alkalinesecurity.com/blog/ctf-writeups/natas-28-getting-it-wrong/ Now that I knew it was ...
- 2.python数据类型
1 Number(数字) 2 字符串类型(string) 字符串内置方法 # string.capitalize() 把字符串的第一个字符大写 # string.center(width) 返 ...
- Eclipse多行同时进行编辑,可编辑或修改相同内容
使用Shift+Alt+A可以进入Eclipse多行编辑的功能,选中的一部分区域从光标开始处同时进行修改或者插入功能. 再次按下Shift+Alt+A可已退出该编辑模式.
- Java I/O---添加属性和有用的接口—FilterlnputStream&FilterOutputStream
0.装饰器模式 Java I/O类库需要多种不同功能的组合,这正是使用装饰器模式的理由所在.这也是Java I/O类库里存在filter(过滤器)类的原因所在,抽象类filter是所有装饰器类的基类. ...