欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

java 內部類的實例詳解

 更新時間:2017年09月20日 16:46:31   投稿:lqh  
這篇文章主要介紹了java 內部類的實例詳解的相關資料,希望通過本文大家能夠理解掌握java內部類的使用,需要的朋友可以參考下

java 內部類的實例詳解

可以將一個類的定義放在另一個類的定義內部,這就是內部類。

內部類是一個非常有用的特性但又比較難理解使用的特性(鄙人到現在都沒有怎么使用過內部類,對內部類也只是略知一二)。

第一次見面

內部類我們從外面看是非常容易理解的,無非就是在一個類的內部在定義一個類。

public class OuterClass {
  private String name ;
  private int age;

  public String getName() {
    return name;
  }

  public void setName(String name) {
    this.name = name;
  }

  public int getAge() {
    return age;
  }

  public void setAge(int age) {
    this.age = age;
  }

  class InnerClass{
    public InnerClass(){
      name = "chenssy";
      age = 23;
    }
  }
}

在這里InnerClass就是內部類,對于初學者來說內部類實在是使用的不多,鄙人菜鳥一個同樣沒有怎么使用過(貌似僅僅只在做swing 注冊事件中使用過),但是隨著編程能力的提高,我們會領悟到它的魅力所在,它可以使用能夠更加優(yōu)雅的設計我們的程序結構。在使用內部類之間我們需要明白為什么要使用內部類,內部類能夠為我們帶來什么樣的好處。

一、為什么要使用內部類

為什么要使用內部類?在《Think in java》中有這樣一句話:使用內部類最吸引人的原因是:每個內部類都能獨立地繼承一個(接口的)實現,所以無論外圍類是否已經繼承了某個(接口的)實現,對于內部類都沒有影響。

在我們程序設計中有時候會存在一些使用接口很難解決的問題,這個時候我們可以利用內部類提供的、可以繼承多個具體的或者抽象的類的能力來解決這些程序設計問題??梢赃@樣說,接口只是解決了部分問題,而內部類使得多重繼承的解決方案變得更加完整。

public interface Father {

}

public interface Mother {

}

public class Son implements Father, Mother {

}

public class Daughter implements Father{

  class Mother_ implements Mother{

  }
}

其實對于這個實例我們確實是看不出來使用內部類存在何種優(yōu)點,但是如果Father、Mother不是接口,而是抽象類或者具體類呢?這個時候我們就只能使用內部類才能實現多重繼承了。

其實使用內部類最大的優(yōu)點就在于它能夠非常好的解決多重繼承的問題,但是如果我們不需要解決多重繼承問題,那么我們自然可以使用其他的編碼方式,但是使用內部類還能夠為我們帶來如下特性(摘自《Think in java》):

  1、內部類可以用多個實例,每個實例都有自己的狀態(tài)信息,并且與其他外圍對象的信息相互獨立。

  2、在單個外圍類中,可以讓多個內部類以不同的方式實現同一個接口,或者繼承同一個類。

  3、創(chuàng)建內部類對象的時刻并不依賴于外圍類對象的創(chuàng)建。

  4、內部類并沒有令人迷惑的“is-a”關系,他就是一個獨立的實體。

  5、內部類提供了更好的封裝,除了該外圍類,其他類都不能訪問。

二、內部類基礎

在這個部分主要介紹內部類如何使用外部類的屬性和方法,以及使用.this與.new。

當我們在創(chuàng)建一個內部類的時候,它無形中就與外圍類有了一種聯(lián)系,依賴于這種聯(lián)系,它可以無限制地訪問外圍類的元素。

public class OuterClass {
  private String name ;
  private int age;

  /**省略getter和setter方法**/

  public class InnerClass{
    public InnerClass(){
      name = "chenssy";
      age = 23;
    }

    public void display(){
      System.out.println("name:" + getName() +"  ;age:" + getAge());
    }
  }

  public static void main(String[] args) {
    OuterClass outerClass = new OuterClass();
    OuterClass.InnerClass innerClass = outerClass.new InnerClass();
    innerClass.display();
  }
}
--------------
Output:
name:chenssy  ;age:23

