访问控制(Access control)(或 Implementation hiding)与最初实现不恰当有关
public 成员放在类的开头,接着是 protected 成员,包访问权限成员,最后是 private 成员。
包(Package)
- 包名小写
- package名称是类的创建者的范顺序的Internet域名 ?
- 包内包含一组类,被组织在单独的namespace下。
一个Java源代码文件被称为一个 编译单元 (complication unit),每个编译单元中只能有一个 public 类
代码组织
package hiding
import hiding.*
Means: 当前编译单元为 hiding 类库的一部分;引用hiding下面所有的class
- 使用package语句,它必须是文件中除注释以外的第一句程序代码。
冲突
import xxx.* 导入两个相同名字的类库时,则需要强制指明类所在package名称。java.util.Vector v = new java.util.Vector()
定制工工具库
制定一个自己常用的package,并不断地将常用代码加入自己的类库中,即可通过import自己的类来使用这些方法。
最初使用关键字 package 可能会有点不顺,因为除非遵守“包名对应目录路径”的规则,否则会收到很多意外的运行时错误信息如找不到特定的类,即使这个类就位于同一目录中。如果你收到类似信息,尝试把 package 语句注释掉,如果程序能运行的话,你就知道问题出现在哪里了。
访问权限修饰符
包访问权限
未使用访问修饰符时,则为默认访问权限,被称为包访问权限(Package access)(freiendly),允许当前包中所有其他类成员访问。
public,private,protected,default
- 若未明显指定访问权限修饰符,则默认为default。调用该类的function时,需要满足与该类在同一package下。
- protected 用于将代码向继承子类授权访问
- public 类的名称必须完全与含有该编译单元的文件名相匹配。
书中所提包访问权限与public构造器冲突实际上为,包访问权限只允许当前包中其他类成员访问,而非public,故定义public构造器实际为错误决定。
类既不能是 private 的(这样除了该类自身,任何类都不能访问它),也不能是 protected 的。为了防止类被外界访问,可以将所有的构造器声明为 private,这样只有你自己能创建对象(在类的 static 成员中)
// hiding/Lunch.java
// Demonstrates class access specifiers. Make a class
// effectively private with private constructors:
class Soup1 {
private Soup1() {}
public static Soup1 makeSoup() { // [1]
return new Soup1();
}
}
class Soup2 {
private Soup2() {}
private static Soup2 ps1 = new Soup2(); // [2]
public static Soup2 access() {
return ps1;
}
public void f() {}
}
// Only one public class allowed per file:
public class Lunch {
void testPrivate() {
// Can't do this! Private constructor:
//- Soup1 soup = new Soup1();
}
void testStatic() {
Soup1 soup = Soup1.makeSoup();
}
void testSingleton() {
Soup2.access().f();
}
}
[1]表示用static方法返回对象。
[2]使用 单例模式 ,作为 static private 的成员创建,有且只有一个。