最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

詳解Java內(nèi)部類——匿名內(nèi)部類

 更新時間:2020年08月21日 10:13:42   作者:弗蘭克的貓  
這篇文章主要介紹了詳解Java 匿名內(nèi)部類的相關(guān)資料,幫助大家更好的理解和學(xué)習(xí)java 內(nèi)部類的相關(guān)知識,感興趣的朋友可以了解下

  今天來看看另一個更加神奇的類——匿名內(nèi)部類。

  就像它的名字表示的那樣,這個類是匿名的,用完之后,深藏功與名,就像掃地僧那樣默默潛藏于深山之中。匿名內(nèi)部類不僅沒有名字,連class關(guān)鍵字都省掉了,而且匿名內(nèi)部類必須繼承于某個類或者實現(xiàn)某個接口,長的就像這樣:

new 父類(參數(shù)列表)|實現(xiàn)接口() {  
     //匿名內(nèi)部類的內(nèi)部定義
    } 

  來看一個栗子:

public abstract class Human {
  public abstract void walk();
}

  這是一個抽象類,如果使用匿名內(nèi)部類來繼承的話是這樣的:

public class AnonymousTest {
  public static void main(String[] args) {
    Human human = new Human(){
      public void walk(){
        System.out.println("AnonymousHuman can walk.");
      };
    };
    human.walk();
  }
}

  簡單粗暴,看起來就像局部內(nèi)部類的簡化版。如果不使用匿名內(nèi)部類,會是怎樣呢?

  我們需要先創(chuàng)建一個類來繼承這抽象類:

public class Man extends Human {
  @Override
  public void walk() {
    System.out.println("Man can walk.");
  }
}

  然后再來使用這個類:

public class AnonymousTest {
  public static void main(String[] args) {
    Human human = new Man();
    human.walk();
  }
}

  因為一個單獨的類往往放在一個單獨的文件中,如果這個類只需要創(chuàng)建一個對象,那未免有些大材小用了,從上面的栗子可以比較出匿名內(nèi)部類的一個優(yōu)勢:在類只需要創(chuàng)建一個對象的情況下更加簡單方便。

  再舉一個實際一點的栗子:

public class AnonymousTest {
  public static void main(String[] args) {
    Thread t = new Thread() {
      public void run() {
        for (int i = 0; i < 10; i++) {
          try {
            sleep(1000);
          } catch (InterruptedException e) {
            e.printStackTrace();
          }
          System.out.println(i);
        }
      }
    };
    t.start();
  }
}

  這里創(chuàng)建了一個繼承于Thread的匿名內(nèi)部類,覆蓋了其中的 run方法,并創(chuàng)建了一個實例返回給了t,然后再調(diào)用run方法,可以看到,匿名內(nèi)部類只能存在一個實例對象,因為new過一次就無法再創(chuàng)建了,也許會覺得局部內(nèi)部類已經(jīng)很局限了,為什么要出現(xiàn)比局部內(nèi)部類適用范圍更小的匿名內(nèi)部類?、

  這你就不懂了吧,在Java的實際使用中,匿名內(nèi)部類大有用處,為什么要使用匿名內(nèi)部類呢?

  有時候,我們創(chuàng)建的類只需要一個實例,比如說在多線程中,要使用多線程,一般先繼承Thread類或者實現(xiàn)Runnable接口,然后再去調(diào)用它的方法,而每個任務(wù)一般都不一樣,每次都新建一個類顯然會很難管理,因為每個類只用一次就丟掉了,這個時候使用匿名內(nèi)部類就很方便了,不僅不需要管理一堆一次性類,而且創(chuàng)建起來簡單粗暴。就像上述栗子,還能簡化成這樣:

public class AnonymousTest {
  public static void main(String[] args) {
    new Thread() {
      public void run() {
        for (int i = 0; i < 10; i++) {
          try {
            sleep(1000);
          } catch (InterruptedException e) {
            e.printStackTrace();
          }
          System.out.println(i);
        }
      }
    }.start();
  }
}

  創(chuàng)建實例后直接調(diào)用run方法,簡單粗暴。

  匿名內(nèi)部類不僅可以繼承于類,也可以實現(xiàn)于接口,比如說這樣:

public class AnonymousTest {
  public static void main(String[] args) {
    new Thread(new Runnable() {
      public void run() {
        for (int i = 0; i < 10; i++) {
          try {
            sleep(1000);
          } catch (InterruptedException e) {
            e.printStackTrace();
          }
          System.out.println(i);
        }
      }
    }).start();
  }
}

  當(dāng)然,還有些不得不用內(nèi)部類的情況,類只能繼承于一個類,如果一個類需要使用到另一個包中的另一個類的一個protected方法,卻已經(jīng)繼承于另一個類,那么這個時候就不得不用內(nèi)部類來解決了。

  比如說,還有一個Woman(女人)類:

