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

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

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

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

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

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

  來(lái)看一個(gè)栗子:

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

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

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

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

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

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

  然后再來(lái)使用這個(gè)類(lèi):

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

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

  再舉一個(gè)實(shí)際一點(diǎn)的栗子:

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)建了一個(gè)繼承于Thread的匿名內(nèi)部類(lèi),覆蓋了其中的 run方法,并創(chuàng)建了一個(gè)實(shí)例返回給了t,然后再調(diào)用run方法,可以看到,匿名內(nèi)部類(lèi)只能存在一個(gè)實(shí)例對(duì)象,因?yàn)閚ew過(guò)一次就無(wú)法再創(chuàng)建了,也許會(huì)覺(jué)得局部?jī)?nèi)部類(lèi)已經(jīng)很局限了,為什么要出現(xiàn)比局部?jī)?nèi)部類(lèi)適用范圍更小的匿名內(nèi)部類(lèi)?、

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

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

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)建實(shí)例后直接調(diào)用run方法,簡(jiǎn)單粗暴。

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

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)部類(lèi)的情況,類(lèi)只能繼承于一個(gè)類(lèi),如果一個(gè)類(lèi)需要使用到另一個(gè)包中的另一個(gè)類(lèi)的一個(gè)protected方法,卻已經(jīng)繼承于另一個(gè)類(lèi),那么這個(gè)時(shí)候就不得不用內(nèi)部類(lèi)來(lái)解決了。

  比如說(shuō),還有一個(gè)Woman(女人)類(lèi):

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

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

  內(nèi)部類(lèi)的出現(xiàn)讓這個(gè)問(wèn)題變得很簡(jiǎ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();
  }
}

  因?yàn)樵诓煌陌?,不能直接使用Woman的dance方法,但是可以用內(nèi)部類(lèi)來(lá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)部類(lèi)還是有很多限制的:

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

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

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

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

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

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

  當(dāng)然,首先,還是可以使用初始化塊來(lái)實(shí)現(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();
  }
}

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

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.");
      }
    };
  }
}

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

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

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

相關(guān)文章

  • Spark學(xué)習(xí)筆記之Spark SQL的具體使用

    Spark學(xué)習(xí)筆記之Spark SQL的具體使用

    這篇文章主要介紹了Spark學(xué)習(xí)筆記之Spark SQL的具體使用,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2019-06-06
  • Java多線(xiàn)程并發(fā)生產(chǎn)者消費(fèi)者設(shè)計(jì)模式實(shí)例解析

    Java多線(xiàn)程并發(fā)生產(chǎn)者消費(fèi)者設(shè)計(jì)模式實(shí)例解析

    這篇文章主要介紹了Java多線(xiàn)程并發(fā)生產(chǎn)者消費(fèi)者設(shè)計(jì)模式實(shí)例解析,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-03-03
  • 用Java實(shí)現(xiàn)連連看小游戲

    用Java實(shí)現(xiàn)連連看小游戲

    這篇文章主要為大家詳細(xì)介紹了用Java實(shí)現(xiàn)連連看小游戲,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2022-05-05
  • Java中JVM的雙親委派、內(nèi)存溢出、垃圾回收和調(diào)優(yōu)詳解

    Java中JVM的雙親委派、內(nèi)存溢出、垃圾回收和調(diào)優(yōu)詳解

    這篇文章主要介紹了Java中JVM的雙親委派、內(nèi)存溢出、垃圾回收和調(diào)優(yōu)詳解,類(lèi)加載器是Java虛擬機(jī)(JVM)的一個(gè)重要組成部分,它的主要作用是將類(lèi)的字節(jié)碼加載到內(nèi)存中,并生成對(duì)應(yīng)的Class對(duì)象,需要的朋友可以參考下
    2023-07-07
  • SpringBoot使用SOFA-Lookout監(jiān)控的方法

    SpringBoot使用SOFA-Lookout監(jiān)控的方法

    本文介紹SpringBoot使用螞蟻金服SOFA-Lookout配合Prometheus進(jìn)行監(jiān)控,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2019-03-03
  • Spring的自動(dòng)裝配常用注解詳解

    Spring的自動(dòng)裝配常用注解詳解

    這篇文章主要介紹了Spring的自動(dòng)裝配常用注解詳解,自動(dòng)裝配就是指 Spring 容器在不使用 <constructor-arg> 和<property> 標(biāo)簽的情況下,可以自動(dòng)裝配相互協(xié)作的 Bean 之間的關(guān)聯(lián)關(guān)系,將一個(gè) Bean 注入其他 Bean 的 Property 中,需要的朋友可以參考下
    2023-08-08
  • JAVA時(shí)間存儲(chǔ)類(lèi)Period和Duration使用詳解

    JAVA時(shí)間存儲(chǔ)類(lèi)Period和Duration使用詳解

    這篇文章主要為大家介紹了JAVA時(shí)間存儲(chǔ)類(lèi)Period和Duration使用詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-09-09
  • JDK8中新增的Optional工具類(lèi)基本使用

    JDK8中新增的Optional工具類(lèi)基本使用

    Optional不是對(duì)null關(guān)鍵字的一種替代,而是對(duì)于null判定提供了一種更加優(yōu)雅的實(shí)現(xiàn),接下來(lái)通過(guò)本文給大家分享JDK8中新增的Optional工具類(lèi)基本使用,感興趣的朋友跟隨小編一起看看吧
    2021-06-06
  • Java枚舉_動(dòng)力節(jié)點(diǎn)Java學(xué)院整理

    Java枚舉_動(dòng)力節(jié)點(diǎn)Java學(xué)院整理

    enum 的全稱(chēng)為 enumeration, 是 JDK 5 中引入的新特性,存放在 java.lang 包中。這篇文章給大家介紹Java枚舉相關(guān)知識(shí),需要的的朋友參考下
    2017-04-04
  • Java騷操作之CountDownLatch代碼詳解

    Java騷操作之CountDownLatch代碼詳解

    這篇文章主要介紹了Java騷操作之CountDownLatch代碼詳解,本文通過(guò)實(shí)例圖文相結(jié)合給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2021-02-02

最新評(píng)論