Ⅵ 访问权限控制
6.1包:库单元
-
一个
.java
文件被认为是一个编译单元,一个编译单元内只能有一个public
类,并且此类必须和文件名相同(包括大小写)。若这个编译单元内有其他类,那么包的外部世界是无法看见这些类的。这些类为编译单元内的public
类提供支持。 -
当编译
.java
文件时,会输出.class
文件,每个类都会被编译为.class
(包括非public
类) -
Java没有C语言的条件编译功能,该功能是作为一个开关,来编译不同的代码来产生不同的行为。这项功能往往用于C语言跨平台上,这对于Java而言,是没有必要的,因为Java在设计阶段已经解决了这一问题。
条件编译还有一些其他家价值的用途,比如调试。
6.2 Java访问权限修饰词
- 包访问权限:
- 这是默认权限,没有任何关键字修饰。意味着当前包中的所有其他类对这个成员都有权访问;对于包之外来说,这个成员相当于被
private
修饰。
- public权限:
- 公有权限,这对于每个人都是开放的。
- 举个栗子:
//:access/food/Chicken.java
public class Chicken {
public Chicken(){
System.out.println("构造一只鸡");
}
//没有修饰符默认包访问权限
void eat(){
System.out.println("吃");
}
//公有权限
public void get(){
System.out.println("获得");
}
}
//:access/Dinner.java
public class Dinner {
public static void main(String[] args){
Chicken c=new Chicken();
c.eat();//这句无法访问,因为不在一个包中
c.get();//可以访问
}
}
- private权限:
-
私有权限,除了包含改成员的类,其他任何类都无法访问。
-
默认的包访问权限通常已经提供了充足的隐藏措施。类库的使用者是无法访问带有包权限的成员的。这样的设计很不错,因为默认访问权限应该是一种常用的权限,同时也是为了让类库的设计者在忘记给成员添加权限控制关键字时,能够使成员自动得到一种权限(一般不会出现设计者忘记添加关键字的情况)
-
这样说来,你可能会认为不需要经常使用
private
?错了,private
的使用非常重要。有一种场景(并非只有这一种),当需要控制如何创建对象,并阻止别人直接访问构造器,可以这样使用。
举个栗子:
public class Chicken {
private Chicken(){}
static Chicken makeAChicken(){
return new Chicken();
}
}
//隐藏了构造器
Chicken c=Chicken.makeAChicken();
- protected权限:
-
继承访问权限。
-
对于在这个packge外,某些基类的设计者,希望把这个类中的一些成员的访问权限赋予派生类而不是所有类。这就需要使用
protected
来修饰。对于在这个包内,protected
提供默认的包访问权限。 -
举个栗子:
//:access/food/Chicken.java
public class Chicken {
public Chicken(){
System.out.println("构造一只鸡");
}
//继承访问权限
protected void eat(){
System.out.println("吃");
}
//:access/FriedChicken.java
public class FriedChicken extends Chicken {
public FriedChicken(){}
public void chomp(){
eat();
}
}
//:access/Dinner.java
public class Dinner {
public static void main(String[] args){
FriedChicken fc=new FriedChicken();
fc.chomp();
}
}
6.4 类的访问权限
-
类不可以是
private
(因为这样会使其他任何类都访问不到它),也不可以是protected
的。(一个内部类可以是private
或protected
,但这是特例)。对于类的访问权限,只有public
和默认访问权限。 -
假如一个类是包访问权限,这意味着该类的对象可以由包内的任何其他类来创建。但是需要注意的是,若这个类的某个
static
成员是public
的话,包外还是可以调取这个static
成员。
6.5 总结
设计访问控制权限有两个原因。
-
第一是为了使类库的使用者(客户端程序员)不要去触碰那些他们不该触碰的部分。这对于客户端程序员而言是一种服务,同时也可以看到对他们来说,什么是重要的,什么是可以忽略的。(这个概念最早的两章中提过)
-
第二个原因,是为了让类库的设计者可以修改优化类的内部工作方式,而不用担心这会对类库的使用者带来影响。
需要注意的是,访问权限控制专注于类库的创建者和类库的使用者(客户端程序员)之间的关系,这种关系是一种通信方式。
但是,在一些情况下并非如此。假如你在一个组内和大家一起工作,所有的东西都放在一个包内,这种情况是另一种不同的通信方式,因此严格遵循访问权限规则不一定是最佳选择,默认包访问权限也许仅仅只是可行。(这点暂时还不是很理解)
扫一扫,关注公众号小白的成长探索之路。
网友评论