程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> JAVA編程 >> 關於JAVA >> java的抽象類和方法

java的抽象類和方法

編輯:關於JAVA

在我們所有樂器(Instrument)例子中,基礎類Instrument內的方法都肯定是“偽”方法。若去調用這些方法,就會出現錯誤。那是由於Instrument的意圖是為從它衍生出去的所有類都創建一個通用接口。
之所以要建立這個通用接口,唯一的原因就是它能為不同的子類型作出不同的表示。它為我們建立了一種基本形式,使我們能定義在所有衍生類裡“通用”的一些東西。為闡述這個觀念,另一個方法是把Instrument稱為“抽象基礎類”(簡稱“抽象類”)。若想通過該通用接口處理一系列類,就需要創建一個抽象類。對所有與基礎類聲明的簽名相符的衍生類方法,都可以通過動態綁定機制進行調用(然而,正如上一節指出的那樣,如果方法名與基礎類相同,但自變量或參數不同,就會出現過載現象,那或許並非我們所願意的)。
如果有一個象Instrument那樣的抽象類,那個類的對象幾乎肯定沒有什麼意義。換言之,Instrument的作用僅僅是表達接口,而不是表達一些具體的實施細節。所以創建一個Instrument對象是沒有意義的,而且我們通常都應禁止用戶那樣做。為達到這個目的,可令Instrument內的所有方法都顯示出錯消息。但這樣做會延遲信息到運行期,並要求在用戶那一面進行徹底、可靠的測試。無論如何,最好的方法都是在編譯期間捕捉到問題。
針對這個問題,Java專門提供了一種機制,名為“抽象方法”。它屬於一種不完整的方法,只含有一個聲明,沒有方法主體。下面是抽象方法聲明時采用的語法:
abstract void X();
包含了抽象方法的一個類叫作“抽象類”。如果一個類裡包含了一個或多個抽象方法,類就必須指定成abstract(抽象)。否則,編譯器會向我們報告一條出錯消息。
若一個抽象類是不完整的,那麼一旦有人試圖生成那個類的一個對象,編譯器又會采取什麼行動呢?由於不能安全地為一個抽象類創建屬於它的對象,所以會從編譯器那裡獲得一條出錯提示。通過這種方法,編譯器可保證抽象類的“純潔性”,我們不必擔心會誤用它。
如果從一個抽象類繼承,而且想生成新類型的一個對象,就必須為基礎類中的所有抽象方法提供方法定義。如果不這樣做(完全可以選擇不做),則衍生類也會是抽象的,而且編譯器會強迫我們用abstract關鍵字標志那個類的“抽象”本質。
即使不包括任何abstract方法,亦可將一個類聲明成“抽象類”。如果一個類沒必要擁有任何抽象方法,而且我們想禁止那個類的所有實例,這種能力就會顯得非常有用。
Instrument類可很輕松地轉換成一個抽象類。只有其中一部分方法會變成抽象方法,因為使一個類抽象以後,並不會強迫我們將它的所有方法都同時變成抽象。下面是它看起來的樣子:

下面是我們修改過的“管弦”樂器例子,其中采用了抽象類以及方法:
 

//: Music4.java
// Abstract classes and methods
import java.util.*;

abstract class Instrument4 {
  int i; // storage allocated for each
  public abstract void play();
  public String what() {
    return "Instrument4";
  }
  public abstract void adjust();
}

class Wind4 extends Instrument4 {
  public void play() {
    System.out.println("Wind4.play()");
  }
  public String what() { return "Wind4"; }
  public void adjust() {}
}

class Percussion4 extends Instrument4 {
  public void play() {
    System.out.println("Percussion4.play()");
  }
  public String what() { return "Percussion4"; }
  public void adjust() {}
}

class Stringed4 extends Instrument4 {
  public void play() {
    System.out.println("Stringed4.play()");
  }
  public String what() { return "Stringed4"; }
  public void adjust() {}
}

class Brass4 extends Wind4 {
  public void play() {
    System.out.println("Brass4.play()");
  }
  public void adjust() { 
    System.out.println("Brass4.adjust()");
  }
}

class Woodwind4 extends Wind4 {
  public void play() {
    System.out.println("Woodwind4.play()");
  }
  public String what() { return "Woodwind4"; }
}

public class Music4 {
  // Doesn't care about type, so new types
  // added to the system still work right:
  static void tune(Instrument4 i) {
    // ...
    i.play();
  }
  static void tuneAll(Instrument4[] e) {
    for(int i = 0; i < e.length; i++)
      tune(e[i]);
  }
  public static void main(String[] args) {
    Instrument4[] orchestra = new Instrument4[5];
    int i = 0;
    // Upcasting during addition to the array:
    orchestra[i++] = new Wind4();
    orchestra[i++] = new Percussion4();
    orchestra[i++] = new Stringed4();
    orchestra[i++] = new Brass4();
    orchestra[i++] = new Woodwind4();
    tuneAll(orchestra);
  }
} ///:~


可以看出,除基礎類以外,實際並沒有進行什麼改變。
創建抽象類和方法有時對我們非常有用,因為它們使一個類的抽象變成明顯的事實,可明確告訴用戶和編譯器自己打算如何用它。

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved