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---访问权限修饰符如何控制成员变量、成员方法及类的访问范围的更多相关文章

  1. 包和访问权限修饰符,.单例设计模式,.Object类常用方法,.内部类

    1.包和访问权限修饰符 1.1 包 为什么要导包? 将字节码文件(.class)文件进行分类存放 --->包 其实就是文件夹 import java.util.Arrays; 包的划分规则 方案 ...

  2. 【java学习笔记2】访问控制修饰符 public、protected、默认、private

    先写了一个User()类: package chapter01; public class User { // 私有的 private int id; // 受保护的 protected int ag ...

  3. Java中的四种权限修饰符及六种非访问修饰符(简识)

    一.是哪四种访问权限修饰符呢? public > protected > [default] > private (公共的 ) (受保护的) (默认的) (私有的) 二.简单认识四种 ...

  4. java访问权限修饰符

    作用域 当前类 同一package 子孙类 其他package public √ √ √ √ protected √ √ √ × friendly √ √ × × private √ × × × ja ...

  5. Java访问权限修饰符public protected friendly private用法总结(转载好文Mark)

    首先声明:Java中,friendly这个修饰符并没有显式的声明,在成员变量和方法前什么修饰符也不用,默认的就是friendly.为了条理清晰,分三种不同情况来总结. 一 访问权限修饰符修饰成员变量和 ...

  6. Java 访问权限修饰符以及protected修饰符的理解

    2017-11-04 22:28:39 访问权限修饰符的权限 访问修饰符protected的权限理解 在Core Java中有这样一段话“在Object类中,clone方法被声明为protected, ...

  7. java四种访问权限修饰符

    java中四个访问权限修饰符: public(公开的).protected(受保护的).default(默认的).private(私有的). 它们决定了紧跟其后被定义的东西的使用范围. 适用范围< ...

  8. Java语言中的访问权限修饰符

    一个Java应用有很多类,但是有些类,并不希望被其他类使用.每个类中都有数据成员和方法成员,但是并不是每个数据和方法,都允许在其他类中调用.如何能做到访问控制呢?就需要使用访问权限修饰符. Java语 ...

  9. Java的访问权限修饰符

    default或者friendly表示默认的访问权限修饰符.

随机推荐

  1. MERGE语法详解

    merge语法是根据源表对目标表进行匹配查询,匹配成功时更新,不成功时插入. 其基本语法规则是 merge into 目标表 a using 源表 b on(a.条件字段1=b.条件字段1 and a ...

  2. python 爬取国家粮食局东北地区玉米收购价格监测信息

    #!/usr/bin/python# -*- coding: UTF-8 -*-import reimport sysimport timeimport urllibimport urllib.req ...

  3. BST性能分析&改进思路——平衡与等价

    极端退化 前面所提到的二叉搜索树,已经为我们对数据集进行高效的静态和动态操作打开了一扇新的大门.正如我们所看到的,BST从策略上可以看作是将之前的向量(动态数组)和链表结构的优势结合起来,不过多少令我 ...

  4. Linux----CentOS-7搭建免流服务器

    本次实验采用腾讯云服务器:https://cloud.tencent.com/ 大学生身份的可以看看有没有什么活动购买 其他身份的78一个月 关于腾讯云服务器的使用可以看看腾讯云的使用手册 本博客涉及 ...

  5. ITM事件直接接收并解析

    之前在实施一个监控项目时.客户由于买了IBM的小机.当前就赠送了TIVOLI的系统监控软件一套,客户也在他们的生产环境中部署了ITM的监控.由于没有购买IBM的netcool,无法集中管理告警事件,请 ...

  6. nginx+redis实现session的共享

    上一篇我们介绍了nginx实现的负载均衡和动静分离,可看这边. 我们在文章的末尾说到,负载均衡需要面临的一个问题是内存数据的同步.例如:我有A,B两台服务器做了负载均衡,当我在A服务器上执行了登录并且 ...

  7. IDEA 初始配置教程

    IDEA 初始配置教程 如果你是第一次使用 IDEA,或者对 IDEA 常用配置仍然不熟悉,那么本文就特别适合你. 本文只是根据我自己的使用经验来进行配置,不一定适合所有的情况,但是对你肯定会有帮助. ...

  8. 伪列:Oracle显示查询结果前几条记录用rownum<=。去掉重复记录,保留最早录入记录:取出最小ROWID

    显示6-10行记录: 去掉重复记录,保留最早录入记录:取出最小ROWID SELECT deptno,dname,loc,min(ROWID) FROM dept GROUP BY deptno,dn ...

  9. 【java】java.util.Arrays类常用方法

    package Arrays类; import java.util.Arrays; public class TestArrays { public static void main(String[] ...

  10. iOS学习之Socket使用简明教程- AsyncSocket

    转载自:http://my.oschina.net/joanfen/blog/287238 如果需要在项目中像QQ微信一样做到即时通讯,必须使用socket通讯,本人也是刚学习,分享一下,有什么不对的 ...