public class Woman {
  protected void dance(){
    System.out.println("Woman can dance.");
  }
}

  這個時候,如果Man(男人)也難不住寂寞,想要dance(跳舞)一下,那該怎么辦呢?繼承Woman類?顯然不合乎邏輯,而且也無法實現(xiàn),因為已經(jīng)繼承于Human類了,但就是想要dance,該怎么辦?

  內(nèi)部類的出現(xiàn)讓這個問題變得很簡單:

public class Man extends Human {
  @Override
  public void walk() {
    System.out.println("Man can walk.");
  }

  public void dance(){
    new Woman(){
      public void manDance(){
        super.dance();
      }
    }.manDance();
  }
}

  因為在不同的包下,不能直接使用Woman的dance方法,但是可以用內(nèi)部類來繼承,從而調(diào)用protected方法,然后再放入Man的方法中,這樣,Man也能像Woman一樣dance了:

public class AnonymousTest {
  public static void main(String[] args) {
    Man human = new Man();
    human.walk();
    human.dance();
  }
}

  當(dāng)然,使用匿名內(nèi)部類還是有很多限制的:

  1、匿名內(nèi)部類必須是繼承一個類或者實現(xiàn)一個接口,但是兩者不可兼得,同時也只能繼承一個類或者實現(xiàn)一個接口。

2、匿名內(nèi)部類不能定義構(gòu)造函數(shù)。

3、匿名內(nèi)部類中不能存在任何的靜態(tài)成員變量和靜態(tài)方法。

4、匿名內(nèi)部類是特殊的局部內(nèi)部類,所以局部內(nèi)部類的所有限制同樣對匿名內(nèi)部類生效。

5、匿名內(nèi)部類不能是抽象的,它必須要實現(xiàn)繼承的類或者實現(xiàn)的接口的所有抽象方法。

  那么問題來了,怎樣初始化一個匿名內(nèi)部類呢?畢竟匿名內(nèi)部類是不能有構(gòu)造器的。

  當(dāng)然,首先,還是可以使用初始化塊來實現(xiàn)的,就像這樣:

public class AnonymousTest {
  public static void main(String[] args) {
    Human human = new Human() {
      private String name;
      {
        name = "human";
      }
      @Override
      public void walk() {
        System.out.println(name + " walk.");
      }
    };
    human.walk();
  }
}

  但是這樣顯然就比較呆板,不夠靈活,無法接受外部參數(shù),那么怎樣靈活使用呢?不要心急,方法總比問題多,還是有辦法解決的:

public class AnonymousTest {
  public static void main(String[] args) {
    Human human = new AnonymousTest().getHumanInstance("Frank");
    human.walk();
  }

  public Human getHumanInstance(final String name){
    return new Human() {
      private String nameA;
      {
        nameA = name;
      }
      @Override
      public void walk() {
        System.out.println(nameA + " walk.");
      }
    };
  }
}

  這里利用初始化塊來對匿名內(nèi)部類進行初始化,注意,如果匿名內(nèi)部類需要使用外部的參數(shù)或者變量,那么必須使用final修飾,因為內(nèi)部類使用的其實是參數(shù)的拷貝,并不是參數(shù)本身,為了更明顯的表明參數(shù)不可變,編譯器會要求使用final關(guān)鍵字來修飾需要使用的變量。

  至此,匿名內(nèi)部類講解完畢,歡迎大家繼續(xù)關(guān)注!

