《Java編程思想》之介面(Java中實現多重繼承?!)

來源:互聯網
上載者:User

1、interface不僅僅只是一個極度抽象的類,因為它允許人們通過建立一個能夠被向上轉型為多種基底類型的類,來實現某種類似C++多重繼承變種的特性。

2、像類一樣,可以在interface關鍵字前面添加public關鍵字(但僅限於該介面在與其同名的檔案中被定義),或者不添加它而使其只是具有包存取權限,這樣它就只能在同一個包內可用。

3、可以選擇在介面中顯示地將方法聲明為public的,但即使你不這麼做,它們也是public的。因此當實現一個介面時,在介面中被定義的方法必須被定義為public

4、Java中,在方法的繼承過程中,其可存取權限不能被降低。

5、介面也可以包含欄位,但是它們隱式為static和final的。

6、因為介面是根本沒有任何具體實現的——也就是說,沒有任何與介面相關的儲存;因此,也就無法阻止多個介面的組合,也就是“多重繼承”。如下例子:

interface CanFight{   void fight();}interface CanSwim{   void swim();}interface CanFly{   void fly();}class ActionCharacter{   public void fight(){      System.out.println("ActionCharacter.fight()");   }}class Hero extends ActionCharacter implements CanFight, CanSwim, CanFly{   public void swim(){      System.out.println("Hero.swim()");   }   public void fly(){      System.out.println("Hero.fly()");   }   /**1.注意CanFight中的fight()方法並沒在這裡定義    * 2.這是因為CanFight介面與ActionCharacter類中的fight()方法的特徵簽名是一樣的。    * 3.所以即使Hero沒有顯式地提供fight()的定義,其定義也因ActionCharacter而隨之而來。    * 4.若把ActionCharacter的fight()改為private,就會出現提示說    *   “類型 Hero必須實現繼承的抽象方法 CanFight.fight()”的錯誤。    * 5.若把ActionCharacter的fight()改為private,就會出現提示說    *   “繼承的方法 ActionCharacter.fight()不能隱藏 CanFight中的公用抽象方法”的錯誤。    */  }public class Adventure{   public static void t(CanFight x){x.fight();}   public static void u(CanSwim x){x.swim();}   public static void v(CanFly x){x.fly();}   public static void w(ActionCharacter x){x.fight();}   public static void main(String[] args){      Hero h = new Hero();      t(h);      u(h);      v(h);      w(h);   }}

運行結果:

1).注意CanFight中的fight()方法並沒有在Hero定義

2).這是因為CanFight介面與ActionCharacter類中的fight()方法的特徵簽名是一樣的。

3).所以即使Hero沒有顯式地提供fight()的定義,其定義也因ActionCharacter而隨之而來。

4).若把ActionCharacter的fight()改為private,就會出現提示說“類型 Hero必須實現繼承的抽象方法CanFight.fight()”的錯誤。

5).若把ActionCharacter的fight()改為private,就會出現提示說“繼承的方法 ActionCharacter.fight()不能隱藏CanFight中的公用抽象方法”的錯誤。

7、以上例子所展示的就是使用介面的核心原因:為了能夠向上轉型為多個基底類型

8、使用介面的第二原因:與使用抽象基類相同,防止用戶端程式員建立該類的對象,並確保這僅僅是建立一個介面。

9、應該使用介面還是抽象類別:當要建立不帶任何方法定義和成員變數的基類時,使用介面。

10、事實上,如果知道某事物應該成為一個基類,那麼第一選擇應該是使它成為一個介面,只有在強制你必須具有方法定義和成員變數時,才應該選擇抽象類別,或者在必要時使其成為一個具體類。

11、介面通過繼承來擴充,如下:

interface Plant{   void grow();}interface Flower extends Plant{   void bloom();}interface Apple extends  Plant, Flower{   void fruit();}class RedApple implements Apple{   public void grow(){      System.out.println("RedApple isgrowing.");   }   public void bloom(){      System.out.println("RedApple isblooming.");   }   public void fruit() {      System.out.println("RedApple isfruiting.");   }}

