Java中的访问控制修饰符已经困惑笔者多时,其中较复杂的情况一直不能理解透彻。今天下定决心,系统、全面地研究Java中的访问控制修饰符的所有方面,并整理成这篇文章,希望有同样疑惑的读者读完后能有所收获。如果文章中出现错误,欢迎评论指出,共同交流~

说在前面:这篇文章只研究Java中访问控制修饰符声明类的变量/方法的情况。

先抛出结论:

* 成员变量/方法的访问权限

*                                        private        default        protected        public

* 自己包自己类                          √               √                  √                √

* 自己包别的类                                           √                  √                √

* 别的包别的类有继承关系②                                            ①               √

* 别的包别的类无继承关系                                                                 √

①:子类可以继承,但是不能访问父类的成员变量/方法(一般来说,可以访问就可以继承)。

②:有继承关系说明访问对象所在的类是父类。

1. 让我们来看一下Java中访问控制修饰符的定义。

Java中,可以使用访问控制符来保护对类、变量、方法和构造方法的访问。

访问的形式有以下四种:

· 某个类的成员变量访问某个类的成员变量

· 某个类的成员变量访问某个类的成员方法

· 某个类的成员方法访问某个类的成员变量

· 某个类的成员方法访问某个类的成员方法

ps:以下代码均以第三种形式为例,其他形式基本一致。

根据访问对象的不同,访问的方式又可划分为两大类:

· 访问对象在同一个类,此时可以通过[成员变量/方法的名字]直接访问。

class A {
int a = 10; void printA() {
System.out.println(a);
}
}

printA()要访问a,因为它们在同一个类,所以可以通过a直接访问。

· 访问对象在不同类(假设访问对象在类B),此时可以通过声明、初始化B的一个对象,通过[对象名.成员变量/方法的名字]进行访问。

ps:这种情况仅限于成员方法访问成员变量/方法。

class A {
void printB() {
B ob = new B();
System.out.println(ob.b);
}
} class B {
int b = 10;
}

A中的printB()要访问B中的b,因为它们不在同一个类,所以可以在printB()中声明、初始化B的一个对象ob,通过ob.b进行访问。

此外,当访问对象为静态变量/方法时,可以通过[访问对象所在类的类名.成员变量/方法的名字]进行访问。

class A {
static int a = 10; int doubleA = A.a * 2; void printB() {
System.out.println(B.b);
}
} class B {
static int b = 10;
}

doubleA要访问a,由于a为静态变量,因此可以通过A.a进行访问。

A中的printB()要访问B中的b,由于b为静态变量,因此可以通过B.b进行访问。

2.结论中提到了包,我们来看一下Java中包的定义和作用。

为了更好地组织类,Java提供了包机制,用于区别类名的命名空间。

包的作用

  • 1 把功能相似或相关的类或接口组织在同一个包中,方便类的查找和使用。
  • 2 如同文件夹一样,包也采用了树形目录的存储方式。同一个包中的类名字是不同的,不同的包中的类的名字是可以相同的,当同时调用两个不同包中相同类名的类时,应该加上包名加以区别。因此,包可以避免名字冲突。
  • 3 包也限定了访问权限,拥有包访问权限的类才能访问某个包中的类。

Java使用包(package)这种机制是为了防止命名冲突,访问控制,提供搜索和定位类(class)、接口、枚举(enumerations)和注释(annotation)等。

关于包的使用方法,请参考Java教程 包(package),在此不详细赘述。

值得注意的是,import关键字引入的是class文件,而非java文件。

3.结论中还提到了继承,我们来看一下Java中继承的定义。

继承是java面向对象编程技术的一块基石,因为它允许创建分等级层次的类。继承可以理解为一个对象从另一个对象获取属性的过程。

关于继承的细节,请参照Java教程 继承,在此不详细赘述。

需要理解的是,子类继承父类的成员变量/方法时,是先访问再继承。因此上面访问权限的规则同样适用于继承。

在同一个包里,如果父类的某个成员变量/方法可以被访问,则该成员变量/方法可以被继承。即如果在子类成员方法中,声明、初始化父类的一个对象后,可以通过[对象名.成员变量/方法a]访问a,则声明、初始化子类的一个对象后,也一定可以通过[对象名.成员变量/方法a]访问a。

class A extends B {
void printB() {
B ob = new B();
System.out.println(ob.b);
A ob2 = new A();
System.out.println(ob2.b);
}
} class B {
int b = 10;
}

A继承B,因此A继承B的成员变量b。由于A在printB()中,声明、初始化B的一个对象ob后,可以通过ob.b访问b,则声明、初始化A的一个对象ob2后,可能通过ob2.b访问b。(可以访问则可以继承)。

然而,在不同包里,子类继承父类时,子类只能访问父类的public型成员变量/方法,却能继承父类的protected和public型成员变量/方法。(请看下面的例子)

值得注意的是,子类继承父类的成员变量/方法,并不意味着这些成员变量/方法存在于子类,因此不能通过[成员变量/方法的名字]直接访问。可以理解为继承而来的成员变量/方法进入了子类的异次元(雾)。

当然,如果继承而来的成员变量/方法被重写,这些成员变量/方法就存在于子类了,此时可以通过[成员变量/方法的名字]直接访问。

此处不讨论多态的情况,请参照Java教程 多态

回到结论,让我们来一层层地验证Java中的访问控制修饰符。

/* Stark.java */

package winter.is.coming;

