最近又开始看Think in java了,^^
一.类的"封装"与访问权限
java中类一般都是"封装"到package中,然后再由各个package组合在一起打包成jar包,如果一个名为parent的package中有一个java文件(.java),那么这个文件一般有且只有一个public 修饰的类,该类名必须和文件名一致,也可以有其它额外的类,但只有public修饰的类可以被parent包外访问,其它的类一般用作为public 提供支持,下面是个例子。
//son包下的Cookie类定义了一个拥有包访问权限的bite函数
package packaging.son;
import packaging.Util;
public class Cookie {
public Cookie(){
Util.print("Cookie的构造函数");
}
void bite(){
Util.print("bite");
}
protected void bite2(){
Util.print("bite2");
}
}
class Cream{
}
//son包下的Cookie类定义了一个拥有包访问权限的bite函数
package packaging.son;
import packaging.Util;
public class Cookie {
public Cookie(){
Util.print("Cookie的构造函数");
}
void bite(){
Util.print("bite");
}
protected void bite2(){
Util.print("bite2");
}
}
class Cream{
}
在上面的类中定义了一个Cream的非公开类
//调用son包中cookie类的具有包访问权限的bite函数,会出错
package packaging;
import packaging.son.Cookie;
public class Dinner {
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
Cookie cookie=new Cookie();
//Cream c=new Cream();
//cookie.bite();
}
}
//调用son包中cookie类的具有包访问权限的bite函数,会出错
package packaging;
import packaging.son.Cookie;
public class Dinner {
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
Cookie cookie=new Cookie();
//Cream c=new Cream();
//cookie.bite();
}
}
在测试程序里生成Cream对象时会出错,Dinner类所在包为packaging,因为在Dinner中只能使用被public 修饰的cookie类
编译器在碰到import语句时,首先会从CLASSPATH中查找,查找子目录为packaging/son/中所对应的变异后的.class文件
二.单例模式
如果一个类的构造函数的访问权限为private,那么这个类将不会被实例化,除非在这个类的static成员里,单例模式就是这样的
package packaging;
public class Singleton {
private static Singleton singleton=new Singleton();
private Singleton(){}
public static Singleton getObject(){
return singleton;
}
public void test(){
Util.print("test");
}
public static void main(String[] args){
Singleton.getObject().test();
}
}
package packaging;
public class Singleton {
private static Singleton singleton=new Singleton();
private Singleton(){}
public static Singleton getObject(){
return singleton;
}
public void test(){
Util.print("test");
}
public static void main(String[] args){
Singleton.getObject().test();
}
}
上面的类就是一个单例模式,其中加了一个测试的程序
二.类成员的访问权限
类成员的访问权限有4个,private,protected,package,public四种,其中private和public用的最多,package主要在同一包内可访问,如前面的代码,在son包中定义的Cookie类的成员方法bite是包访问权限的,而Dinner与Cookie不在同一个包中,所以无法访问Cookie中bite,protected用于继承,先看个例子
import packaging.son.Cookie;
public class ChocolateChip extends Cookie{
public ChocolateChip(){
Util.print("Chocolate构造函数");
}
public void chomp(){
//bite();
}
public void chomp2(){
bite2();
}
public static void main(String[] args) {
ChocolateChip c=new ChocolateChip();
c.chomp();
c.chomp2();
}
}
import packaging.son.Cookie;
public class ChocolateChip extends Cookie{
public ChocolateChip(){
Util.print("Chocolate构造函数");
}
public void chomp(){
//bite();
}
public void chomp2(){
bite2();
}
public static void main(String[] args) {
ChocolateChip c=new ChocolateChip();
c.chomp();
c.chomp2();
}
}
packageing包中的ChocolateChip类继承了其子包son中的类Cookie,Cookie中的拥有包访问权限的bite方法却不能在子类中可见,父类中随后的具有protected 访问权限的bite2方法可以被子类继承使用
同包之间的类具有包访问权限的方法可以访问
//定义f函数的访问权限为包访问权限
package packaging;
public class Pie {
void f(){
Util.print("Pie.f()");
}
}
//定义f函数的访问权限为包访问权限
package packaging;
public class Pie {
void f(){
Util.print("Pie.f()");
}
}
//由于和Pie类在同一个包中,Cake可以访问到Pie类中具有包访问权限的函数的f
package packaging;
public class Cake {
public static void main(String[] args) {
Pie pie=new Pie();
pie.f();
}
}
//由于和Pie类在同一个包中,Cake可以访问到Pie类中具有包访问权限的函数的f
package packaging;
public class Cake {
public static void main(String[] args) {
Pie pie=new Pie();
pie.f();
}
}
可以看到在Cake中可以访问到pie中具有包访问权限的方法f
综上可得:
1.同一包中的具有package及其以上访问权限的成员,可以被访问
2.在继承中,父子类不在同一包中,可以通过protected进行继承