程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> JAVA編程 >> 關於JAVA >> 周全懂得Java中的外部類和匿名類

周全懂得Java中的外部類和匿名類

編輯:關於JAVA

周全懂得Java中的外部類和匿名類。本站提示廣大學習愛好者:(周全懂得Java中的外部類和匿名類)文章只能為提供參考,不一定能成為您想要的結果。以下是周全懂得Java中的外部類和匿名類正文


Java外部類(Inner Class),相似的概念在C++裡也有,那就是嵌套類(Nested Class),乍看上去外部相似乎有些過剩,它的用途關於初學者來講能夠其實不是那末明顯,然則跟著對它的深刻懂得,你會發明Java的設計者在外部類身上切實其實是居心良苦。學會應用外部類,是控制Java高等編程的一部門,它可讓你更優雅地設計你的法式構造。上面從以下幾個方面來引見:

第一次會晤

public interface Contents {
  int value();
}

public interface Destination {
  String readLabel();
}

public class Goods {
  private class Content implements Contents {
    private int i = 11;
    public int value() {
      return i;
    }
  }

  protected class GDestination implements Destination {
    private String label;
    private GDestination(String whereTo) {
      label = whereTo;
    }
    public String readLabel() {
      return label;
    }
  }

  public Destination dest(String s) {
    return new GDestination(s);
  }
  public Contents cont() {
    return new Content();
  }
}

class TestGoods {
  public static void main(String[] args) {
    Goods p = new Goods();
    Contents c = p.cont();
    Destination d = p.dest("Beijing");
  }
}

在這個例子裡類Content和GDestination被界說在了類Goods外部,而且分離有著protected和private潤飾符來掌握拜訪級別。Content代表著Goods的內容,而GDestination代表著Goods的目標地。它們分離完成了兩個接口Content和Destination。在前面的main辦法裡,直接用Contents c和Destination d停止操作,你乃至連這兩個外部類的名字都沒有看見!如許,外部類的第一個利益就表現出來了——隱蔽你不想讓他人曉得的操作,也即封裝性。

同時,我們也發明了在內部類感化規模以外獲得外部類對象的第一個辦法,那就是應用其內部類的辦法創立並前往。上例中的cont()和dest()辦法就是這麼做的。那末還有無其余辦法呢?固然有,其語法格局以下:

outerObject=new outerClass(Constructor Parameters);

outerClass.innerClass innerObject=outerObject.new InnerClass(Constructor Parameters);

留意在創立非靜態外部類對象時,必定要先創立起響應的內部類對象。至於緣由,也就引出了我們下一個話題——

非靜態外部類對象有著指向其內部類對象的援用

對適才的例子稍作修正:

public class Goods {

  private valueRate=2;

  private class Content implements Contents {
    private int i = 11*valueRate;
    public int value() {
      return i;
    }
  }

  protected class GDestination implements Destination {
    private String label;
    private GDestination(String whereTo) {
      label = whereTo;
    }
    public String readLabel() {
      return label;
    }
  }

  public Destination dest(String s) {
    return new GDestination(s);
  }
  public Contents cont() {
    return new Content();
  }
}

修正的部門用白色顯示了。在這裡我們給Goods類增長了一個private成員變量valueRate,意義是貨色的價值系數,在外部類Content的辦法value()盤算價值時把它乘上。我們發明,value()可以拜訪valueRate,這也是外部類的第二個利益——一個外部類對象可以拜訪創立它的內部類對象的內容,乃至包含公有變量!這是一個異常有效的特征,為我們在設計時供給了更多的思緒和捷徑。要想完成這個功效,外部類對象就必需有指向內部類對象的援用。 Java編譯器在創立外部類對象時,隱式的把其內部類對象的援用也傳了出來並一向保留著。如許就使得外部類對象一直可以拜訪其內部類對象,同時這也是為何在內部類感化規模以外向要創立外部類對象必需先創立其內部類對象的緣由。

有人會問,假如外部類裡的一個成員變量與內部類的一個成員變量同名,也即內部類的同名成員變量被屏障了,怎樣辦?沒事,Java裡用以下格局表達內部類的援用:

outerClass.this

有了它,我們就不怕這類屏障的情形了。

靜態外部類

和通俗的類一樣,外部類也能夠有靜態的。不外和非靜態外部類比擬,差別就在於靜態外部類沒有了指向內部的援用。這現實上和C++中的嵌套類很相像了,Java外部類與C++嵌套類最年夜的分歧就在因而否有指向內部的援用這一點上,固然從設計的角度和以它一些細節來說還有差別。

除此以外,在任何非靜態外部類中,都不克不及有靜態數據,靜態辦法或許又一個靜態外部類(外部類的嵌套可以不止一層)。不外靜態外部類中卻可以具有這一切。這也算是二者的第二個差別吧。

部分外部類

是的,Java外部類也能夠是部分的,它可以界說在一個辦法乃至一個代碼塊以內。