在這個應用程序中,我們可以看到內部了InnerClass可以對外圍類OuterClass的屬性進行無縫的訪問,盡管它是private修飾的。這是因為當我們在創(chuàng)建某個外圍類的內部類對象時,此時內部類對象必定會捕獲一個指向那個外圍類對象的引用,只要我們在訪問外圍類的成員時,就會用這個引用來選擇外圍類的成員。

其實在這個應用程序中我們還看到了如何來引用內部類:引用內部類我們需要指明這個對象的類型:OuterClasName.InnerClassName。同時如果我們需要創(chuàng)建某個內部類對象,必須要利用外部類的對象通過.new來創(chuàng)建內部類: OuterClass.InnerClass innerClass = outerClass.new InnerClass();。

同時如果我們需要生成對外部類對象的引用,可以使用OuterClassName.this,這樣就能夠產生一個正確引用外部類的引用了。當然這點實在編譯期就知曉了,沒有任何運行時的成本。

/**
 * Java學習交流QQ群:589809992 我們一起學Java!
 */
public class OuterClass {
  public void display(){
    System.out.println("OuterClass...");
  }

  public class InnerClass{
    public OuterClass getOuterClass(){
      return OuterClass.this;
    }
  }

  public static void main(String[] args) {
    OuterClass outerClass = new OuterClass();
    OuterClass.InnerClass innerClass = outerClass.new InnerClass();
    innerClass.getOuterClass().display();
  }
}
-------------
Output:
OuterClass...

到這里了我們需要明確一點,內部類是個編譯時的概念,一旦編譯成功后,它就與外圍類屬于兩個完全不同的類(當然他們之間還是有聯(lián)系的)。對于一個名為OuterClass的外圍類和一個名為InnerClass的內部類,在編譯成功后,會出現這樣兩個class文件:OuterClass.class和OuterClass$InnerClass.class。

在Java中內部類主要分為成員內部類、局部內部類、匿名內部類、靜態(tài)內部類。

三、成員內部類

成員內部類也是最普通的內部類,它是外圍類的一個成員,所以他是可以無限制的訪問外圍類的所有 成員屬性和方法,盡管是private的,但是外圍類要訪問內部類的成員屬性和方法則需要通過內部類實例來訪問。

在成員內部類中要注意兩點,第一:成員內部類中不能存在任何static的變量和方法;第二:成員內部類是依附于外圍類的,所以只有先創(chuàng)建了外圍類才能夠創(chuàng)建內部類。

public class OuterClass {
  private String str;

  public void outerDisplay(){
    System.out.println("outerClass...");
  }

  public class InnerClass{
    public void innerDisplay(){
      //使用外圍內的屬性
      str = "chenssy...";
      System.out.println(str);
      //使用外圍內的方法
      outerDisplay();
    }
  }

  /*推薦使用getxxx()來獲取成員內部類,尤其是該內部類的構造函數無參數時 */
  public InnerClass getInnerClass(){
    return new InnerClass();
  }

  public static void main(String[] args) {
    OuterClass outer = new OuterClass();
    OuterClass.InnerClass inner = outer.getInnerClass();
    inner.innerDisplay();
  }
}
--------------------
chenssy...
outerClass...

推薦使用getxxx()來獲取成員內部類,尤其是該內部類的構造函數無參數時 。

四、局部內部類

有這樣一種內部類,它是嵌套在方法和作用于內的,對于這個類的使用主要是應用與解決比較復雜的問題,想創(chuàng)建一個類來輔助我們的解決方案,到那時又不希望這個類是公共可用的,所以就產生了局部內部類,局部內部類和成員內部類一樣被編譯,只是它的作用域發(fā)生了改變,它只能在該方法和屬性中被使用,出了該方法和屬性就會失效。

對于局部內部類實在是想不出什么好例子,所以就引用《Think in java》中的經典例子了。

定義在方法里:

/**
 * Java學習交流QQ群:589809992 我們一起學Java!
 */
public class Parcel5 {
  public Destionation destionation(String str){
    class PDestionation implements Destionation{
      private String label;
      private PDestionation(String whereTo){
        label = whereTo;
      }
      public String readLabel(){
        return label;
      }
    }
    return new PDestionation(str);
  }

  public static void main(String[] args) {
    Parcel5 parcel5 = new Parcel5();
    Destionation d = parcel5.destionation("chenssy");
  }
}