public class Stark {
private boolean ned;
boolean robb;
protected boolean sansa;
public boolean arya; void howIsNed() {
System.out.println(ned);
}
} class Snow {
void whoseBastard() {
Stark stark = new Stark();
// System.out.println(stark.ned); 不可访问
System.out.println(stark.robb);
}
} /* Greyjoy.java */ import winter.is.coming.Stark; public class Greyjoy extends Stark {
void betray() { Stark stark = new Stark();
// System.out.println(stark.robb); 不可访问
// System.out.println(stark.sansa); 不可访问 Greyjoy greyjoy = new Greyjoy();
// System.out.println(greyjoy.robb); 不可访问
System.out.println(greyjoy.sansa); }
} /* Bolton.java */ import winter.is.coming.Stark; public class Bolton {
void flay() {
Stark stark = new Stark();
System.out.println(stark.arya);
}
}

① 自己包自己类 -- private可访问

Stark中的howIsNed()可以访问Stark中private型的ned。

② 自己包别的类 -- default可访问

Snow中的whoseBastard()可以访问Stark中default型的robb,不可以访问Stark中private型的ned。

③ 别的包别的类有继承关系 -- protected可继承,不可访问

Greyjoy中的betray()可以继承Stark中protected型的sansa,不可以访问Stark中protected型的sansa,也不可以继承和访问Stark中default型的robb。

④ 别的包别的类无继承关系 -- public可访问

Bolton中的flay()可以访问Stark中public型的arya。

详解Java中的访问控制修饰符(public, protected, default, private)的更多相关文章

  1. 【java基础】(1)Java的权限修饰符(public,protected,default,private)

    访问权限修饰符权限从高到低排列是public  ,protected  ,default, private. 一.根据“是否是同包”.“是否是子类”分为4中情况+本类 5种情况 二.把 同包中的子类 ...

  2. Java学习笔记十九:Java中的访问控制修饰符

    Java中的访问控制修饰符 一:Java修饰符的种类: 访问修饰符 非访问修饰符 修饰符用来定义类.方法或者变量,通常放在语句的最前端.我们通过下面的例子来说明: public class Hello ...

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

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

  4. java访问修饰符 public protect default private

    适用范围<访问权限范围越小,安全性越高>   访问权限   类   包  子类  其他包   public     ok   ok    ok     ok         (对所有可用的 ...

  5. java中4种修饰符访问权限的区别及详解全过程

    java中4种修饰符访问权限的区别及详解全过程 http://jingyan.baidu.com/article/fedf0737700b3335ac8977ca.html java中4中修饰符分别为 ...

  6. 分享知识-快乐自己:java 中的访问修饰符

    1):Java中的访问修饰符: Java面向对象的基本思想之一是封装细节并且公开接口.Java语言采用访问控制修饰符来控制类及类的方法和变量的访问权限,从而向使用者暴露接口,但隐藏实现细节. 访问控制 ...

  7. JAVA中的访问修饰符和包

    一.JAVA访问修饰符 访问修饰符,用来控制类中成员的可见性 有四个访问修饰符,分别是:default,private,public,protected 1.default(默认):默认权限,不用写的 ...

  8. 详解Java中的clone方法

    详解Java中的clone方法 参考:http://blog.csdn.net/zhangjg_blog/article/details/18369201/ 所谓的复制对象,首先要分配一个和源对象同样 ...

  9. java 修饰符的作用一(public protected default private 组)

    1.public protected default private 组 public 权限最大,同类,同包,不同包,同包子类父类之间,不同包子类父类之间都可以访问. java 默认的权限是defau ...

随机推荐

  1. hdu----(5050)Divided Land(二进制求最大公约数)

    Divided Land Time Limit: 8000/4000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)Tota ...

  2. 转:怎样在VMware ESXi上 克隆虚拟机

    Cloning virtual machines on VMware ESXi 翻译自http://www.dedoimedo.com/computers/vmware-esxi-clone-mach ...

  3. c# xml的增删改查操作 xmlDocument 的用法

    1.将xml转换为DataTable string path = "";//xml的位置StringReader sr = null;XmlTextReader xmlReader ...

  4. 项目三(集团官网)——总结(1) cookie

    最近十几天一直在忙着做集团官方网站的工作,从刚开始紧张的筹备一直到现在初步成型,今天才有时间特地来记录一下自己在这个项目中的收获. 先来说一说今天遇到的问题吧:关于cookie~ 事情起因是这样的:在 ...

  5. 【转】Session ID/session token 及和cookie区别

    Session + Cookie  知识收集! cookie机制采用的是在客户端保持状态的方案.它是在用户端的会话状态的存贮机制,他需要用户打开客户端的cookie支持.cookie的作用就是为了解决 ...

  6. linux 查看僵尸进程

    top -b -i -n 1 查看僵死进程命令 ps -A -o stat,ppid,pid,cmd | grep -e '^[Zz]' 查看apache 当前进程数 ps -ef | grep ht ...

  7. 扫盲如何在ECLIPSE中使用条件断点

    有时候在编码的时候我们希望知道代码变量符合某个条件时,才中断点,其他的情况不中断点.   解决办法1:   我们写个代码 判断,符合条件在符合条件处进行断点,这个方法很麻烦,需要去修改代码,不要是还需 ...

  8. Eclipse导出可执行Jar文件(包含第三方Jar包)

    1. 首先,右键你的Java工程,选择Export,在Java文件夹下选择Runnable JAR file,如下图所示: 2. 选择Runnable JAR file后,会弹出如下所示的对话框,选择 ...

  9. --投资情况统计详情sql

    --投资情况统计详情sqlselect BidRecord.*, RegInfo.UserName,UserInfo.phone,BorrowInfo.Title,BorrowInfo.BorrowC ...

  10. [Js]瀑布流

    描述: 1.每个图片宽度都一样,高度不一样 思路: 1.算出一共有几列(通过视窗总宽度/单个图片宽度得出) 2.根据一共几列*单个图片宽度,设置外围总宽度并水平居中(注:这个宽度应该是计算出来的,而不 ...