public class Goods1 {
   public Destination dest(String s) {
     class GDestination implements Destination {
        private String label;
        private GDestination(String whereTo) {
          label = whereTo;
        }
        public String readLabel() { return label; }
     }
     return new GDestination(s);
   }

   public static void main(String[] args) {
     Goods1 g= new Goods1();
     Destination d = g.dest("Beijing");
   }
}

下面就是如許一個例子。在辦法dest中我們界說了一個外部類,最初由這個辦法前往這個外部類的對象。假如我們在用一個外部類的時刻僅須要創立它的一個對象並創給內部,便可以如許做。固然,界說在辦法中的外部類可使設計多樣化,用處毫不僅僅在這一點。

上面有一個更怪的例子:

public class Goods2{
   private void internalTracking(boolean b) {
     if(b) {
        class TrackingSlip {
          private String id;
          TrackingSlip(String s) {
             id = s;
          }
          String getSlip() { return id; }
        }
        TrackingSlip ts = new TrackingSlip("slip");
        String s = ts.getSlip();
     }
   }

   public void track() { internalTracking(true); }

   public static void main(String[] args) {
     Goods2 g= new Goods2();
     g.track();
   }
}

你不克不及在if以外創立這個外部類的對象,由於這曾經超越了它的感化域。不外在編譯的時刻,外部類TrackingSlip和其他類一樣同時被編譯,只不外它由它本身的感化域,超越了這個規模就有效,除此以外它和其他外部類並沒有差別。

匿名外部類

java的匿名外部類的語律例則看上去有些怪僻,不外好像匿名數組一樣,當你只須要創立一個類的對象並且用不上它的名字時,應用外部類可使代碼看上去簡練清晰。它的語律例則是如許的:

new interfacename(){......}; 或 new superclassname(){......};

上面接著後面持續舉例子:

public class Goods3 {
   public Contents cont(){
     return new Contents(){
        private int i = 11;
        public int value() {
          return i;
        }
     };
   }
}

這裡辦法cont()應用匿名外部類直接前往了一個完成了接口Contents的類的對象,看上去切實其實非常簡練。

在java的事宜處置的匿名適配器中,匿名外部類被年夜量的應用。例如在想封閉窗口時加上如許一句代碼:

frame.addWindowListener(new WindowAdapter(){
   public void windowClosing(WindowEvent e){
     System.exit(0);
   }
});

有一點須要留意的是,匿名外部類因為沒著名字,所以它沒有結構函數(然則假如這個匿名外部類繼續了一個只含有帶參數結構函數的父類,創立它的時刻必需帶上這些參數,並在完成的進程中應用super症結字挪用響應的內容)。假如你想要初始化它的成員變量,有上面幾種辦法:

假如是在一個辦法的匿名外部類,可以應用這個辦法傳進你想要的參數,不外記住,這些參數必需被聲明為final。

將匿名外部類改革成著名字的部分外部類,如許它便可以具有結構函數了。

在這個匿名外部類中應用初始化代碼塊。

為何須要外部類?

java外部類有甚麼利益?為何須要外部類?

起首舉一個簡略的例子,假如你想完成一個接口,然則這個接口中的一個辦法和你構思的這個類中的一個辦法的稱號,參數雷同,你應當怎樣辦?這時候候,你可以建一個外部類完成這個接口。因為外部類對內部類的一切內容都是可拜訪的,所以如許做可以完成一切你直接完成這個接口的功效。

不外你能夠要質疑,更改一下辦法的不就好了嗎?

切實其實,以此作為設計外部類的來由,其實沒有壓服力。

真實的緣由是如許的,java中的外部類和接口加在一路,可以的處理常被C++法式員埋怨java中存在的一個成績——沒有多繼續。現實上,C++的多繼續設計起來很龐雜,而java經由過程外部類加上接口,可以很好的完成多繼續的後果。

java外部類總結

(1)  在辦法間界說的非靜態外部類:

● 核心類和外部類可相互拜訪本身的公有成員。

● 外部類中不克不及界說靜態成員變量。

在內部類感化規模以外向要創立外部類對象必需先創立其內部類對象

(2) 在辦法間界說的靜態外部類:

● 只能拜訪內部類的靜態成員。

靜態外部類沒有了指向內部的援用

(3) 在辦法中界說的部分外部類:

● 該外部類沒有任何的拜訪掌握權限

● 核心類看不見辦法中的部分外部類的,然則部分外部類可以拜訪核心類的任何成員。

● 辦法體中可以拜訪部分外部類,然則拜訪語句必需在界說部分外部類以後。

● 部分外部類只能拜訪辦法體中的常量,即用final潤飾的成員。

(4) 在辦法中界說的匿名外部類:

● 沒有結構器,取而代之的是將結構器參數傳遞給超類結構器

當你只須要創立一個類的對象並且用不上它的名字時,應用匿名外部類可使代碼看上去簡練清晰。

以上這篇周全懂得Java中的外部類和匿名類就是小編分享給年夜家的全體內容了,願望能給年夜家一個參考,也願望年夜家多多支撐。

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