定義在作用域內:

public class Parcel6 {
  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("chenssy");
      String string = ts.getSlip();
    }
  }

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

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

五、匿名內部類

在做Swing編程中,我們經常使用這種方式來綁定事件

button2.addActionListener( 
        new ActionListener(){ 
          public void actionPerformed(ActionEvent e) { 
            System.out.println("你按了按鈕二"); 
          } 
        });

我們咋一看可能覺得非常奇怪,因為這個內部類是沒有名字的,在看如下這個例子:

/**
 * Java學習交流QQ群:589809992 我們一起學Java!
 */
public class OuterClass {
  public InnerClass getInnerClass(final int num,String str2){
    return new InnerClass(){
      int number = num + 3;
      public int getNumber(){
        return number;
      }
    };    /* 注意:分號不能省 */
  }

  public static void main(String[] args) {
    OuterClass out = new OuterClass();
    InnerClass inner = out.getInnerClass(2, "chenssy");
    System.out.println(inner.getNumber());
  }
}

interface InnerClass {
  int getNumber();
}

----------------
Output:

這里我們就需要看清幾個地方

1、 匿名內部類是沒有訪問修飾符的。

2、 new 匿名內部類,這個類首先是要存在的。如果我們將那個InnerClass接口注釋掉,就會出現編譯出錯。

3、 注意getInnerClass()方法的形參,第一個形參是用final修飾的,而第二個卻沒有。同時我們也發(fā)現第二個形參在匿名內部類中沒有使用過,所以當所在方法的形參需要被匿名內部類使用,那么這個形參就必須為final。

4、 匿名內部類是沒有構造方法的。因為它連名字都沒有何來構造方法。

PS:由于篇幅有限,對匿名內部類就介紹到這里,有關更多關于匿名內部類的知識,我就會在下篇博客(java提高篇—–詳解匿名內部類)做詳細的介紹,包括為何形參要定義成final,怎么對匿名內部類進行初始化等等,敬請期待……

六、靜態(tài)內部類

在java提高篇——關鍵字static中提到Static可以修飾成員變量、方法、代碼塊,其他它還可以修飾內部類,使用static修飾的內部類我們稱之為靜態(tài)內部類,不過我們更喜歡稱之為嵌套內部類。靜態(tài)內部類與非靜態(tài)內部類之間存在一個最大的區(qū)別,我們知道非靜態(tài)內部類在編譯完成之后會隱含地保存著一個引用,該引用是指向創(chuàng)建它的外圍內,但是靜態(tài)內部類卻沒有。沒有這個引用就意味著:

1、 它的創(chuàng)建是不需要依賴于外圍類的。

2、 它不能使用任何外圍類的非static成員變量和方法。

/**
 * Java學習交流QQ群:589809992 我們一起學Java!
 */
public class OuterClass {
  private String sex;
  public static String name = "chenssy";

  /**
   *靜態(tài)內部類
   */
  static class InnerClass1{
    /* 在靜態(tài)內部類中可以存在靜態(tài)成員 */
    public static String _name1 = "chenssy_static";

    public void display(){
      /* 
       * 靜態(tài)內部類只能訪問外圍類的靜態(tài)成員變量和方法
       * 不能訪問外圍類的非靜態(tài)成員變量和方法
       */
      System.out.println("OutClass name :" + name);
    }
  }

  /**
   * 非靜態(tài)內部類
   */
  class InnerClass2{
    /* 非靜態(tài)內部類中不能存在靜態(tài)成員 */
    public String _name2 = "chenssy_inner";
    /* 非靜態(tài)內部類中可以調用外圍類的任何成員,不管是靜態(tài)的還是非靜態(tài)的 */
    public void display(){
      System.out.println("OuterClass name:" + name);
    }
  }

  /**
   * @desc 外圍類方法
   * @author chenssy
   * @data 2013-10-25
   * @return void
   */
  public void display(){
    /* 外圍類訪問靜態(tài)內部類:內部類. */
    System.out.println(InnerClass1._name1);
    /* 靜態(tài)內部類 可以直接創(chuàng)建實例不需要依賴于外圍類 */
    new InnerClass1().display();

    /* 非靜態(tài)內部的創(chuàng)建需要依賴于外圍類 */
    OuterClass.InnerClass2 inner2 = new OuterClass().new InnerClass2();
    /* 方位非靜態(tài)內部類的成員需要使用非靜態(tài)內部類的實例 */
    System.out.println(inner2._name2);
    inner2.display();
  }