心細的人可能看到了Apple介面後extends  Plant, Flower。一般情況下,只可以將extends用於單一類,但是既然介面可以由多個其它介面產生,那麼在建立一個新介面時,extends當然可以引用多個基類介面此文法僅適用與介面的繼承。

12、Java中構建如同C++的enum類型那樣具備型別安全(變數的取值被限定在一個有限的範圍內):

public final class Month{   private String name;   //private構造器,無法建立它的任何執行個體,所有執行個體都是在類的內部有其身建立的finalstatic執行個體   private Month(String name){      this.name = name;   }   public String toString(){      return name;   }   public static final Month      JAN = new Month("January"),      FEB   = new Month("February"),      MAR   = new Month("March"),      APR   = new Month("April"),      MAY   = new Month("May"),      JUN   = new Month("June"),      JUL   = new Month("July"),      AUG   = new Month("August"),      SEP   = new Month("September"),      OCT   = new Month("October"),      NOV   = new Month("November"),      DEC   = new Month("December");   public static final Month[] month = {      JAN, FEB, MAR, APR, MAY, JUN, JUL, AUG, SEP, OCT, NOV, DEC   };   public static final Month number(int order){      return month[order - 1];   }   public static void main(String[] args){      //curMonth是一個Month對象,它僅可以被賦予一個Month對象。這就體現了型別安全。      Month curMonth = Month.JAN;      System.out.println(curMonth);      curMonth = Month.number(12);      System.out.println(curMonth);      //這種方式同樣也允許你可互換地使用==或equal(),因為Month的每一個值都僅有一個執行個體。      System.out.println(curMonth == Month.DEC);      System.out.println(curMonth.equals(Month.DEC));      System.out.println(Month.month[3]);   }}

運行結果:

13、介面可以嵌套在類或其他介面中。嵌套介面可以擁有public和“包訪問”兩種可視性。同時,public和包訪問的嵌套介面都可以被實現為public、包訪問以及private的嵌套類。

class A{   interface B{      void fromB();   }   interface D{      void fromD();   }   //嵌套介面可以是private存取權限。   //它帶來的好處是:強制介面中的方法定義不要添加任何類型資訊(也就是說,不允許向上轉型),不明白,請看看最後的解說。   private interface I{      void fromI();   }   //private的嵌套介面可以被實現為private   private class J implements I{      public void fromI() {        System.out.println("E.J.fromI()");      }   }   //private的嵌套介面也可以被實現為public   public class J1 implements I{      public void fromI() {        System.out.println("E.J1.fromI()");      }   }   //結合getI()和setI()方法實現“向上轉型”?!   public I getI(){      return new J1();   }   public void setI(I i){      i.fromI();   }   //介面之間可以嵌套,嵌套在另一個介面中的介面只能是public的   interface K{      interface L{//此處也預設是public的        void fromL();      }   }}public class E implements A.D{   public void fromD() {      System.out.println("E.fromD()");   }   //內部類F public   public class F implements A.B{      public void fromB() {        System.out.println("E.F.fromB()");      }   }   //內部類G protected   protected class G implements A.B{      public void fromB() {        System.out.println("E.G.fromB()");      }   }   //內部類I private   private class H implements A.B{      public void fromB() {        System.out.println("E.I.fromB()");      }   }   public static void main(String[] args){      E e = new E();      e.fromD();      //內部的執行個體化      E.F f = e.new F();      f.fromB();           E.G g = e.new G();      g.fromB();           E.H h = e.new H();      h.fromB();      //"實現了private介面I"的"public類J1"的執行個體化。      A.J1 j1 = new A().new J1();      j1.fromI();           A a = new A();      //A.I i = a.getI();//類型 A.I 不可視      //A.J1 j = a.getI();//不能從 A.I轉換為 A.J1      //a.getI().fromI();//類型 A.I 不可視      a.setI(a.getI());   }}

運行結果:

getI(),返回private介面的引用的public方法。在main()中,數次使用傳回值的行為都失敗了。只有一種方式可以成功,那就是將傳回值交給有權使用它的對象。在上例中,是一個A的對象a同過setI()方法來實現的。

以上內容整理自《Java編程思想》,如有遺漏,請您不吝指出!


聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.