大可制作:QQ群:31564239(asp|jsp|php|mysql)

Java Gossip: 抽象类(Abstract class)

当您定义类时,可以仅声明方法名称而不实现当中的逻辑,这样的方法称之为“抽象方法”(Abstract method),如果一个类中包括了抽象方法,则该类称之为“抽象类”(Abstract class),抽象类是个未定义完全的类,所以它不能被用来生成对象,它只能被继承,并于继承后完成未完成的抽象方法定义。

在Java中要声明抽象方法与抽象类,您使用"abstract"关键字,直接来看个应用的例子,下面定义一个简单的比大小游戏抽象类:

  • AbstractGuessGame.java
public abstract class AbstractGuessGame {
private int number;

public void setNumber(int number) {
this.number = number;
}

public void start() {
showMessage("Welcome");

int guess;
do {
guess = getUserInput();
if(guess > number) {
showMessage("bigger than the goal number");
}
else if(guess < number) {
showMessage("smaller than the goal number");
}
else
showMessage("you win");
} while(guess != number);
}

protected abstract void showMessage(String message);
protected abstract int getUserInput();
}

在声明类时使用"abstract"关键字,表示这是一个抽象类,在这个类中,您定义了start()方法,当中先实现比大小游戏的基本规则,然而 您不实现与使用者互动及讯息是如何显示的,这您分别定义为抽象方法showMessage()与 getUserInput(),在方法上使用"abstract"关键字,可以仅定义方法而不实现其内容。

使用这个类的办法是继承它,并完成当中未定义完全的抽象方法showMessage()与getUserInput(),例如实现一个简单的文字接口游戏类:

  • ConcreteGuessGame.java
import java.util.Scanner;

public class ConcreteGuessGame extends AbstractGuessGame {
private Scanner scanner;

public ConcreteGuessGame() {
scanner = new Scanner(System.in);
}

protected void showMessage(String message) {
System.out.println(message + "!");
}

protected int getUserInput() {
System.out.print("input a number: ");
return scanner.nextInt();
}
}

接下来写个简单的测试程序,看看这个文字接口比大小游戏类是不是可以运作:
  • Test.java
public class Test {
public static void main(String[] args) {
AbstractGuessGame guessGame =
new ConcreteGuessGame();
guessGame.setNumber(50);
guessGame.start();
}
}

这边必须知道,一个基底类的对象引用名称,可以用来指向其衍生类的对象而不会发生错误,所以上面的这个指定是可以接受的:
AbstractGuessGame guessGame =
                    new ConcreteGuessGame();
 

由于guessGame仍是AbstractGuessGame类型的引用名称,它可以操作子类 ConcreteGuessGame的实例中名称相同的公开操作接口(方法),简单的说,透过guessGame引用名称,您可以操作 ConcreteGuessGame的实例之setNumber()与start()方法,这是多态(Polymorphism)操作的一个实际例子。

执行结果:

Welcome!
input a number: 10
smaller than the goal number!
input a number: 60
bigger than the goal number!
input a number: 50
you win!


今天如果您想要实现一个有视窗接口的比大小游戏,则您可以继承AbstractGuessGame并实现您的抽象方法showMessage()与 getUserInput(),事实上,上面的例子是 Template Method 模式 的一个实际例子,使用抽象类与方法来实现Template Method 模式,在很多应用场合都可以见到。