  public static void main(String[] args) {
    OuterClass outer = new OuterClass();
    outer.display();
  }
}
----------------
Output:
chenssy_static
OutClass name :chenssy
chenssy_inner
OuterClass name:chenssy

上面這個例子充分展現了靜態(tài)內部類和非靜態(tài)內部類的區(qū)別。

到這里內部類的介紹就基本結束了!對于內部類其實本人認識也只是皮毛,逼近菜鳥一枚,認知有限!我會利用這幾天時間好好研究內部類!

如有疑問請留言或者到本站社區(qū)交流討論,感謝閱讀,希望能幫助到大家,謝謝大家對本站的支持!

相關文章

  • Java Math類的三個方法ceil,floor,round用法

    Java Math類的三個方法ceil,floor,round用法

    這篇文章主要介紹了Java Math類的三個方法ceil,floor,round用法,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-07-07
  • maven繼承父工程統(tǒng)一版本號的實現

    maven繼承父工程統(tǒng)一版本號的實現

    這篇文章主要介紹了maven繼承父工程統(tǒng)一版本號的實現,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2020-08-08
  • Java中關于線程安全的三種解決方式

    Java中關于線程安全的三種解決方式

    這篇文章主要介紹了Java中關于線程安全的三種解決方式,本文給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2021-09-09
  • Java面向對象之單例設計模式詳解

    Java面向對象之單例設計模式詳解

    這篇文章主要介紹了Java面向對象之單例設計模式詳解,所謂類的單例設計模式,就是采取一定的方法保證在整個的軟件系統(tǒng)中,對某個類只能存在一個對象實例,并且該類只提供一個取得其對象實例的方法,需要的朋友可以參考下
    2024-01-01
  • 教你怎么用Java數組和鏈表實現棧

    教你怎么用Java數組和鏈表實現棧

    本篇文章為大家詳細介紹了怎么用Java數組和鏈表實現棧,文中有非常詳細的代碼示例及注釋,對正在學習java的小伙伴們很有幫助,需要的朋友可以參考下
    2021-05-05
  • 基于Luhn算法的銀行卡校驗規(guī)則

    基于Luhn算法的銀行卡校驗規(guī)則

    這篇文章主要為大家介紹了基于Luhn算法的銀行卡校驗規(guī)則,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2022-05-05
  • Spring底層原理深入分析

    Spring底層原理深入分析

    Spring框架是一個開放源代碼的J2EE應用程序框架,由Rod Johnson發(fā)起,是針對bean的生命周期進行管理的輕量級容器(lightweight container)。 Spring解決了開發(fā)者在J2EE開發(fā)中遇到的許多常見的問題,提供了功能強大IOC、AOP及Web MVC等功能
    2022-07-07
  • Java中ArrayList刪除的常用操作及方法

    Java中ArrayList刪除的常用操作及方法

    ArrayList是最常用的一種java集合,在開發(fā)中我們常常需要從ArrayList中刪除特定元素,本文主要介紹了Java中ArrayList刪除的常用操作及方法,感興趣的可以了解一下
    2023-11-11
  • Spring中的ClassPathXmlApplicationContext源碼詳解

    Spring中的ClassPathXmlApplicationContext源碼詳解

    這篇文章主要介紹了Spring中的ClassPathXmlApplicationContext源碼詳解,ApplicationContext的主要實現類是ClassPathXmlApplicationContext和FileSystemXmlApplicationContext,前者默認從類路徑加載配置文件,后者默認從文件系統(tǒng)中裝載配置文件,需要的朋友可以參考下
    2023-12-12
  • idea插件在線和離線安裝方法

    idea插件在線和離線安裝方法

    這篇文章主要介紹了idea插件在線和離線安裝方法,文末補充介紹了IntelliJ IDEA 安裝mybaits當前運行sql日志插件在線與離線安裝方法
    ,感興趣的朋友一起看看吧
    2023-12-12

最新評論