以上就是詳解Java內(nèi)部類——匿名內(nèi)部類的詳細內(nèi)容,更多關(guān)于Java 匿名內(nèi)部類的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • 如何使用MybatisPlus快速進行增刪改查詳解

    如何使用MybatisPlus快速進行增刪改查詳解

    增刪改查在日常開發(fā)中是再正常不多的一個需求了,下面這篇文章主要給大家介紹了關(guān)于如何使用MybatisPlus快速進行增刪改查的相關(guān)資料,文中通過實例代碼介紹的非常詳細,需要的朋友可以參考下
    2022-08-08
  • Java動態(tài)腳本Groovy獲取Bean技巧

    Java動態(tài)腳本Groovy獲取Bean技巧

    這篇文章主要給大家分享的是Java動態(tài)腳本Groovy獲取Bean技巧,在Java代碼中當(dāng)我們需要一個Bean對象,通常會使用spring中@Autowired注解,用來自動裝配對象。下面我們一起進入文章學(xué)習(xí)個表格多 詳細內(nèi)容吧

    2021-12-12
  • Java中堆和棧的概念和區(qū)別

    Java中堆和棧的概念和區(qū)別

    Java的堆是一個運行時數(shù)據(jù)區(qū),類的對象從堆中分配空間。棧中主要存放一些基本數(shù)據(jù)類型的變量(byte,short,int,long,float,double,boolean,char)和對象的引用,這篇文章給大家詳細介紹java 堆和棧的概念和區(qū)別,一起看看吧
    2020-06-06
  • 使用Java Servlet生成動態(tài)二維碼的實現(xiàn)步驟

    使用Java Servlet生成動態(tài)二維碼的實現(xiàn)步驟

    在現(xiàn)代互聯(lián)網(wǎng)時代,二維碼廣泛應(yīng)用于各個領(lǐng)域,包括支付、認證、信息傳遞等,在Web開發(fā)中,通過Java Servlet生成動態(tài)二維碼是一個常見的需求,本文將介紹如何使用Java Servlet結(jié)合Google的ZXing庫生成動態(tài)二維碼,需要的朋友可以參考下
    2023-11-11
  • Java面試題沖刺第十三天--數(shù)據(jù)庫(3)

    Java面試題沖刺第十三天--數(shù)據(jù)庫(3)

    這篇文章主要為大家分享了最有價值的三道數(shù)據(jù)庫面試題,涵蓋內(nèi)容全面,包括數(shù)據(jù)結(jié)構(gòu)和算法相關(guān)的題目、經(jīng)典面試編程題等,感興趣的小伙伴們可以參考一下
    2021-07-07
  • Java輕松生成5位隨機數(shù)

    Java輕松生成5位隨機數(shù)

    這篇文章主要介紹了Java輕松生成5位隨機數(shù)的相關(guān)資料,需要的朋友可以參考下
    2023-10-10
  • SpringBoot整合redis實現(xiàn)輸入密碼錯誤限制登錄功能

    SpringBoot整合redis實現(xiàn)輸入密碼錯誤限制登錄功能

    遇到這樣的需求需要實現(xiàn)一個登錄功能,并且2分鐘之內(nèi)只能輸入5次錯誤密碼,若輸入五次之后還沒有輸入正確密碼,系統(tǒng)將會將該賬號鎖定1小時,這篇文章主要介紹了SpringBoot整合redis并實現(xiàn)輸入密碼錯誤限制登錄功能,需要的朋友可以參考下
    2024-02-02
  • Java實現(xiàn)合并多個PDF的示例代碼

    Java實現(xiàn)合并多個PDF的示例代碼

    這篇文章主要介紹了通過Java實現(xiàn)合并多個PDF,并將合并后的新PDF存儲到文件夾下,文中的示例代碼簡潔易懂,感興趣的可以跟隨小編一起試一試
    2022-01-01
  • 利用Java如何獲取Mybatis動態(tài)生成的sql接口實現(xiàn)

    利用Java如何獲取Mybatis動態(tài)生成的sql接口實現(xiàn)

    MyBatis 的強大特性之一便是它的動態(tài)SQL,下面這篇文章主要給大家介紹了關(guān)于利用Java如何獲取Mybatis動態(tài)生成的sql接口實現(xiàn)的相關(guān)資料,文中通過實例代碼介紹的非常詳細,需要的朋友可以參考下
    2022-01-01
  • 解決java.lang.ClassCastException的java類型轉(zhuǎn)換異常的問題

    解決java.lang.ClassCastException的java類型轉(zhuǎn)換異常的問題

    這篇文章主要介紹了解決java.lang.ClassCastException的java類型轉(zhuǎn)換異常的問題,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2020-09-09

最新評論

西丰县| 秦皇岛市| 北海市| 集安市| 汶上县| 余江县| 营口市| 上栗县| 安福县| 万山特区| 托克托县| 古浪县| 罗田县| 逊克县| 化德县| 武邑县| 东丰县| 临漳县| 巫溪县| 南郑县| 铜鼓县| 齐河县| 兴仁县| 长岛县| 方正县| 右玉县| 卢龙县| 堆龙德庆县| 双辽市| 昌都县| 安达市| 宜昌市| 万安县| 静宁县| 通辽市| 安溪县| 嘉黎县| 光泽县| 卓尼县| 贵港市| 沐川县|