深入了解 Java 类
既然您了解面向对象编程框架中类和对象的一般角色,那么您应深入了解有关 Java 平台的类结构和实现的以下细节:
类成员:类成员总是 域或 方法。域代表数据,而方法代表操作。类可以定义任何数量的成员。
访问修饰符:使用 访问修饰符声明类成员,访问修饰符指定在定义该成员的类之外对成员的可访问性。例如,绝对不能访问声明为 private 的成员,但可访问声明为 public 的成员。
对象:类仅仅是定义而已。代码中实际使用的是称为 对象的类的实例。您将了解如何从类创建对象。
构造函数: 构造函数是用于创建对象的特殊运算符。一般来说,如果不能创建类的对象,则这个类就没有多大用处。构造函数非常重要,因为它们提供创建新类实例的能力。
this 关键字 :Java 对象隐含引用自身。了解 this 关键字如何引用自身很重要。
类成员
就 成员而言,Java 类是一个定义属性和操作的独立代码模块。域和方法都是成员的例子。
域是在类的内部声明的变量。Java 域有两种变体: 实例变量和 类变量。实例变量与类的每个实例相关,每个实例都有自己的实例变量副本。类变量(用 static 关键字声明)与整个类相关,类与单个类变量共享所有的类实例。例如, BankAccount 中的 balance 域是一个实例域,因为每个 BankAccount 实例有自己的 balance,它独立于其他每个 Account 对象的 balance。在另一方面,您可以声明一个 interest 域作为类域,因为每个 BankAccount 对象都采用相同的利率。
方法是类内部的函数。Java 方法有两种变体: 实例方法和 类方法。每个类实例获得它自己实例方法的副本,但只有一个类方法的副本,所有类实例都共享它。您可以使用 static 关键字声明类方法。使用实例方法对实例变量进行操作,使用类方法对类变量进行操作。例如, BankAccount 中的 deposit() 方法是一个实例方法,因为每个 BankAccount 都有自己的 balance 域, deposit() 方法对该域进行更改。您可以将 setInterest() 方法声明为类方法,因为每个 BankAccount 都共享一个 setInterest() 方法可以更改的 interest 域。
清单 12 中的 BankAccount 有五个域: balance (是实例域)、 interest (是类域)。三个成员是方法: deposit() 和 withdraw() 是实例方法, setInterest() 是类方法。注意,您使用对象名称来访问实例变量,使用类名称来访问类成员。
清单 12. BankAccount 类
2
3 public class BankAccount {
4
5 private float balance; // an instance field
6
7 private static float interest; // a class, or static, field
8
9 // an instance method
10
11 public void deposit(float amount) {
12
13 balance += amount;
14
15 }
16
17 // an instance method
18
19 public void withdraw(float amount) {
20
21 balance -= amount;
22
23 }
24
25 // a class, or static, method
26
27 public static void setInterest(float interestRate) {
28
29 interest = interestRate;
30
31 }
32
33 public static void main(String[] args) {
34
35 // create a new account object
36
37 BankAccount account = new BankAccount();
38
39 // deposit $250.00 into the account
40
41 account.deposit(250.00F);
42
43 // set interest rate for all BankAccount objects
44
45 BankAccount.setInterest(5.0F);
46
47 }
48
49 }
50
51
访问修饰符
与 Visual Basic 类似,Java 语言允许设置类成员的可视性。Java 成员使用 public 修饰符表明可以在类的内部和外部访问某个成员。Java 使用 private 修饰符表明只能在类的内部访问该成员。在类的外部是不能访问私有成员的。
请再次考虑 BankAccount 类。假定您希望使用 BankAccount 对象的程序员通过使用 deposit() 和 withdraw() 方法来更改余额。您要将这些方法声明为 public ,因此可以在 BankAccount 类的代码之外调用这些方法。但是,您不希望其他程序员直接更改 balance 域,因此 balance 域的访问修饰府要采用 private 。
您可能搞不明白默认访问级别(即没有使用 public 或 private 修饰符声明的类成员的访问级别)是哪个级别。您可能认为默认访问级别是 public ,即 Visual Basic 中的默认访问级别。而实际上,Java 语言中的默认访问级别称为 包访问,因为只有同一个包中的类才能访问这些类成员。如果要将某个成员声明为包访问,请不要使用访问修饰符关键字
Java 可以定义一个以上的访问级别,称为 protected 。如果希望某个成员可以在子类中访问,则请使用 protected 修饰符。创建对象
如果您研究一下清单 12 中 BankAccount 类的 main() 方法,就会明白下列代码创建了一个新 BankAccount 对象:
BankAccount account = new BankAccount();
首先,声明一个类型为 BankAccount 的对象(即变量)。您能会猜到, new 关键字留出足够的内存来创建一个新对象。新对象实际上由以下语句创建的: BankAccount() 。该语句看起来像一个方法调用。然而,清单 12 没有声明此名称的方法,因此您可能想知道这个语句是干什么的。
实际上,这个语句是一个构造函数调用。没有构造函数就不能创建 Java 对象,因此,如果您编写的类没有构造函数,编译器就创建一个默认的构造函数。这就是可以调用 BankAccount() 的原因,即使您在 BankAccount 类中没有显式编写构造函数也是如此。
Visual Basic 支持构造函数的概念,方法是允许为每个类定义一个称为 Class_Initialize 的过程,与 Java 语言不同,它不允许传递参数。
Java 构造函数没有返回类型;所有构造函数都返回定义它的类的新对象。每个 Java 构造函数都必须与声明它的类有完全相同的名称。否则,构造函数声明与方法声明几乎一样。特别是,构造函数可以带参数,就像 Java 方法一样。
严格地说,构造函数不是一种方法,因为方法是类成员,而构造函数不是。类成员与域和方法一样,都在子类中继承。而构造函数是绝对不会被继承的。
显式引用
Java 语言使用 this 关键字引用当前的对象。您可以使用 this 关键字显式引用当前类中的域、方法和构造函数。
this 关键字的常见用法是解决变量范围问题。例如, BankAccount 类有一个称为 balance 的字段。我们假定您要编写一个称为 setBalance(float balance) 的方法,它设置对象的 balance 域。问题出在 setBalance(float balance) 域的内部,当您引用 balance 时,您实际上引用 balance 参数,而不是 balance 域。您可以通过使用 this 关键字显式引用该域,如清单 13 所示。
清单 13. "this" 关键字
2
3 public void setBalance(float balance) {
4
5 this.balance = balance;
6
7 }
8