当您定义类别时,可以仅宣告方法名称而不实作当中的逻辑,这样的方法称之为「抽象方法」(Abstract method),如果一个方法中包括了抽象方法,则该类别称之为「抽象类别」(Abstract class),抽象类别是个未定义完全的类别,所以它不能被用来生成对象,它只能被扩充,并于扩充后完成未完成的抽象方法定义。
在Java中要宣告抽象方法与抽象类别,您使用"abstract"关键词,直接来看个应用的例子,下面定义一个简单的比大小游戏抽象类别:
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(),例如实作一个简单的文字接口游戏类别:
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(); } }
接下来写个简单的测试程序,看看这个文字接口比大小游戏类别是不是可以运作:
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 模式,在很多应用场合都可以见到。