`
0428loveyu
  • 浏览: 29356 次
  • 性别: Icon_minigender_2
  • 来自: 西安
文章分类
社区版块
存档分类
最新评论

访问控制符

 
阅读更多

在Java中,一般认为有4种访问控制符,从最严格的到最宽松为private、default、protected、public。这篇文章讨论这四个访问控制符可以用于修饰类(class)、域(field)、方法(method)、构造器(constructor)的情况。除了这四种类型外,接口、enum等也可以使用访问控制符,但是不是每个控制符都能使用。

(在下文中,如果不加说明,类一般指top-level class)

1、 private修饰符

无论是域、方法还是构造器被声明为private,意味着只能在本类中才能使用它们。所谓使用,对于域来说就是访问,方法就是调用,构造器就是新建一个对象。

1.1 private修饰类:

有些地方的文章会说类不能声明为private,理论上来说这是错的。private修饰一个类时,只能用于声明member class(成员类解释),【参考Java8语言规范的8.1.1】这时候只有成员类(member class)的外部类能够实例化这个类(如果这个类可以被实例化,也就是不是抽象类。)。看下面代码(已经通过编译验证):

/**
 * @author Brandon B. Lin
 *
 */
public class Test2 {
	
	public void test() {
		new PrivateClass();
		new PrivateStaticClass();
	}
	
	private class PrivateClass {
		private PrivateClass() {
			
		}
	}
	
	private static class PrivateStaticClass{
		private PrivateStaticClass() {
		}
	}

}

可以看到,成员类可以使用private来修饰,因此它只能在这个类中被实例化(如果可以被实例化)。注意到的是,尽管上面的两个成员类的构造器都是private,依然能够在外部类创建实例,这是嵌套类区别于非嵌套类的一个体现。如果我们在成员类价格abstract,则在其外部类也不能被实例化!有关内部类,一篇很好的英文文章:http://www.learn-java-tutorial.com/inner-classes.cfm


1.2 private修饰构造器:

如果构造器被声明为private,意味着除了本类以外,不能调用构造函数,也就是不能实例化这个类。(注意开头的声明,这里的类指的是top-level class,对于成员类,即使构造器为private,在其外部类一个可以实例化。

private构造器的一个典型应用场景就是单例模式,将构造器声明为private,使得外界不能对该类进行实例化。具体代码如下:

public class Singleton {
	private Singleton() {
		// do something
	}
	
	private static Singleton instance = null;
	
	public static Singleton getInstance() {
		if (instance == null) {
			instance = new Singleton();
		}
		return instance;
	}

}


1.3 private修饰域和方法:

一般情况下,域和方法情况十分类似,因此我们将两者和在一起讨论。private修饰域和方法的时候也很明确,就是这些域不能在类以外被使用,方法不能在类外被调用。域不能在类外被访问并不代表外界无法访问这些域,可以通过get方法对外界提供接口。


2. default修饰符

默认修饰符有时候也称为包访问控制符。

2.1 default修饰类

对于top-level class,不是被public修饰就是没有修饰符,也就是default修饰符。default修饰的top-level类,只能在同一个包中使用,例如被实例化(如果可以被实例化),当然也包括调用静态方法等等其他操作。对于member class,也可以不使用修饰符,也就是default修饰符。如果不使用修饰符,则在同一个包中,可以通过其外部类的实例对象来实例化member class。

2.2 default构造器

如果构造器没有访问控制符,说明在同一个包的范围内,可以使用该类,即实例化这个类。

2.3 default域和方法

没有使用访问控制符的域和方法,可以在包范围内被使用。


3. protected修饰符

3.1 protected class:

如果protected用于修饰类,那只能修饰member class,和private修饰类是一样的。如果一个member class被protected修饰,那么除了在其外部类可以使用这个member class外,外部类的子类也可以使用它(通过外部类的子类的实例)。例如,我们有下面一个类Pkg1Public:

/**
 * @author Brandon B. Lin
 *
 */
public class Pkg1Public {

	private class Pkg1Private {
		
	}
	
	
	protected class Pkg1Protected {
		
	}

}

我们定义了两个成员类,一个为private,一个protected,那么这两个成员类在其外部类,也就是Pkg1Public中都可以被使用。我们再定义一个Pkg1Public类的子类:ExtClass,如下:

/**
 * @author Brandon B. Lin
 *
 */
public class ExtClass extends Pkg1Public {

	public ExtClass() {
		//
	}
	/**
	 * @param args
	 */
	public static void main(String[] args) {
		ExtClass ext = new ExtClass();
		Pkg1Protected p = ext.new Pkg1Protected();
		//Pkg1Private p1 = ext.new Pkg1Private();

	}

}

可以看到,被声明为protected的member class可以通过外部类的子类的实例进行使用,而private的成员类则不行(呗注释掉的一行是不合法的。)


3.2 protected修饰构造器

如果一个类的构造器被修饰为protected,那么这个类可以在同一个包或者其子类中被实例化。在同一个包中被实例化容易理解。在子类中被实例化到底什么玩意儿?如果其子类也在同一个包,那一回事。如果子类不在同一个包,那么这个被protected修饰的构造器一样可以被使用,一般通过super来调用。例如,父类代码如下:

/**
 * @author Brandon B. Lin
 *
 */
public class People {

	protected People() {
		
	}
	
}

子类跟父类在不同的package中,代码如下:

/**
 * @author Brandon B. Lin
 *
 */
public class Children extends People {


	public Children() {
		super();
	}
	
	/**
	 * @param args
	 */
	public static void main(String[] args) {
		// TODO Auto-generated method stub


	}


}
在子类的构造器中,可以调用父类的构造器,及super();如果将父类中的构造器protected去掉,变为包访问,则调用super()是错误的,编译通不过。


3.3 protected修饰域和方法

这个相对简单了,被protected修饰的域和方法,除了包访问范围外,在子类也可以被访问,即使在不同的包。不多解释。


4.public修饰符

public意思是全世界都可以使用。

4.1 public修饰class:

没什么可说呀。top-level要么没有修饰符,要么public。而成员类可以被四种访问控制符任何一个修饰,即使使用public修饰member class不是个好的设计。

4.2 public构造器

简单明了,全世界都可以实例化这个类。能够使用构造器进行实例化的前提当然是这个类可以被使用,比如如果这个类使用默认修饰符,那么在其他包中跟你没办法引用这个类(也就是你根本import不进去),也就没办法使用构造器。

4.3 public修饰域和方法

一样简单,全世界都可以。但是需要注意的是,用public修饰一个实例域不是什么好主意,把static或者final static的域限定为public倒是个好想法。我们这里说导出都可以访问,其实不然,比如我们定义一个类,不是public,如下:

/**
 * @author Brandon B. Lin
 *
 */
class Car {

	public static final int wheel=4;
	private String color;
	public Car(String color) {
		this.color = color;
	}
	
	public String getColor() {
		return color;
	}

}

在其他包中,我们根本没办法访问这个Car类,更不用说访问域和方法了。所以也不是全世界都能访问。


初稿暂时这样,日后进一步修改完善,欢迎指错。


版权所有,转载请注明出处。

分享到:
评论

相关推荐

    java访问控制符.txt

    简要叙述什么是访问控制符,列出Java中的访问控制符,并说明各个访问控制符的控制权限

    as3.0访问控制符

    AS3.0中访问控制符:public、private、protected和internal的区别

    Java语言与面向对象程序设计第09讲(访问控制符和类的设计)

    java语言与面向对象设计PPT,讲解的很是详细,很适合初级学员仔细拜读,里面还有很多随堂练习题

    Java的访问控制符

    java的访问控制符分为两类:类的访问控制符,属性和方法的访问控制符。  1. 类的访问控制符有两种:public, default(默认的,什么都不用写)  default是包内访问控制符。  当然对于内部类还可以有static修饰,...

    Java类的修饰符、访问控制符

    实验目的 理解掌握Java类修饰符、访问控制符等;理解熟悉String类的equals方法和= =运算符;进一步熟悉面向对象基本概念;熟悉Java中对象声明、创建、访问、参数传值等基本语法;

    【后端】java基础(5.3)java高级基础之java的修饰符——访问控制符

    java的控制符可分为两大类,一种是访问控制符,另一种是非访问控制符。我们上文提到的public,private便是访问控制符了。 访问控制符:访问控制符的作用是说明被声明的内容(类、属性、方法和构造方法)的访问权限 ...

    13_访问控制符_2 视频

    13_访问控制符_2 视频文件(javase)

    12_访问控制符_1 视频

    12_访问控制符_1 视频文件(javase)

    剖析Java中的访问/非访问控制符以及神奇的main函数

    文章目录前言特性中的继承访问控制符成员访问控制符private默认protectedpublic类的访问控制符非访问控制符static静态域静态方法finalfinal类final方法final字段和局部变量main()方法 你好,我是goldsun。 你有想法...

    JAVA封装的特点、访问控制符.docx

    )封装的特点: 主要讲述封装与暴露 2)访问控制符 主要讲述private、不写、protected、public 3)指定原则:

    【后端】java基础(5.4)java高级基础之java的修饰符——非访问控制符

    上章讲了访问控制符,这章开始讲非访问控制符。 java中的非访问修饰符的作用各不一样,据我所知常用的有六种: static final abstract synchronized volatile transient 今天我们只讲前三种,后面三种等我们讲到线程...

    JAVA 面向对象程序设计第2章 面向对象进阶.pptx

    2.3.2 Java访问控制符;2.3.2 Java访问控制符;2.3.2 Java访问控制符;2.3.2 Java访问控制符;2.3.2 Java访问控制符;2.3.3 学生实践练习;2.3.3 学生实践练习;2.4 static关键字;2.4 static关键字;2.4.1 静态成员变量;...

    Java 中的访问权限控制

    NULL 博文链接:https://tonysmith.iteye.com/blog/1431942

    java实验报告 四个访问权限,抽象数据类型栈,计算器

    编写四个类A、B、C、D,其中类A、B在同一个包中,类C、D在另一个包中,且类C为类A的子类,通过这四个类来测试private,protected,public和friendly四个访问权限的区别。实现栈的基本操作。实现计算器。

    JAVA入门1.2.3:一个老鸟的JAVA学习心得 PART1(共3个)

    10.1.1 饭前水果:实例变量的访问控制符 237 10.1.2 一切还是从汽车开始 238 10.1.3 一类车,一个类 241 10.1.4 分开也有麻烦 244 10.1.5 使用继承——问题迎刃而解 245 10.1.6 使用Bus类 248 10.1.7 Java中的...

    Java入门1·2·3:一个老鸟的Java学习心得.PART3(共3个)

    10.1.1 饭前水果:实例变量的访问控制符 237 10.1.2 一切还是从汽车开始 238 10.1.3 一类车,一个类 241 10.1.4 分开也有麻烦 244 10.1.5 使用继承——问题迎刃而解 245 10.1.6 使用Bus类 248 10.1.7 Java中的...

    Java中的封装和访问控制符

     封装是Java面向对象的三大特征之一(另外的两个特征为多态和继承),封装指的是将对象的状态信息隐藏在对象内部,从外面是看不出来的,当然也不允许外部程序直接访问对象内部信息,而是通过该类所提供的方法来...

    【05-面向对象(下)】

    •局部内部类不能在外部类以外的地方使用,那么局部内部类也不能使用访问控制符和static修饰 匿名内部类 •匿名内部类适合创建那种只需要一次使用的类,定义匿名内部类的语法格式如下: •new 父类构造器...

    实验指导书

    一、实验目的 1. 通过编制一个独立应用程序,使得学生掌握Java的系统所提供类的引用方法;...3. 掌握类及其成员的访问控制符,static等修饰符的用法。 4. 掌握类中各种变量的作用范围。 5. 掌握方法的重载。

    Java学习笔记-超强笔记

    实例变量的作用域至少在本类内部,受访问控制符的限制。 在重合作用域,实例变量和局部变量允许有命名冲突,“局部优先”。 定义方法: 格式: [ 修饰符 ] 返回类型 方法名( 参数列表 ) [ throws ...

Global site tag (gtag.js) - Google Analytics