5.1.6 控制对类成员的访问
(3)Public
最简单的访问指示是public。在任何类中、任何包中都可以访问了的public成员。只有在外部对象使用的时候不会产生不良的结果的时候,才声明为public成员。为了声明一个public成员,你可以使用public要害字,如下:
package Greek;
public class Alpha {
public int iampublic;
public void publicMethod() {
System.out.println("publicMethod");
}
}
现在,让我们重新编写Beta类再将它放置到不同的包中,并且要确保它跟Alpha毫无关系:
package Roman;
import Greek.*;
class Beta {
void AccessMethod() {
Alpha a = new Alpha();
a.iampublic = 10; // legal
a.publicMethod(); // legal
}
}
从上面的代码段你可以看出,Beta可以合法地检查和修改在Alpha类中地iampublic变量并且可以合法地调用publicMethod。
(4)Package
假如你不显性设置成员访问其它级别的成员的时候,使用package访问级。这个访问级答应在相同包中的类访问成员。访问的级别是假设在相同包中的类是互相信任的朋友。比如 ,以下修改过的Alpha类声明了一个单一包访问的成员变量和方法。Alpha处在Greek包中:
package Greek;
class Alpha {
int iampackage;
void packageMethod() {
System.out.println("packageMethod");
}
}
这个Alpha类同时可以访问iampackage和packageMethod。另外,所有定义在和Alpha相同的类也可以访问iampackage和packageMethod。假如Alpha和Beta都是定义为Greek包的一部分:
package Greek;
class Beta {
void accessMethod() {
Alpha a = new Alpha();
a.iampackage = 10; // 合法
a.packageMethod(); // 合法
}
}
如上所述,Beta可以合法访问iampackage和packageMethod。
5.1.7 理解实例和类成员
Java类可以包括两种类型的成员:实例成员和类成员。这一小节将向你介绍如何生命这两种成员以及如何使用它们。
你可以如下来声明一个成员变量,如Myclass中的aFloat:
class MyClass {
float aFloat;
}
你声明了一个实例变量。每次你创建类的实例的时候,系统就会为这个实例创建一个类实例的副本。你可以对象中访问对象的实例变量。
实例变量跟类变量是有区别的。系统为每个类分配类变量而不管类创建的实例有多少。当第一次调用类的时候,系统为类变量分配内存。所有的实例共享了类的类变量的相同副本。你可以通过一个实例或者类本身来访问类变量。
方法是相似的,类有实例方法和类方法。实例方法是对当前对象实例变量进行操作的,而且访问类变量。另外一个方面,类方法不能访问定义在类中的实例变量,除非它们创建了一个新的对象以及通过对象访问它们。同时,类方法可以在类中被调用,你不必一个实例来调用一个类方法。
缺省地,除非其它指定,定义在类中地成员是实例成员。定义在下面的类有一个实例变量(整型数x)以及两个实例方法(x和setX,是让其它对象来设置和查询x的数值的):
class AnIntegerNamedX {
int x;
public int x() {
return x;
}
public void setX(int newX) {
x = newX;
}
}
每次你从类实例化新对象的时候,你就得到了类实例变量的一个新副本。这些副本跟新对象是联系在一起的。因此,每次你实例化一个新AnIntegerNamedX对象的时候,你就得到了一个和AnintegerNamedX对象有联系的x的新副本。
类的所有实例共享了一个实例方法的相同实现。AnIntegerNamedX的所有实例共享了x和setX的相同实现。这里注重两个方法x和setX都引用了对象的实例变量x。但是你可能会问“假如AnIntegerNamedX的所有实例共享了x和setX的相同实现,这不会模棱两可吗?”,答案当然是:不是。在实例方法中,实例变量的名字是引用了当前对象的实例变量。因此,在x和setX中x就等价于这个x,不会产生模棱两可的情况。
AnIntegerNamedX外部的对象假如想访问x,必须通过AnIntegerNamedX的一个特定实例来实现。假如下面的代码段是在其它对象的方法中,它包含了两种不同AnIntegerNamedX类型的对象,并且设置x为不同的数值,然后显示出来:
. . .
AnIntegerNamedX myX = new AnIntegerNamedX();
AnIntegerNamedX anotherX = new AnIntegerNamedX();
myX.setX(1);
anotherX.x = 2;
System.out.println("myX.x = " + myX.x());
System.out.println("anotherX.x = " + anotherX.x());
. . .
这里值得注重,代码使用setX来设置myX的x数值,而直接赋值给anotherX.x。