JAVA:內部類和匿名內部類

接口中的內部類

??在我們實際開發(fā)過程中,如果想要創(chuàng)建某些公共代碼,使得他們可以被某個接口的所有不同實現(xiàn)所共用,那么接口內部的嵌套類會顯得很方便.也就是說在接口中可以含有內部類.在這里,向大家展示接口中放置普通成員內部類和抽象成員內部類的情況.
?
1.首先創(chuàng)建接口,接口中定義了普通內部類InnerClass和抽象內部類AbInnerClass

package com.diandian.inter;
// 接口IOuterInterface
public interface IOuterInterface{
      int TEMP = 100; // 常量
      void abMethod();// 抽象方法
      public default void deMethod(){ // jdk1.8后可添加
            System.out.println("接口中默認方法");
      }
      public static void stMethod() {
            System.out.println("接口中靜態(tài)方法");
      }
// 普通內部類
public class InnerClass{
        public void show(){
              System.out.println("接口中可定義普通成員內部類");
        }
}
// 抽象內部類
public abstract class AbInnerClass{
        public abstract void abInfo();
        public void info(){
            System.out.println("接口中可定義抽象成員內部類");
        }
}
}

2.普通成員內部類的實例化

// 創(chuàng)建接口的實現(xiàn)類ClassDemo
package com.diandian.inter;
// 實現(xiàn)類ClassDemo
public class ClassDemo implements IOuterInterface{
    @Override
    public void abMethod(){
        System.out.println("實現(xiàn)類");
    }
    // 獲取接口中內部類方法
    public InnerClass getInner(){
        return new InnerClass();
    }
}

      // 獲取普通內部類對象,調用方法
  package com.diandian.test;
  import com.diandian.inter.ClassDemo;
  import com.diandian.inter.IOuterInterface;
  import.com.diandian.inter.IOuterInterface.InnerClass;
    // 測試類:普通成員內部類
public class Test{
    public static void main(String[] args){
          /**第一種實例化對象方式:
              通過接口名.類名 進行實例化
            */
          IOuterInterface.InnerClass inner = new IOuterInterface.InnerClass();
          inner.show();
          /**第二種實例化對象方式:
              通過在實現(xiàn)類中創(chuàng)建接口中內部類獲取方法
              用實現(xiàn)對象調用獲取方法
          */
          ClassDemo demo = new ClassDemo();
          demo.getInner().show();
        /**第三種實例化對象方式:
            將內部類導入后,直接實例化
        */
          InnerClass innerTwo = new InnerClass();
          innerTwo.show();
    }
}

運行結果:

接口中可定義普通成員內部類
接口中可定義普通成員內部類
接口中可定義普通成員內部類

3.抽象成員內部類的實例化

    // 創(chuàng)建接口的實現(xiàn)類AbClassDemo
    package com.diandian.inter;
    // 實現(xiàn)類AbClassDemo
    public class AbClassDemo implements IOuterInterface{
        @Override
          public void abMethod(){
                
          }
          // 繼承抽象類AbInnerClass
        public class AbDemo extends AbInnerClass{
            @Override
              public void abInfo(){
                  System.out.println("重寫接口中抽象內部類中的抽象方法");
              }
         }
    }

獲取抽象內部類對象,調用方法

package com.diandian.test;
import com.diandian.inter.AbClassDemo;
import com.diandian.inter.IOuterInterface;
// 測試類:抽象成員內部類
public class TestOne{
    public static void main(String[] args){
    /*第一種實例化對象方式:
      通過接口名.類名 進行實例化
      但是對于抽象類而言,不能直接實例化,所以這里可使用匿名內部類的方式
    */
     IOuterInterface.AbInnerClass abInner = new IOuterInterface.AbInnerClass(){
        public void abInfo(){
              System.out.println("重寫抽象類中的抽象方法");
        }
    };
    abInner.abInfo();
    abInner.info();
    System.out.println("=====================");
    /*第二種實例化方法:
        在實現(xiàn)類中定義內部類繼承接口中的抽象內部類
    */
    IOuterInterface.AbInnerClass abInnerOne = new AbClassDemo().new AbDemo();
    abInnerOne.abInfo();
    abInnerOne.info();
}
}

運行結果:
重寫抽象類中的抽象方法
接口中可定義抽象成員內部類
========================
重寫接口中抽象類中的抽象方法
接口中可以定義抽象成員內部類

匿名內部類

概念

匿名內部類也及時沒有名字的內部類
正因為沒有名字,所以匿名內部類只能使用一次,它通常用來簡化代碼編寫但使用匿名內部類還有個前提條件:必須繼承一個父類或者一個接口
注意事項:

  • 編譯后的文件名:外部類$數(shù)字.class
  • 無法使用publick,private,abstract,static修飾,匿名內部類不能出現(xiàn)抽象方法
  • 無法編寫構造方法,但可以添加構造代碼塊
  • 不能出現(xiàn)靜態(tài)成員
  • 匿名內部類可實現(xiàn)接口也可以繼承類,但是不可兼得
  • 匿名內部類不能是抽象類的,它必須要實現(xiàn)繼承的類或者實現(xiàn)接口的所有抽象方法
    ?

匿名內部類初始化

??我們一般都是利用構造器來完成某個實例的初始化工作,但是匿名內部類是沒有構造器的,那怎么來初始化匿名內部類呢?使用構造代碼塊!利用構造代碼塊能夠達到為匿名內部類創(chuàng)建一個構造器的效果.
實例:
先定義一個接口,然后定義該接口的匿名內部類.

    public interface InnerClass{
        public String getName();
        public int getAge();
    }
    public class OutClass{
      public InnerClass getInnerClass(final int age,final String name){
          return new InnerClass(){
              int age_;
              String name_;
              // 構造代碼塊完成初始化工作
              {
                    if(0 < age && age < 200){
                          age_ = age;
                          name_ = name;
                    }
              }
              public String getName(){
                    return age_;
              }
          };
      }
      public static void main(String[] args){
          OutClass out = new OutClass();
          InnerClass inner_1 = out.getInnerClass(201,"chenssy");
          System.out.println(inner_1.getName());
          InnerClass inner_2 = out.getInnerClass(23,"chenssy");
           System.out.println(inner_2.getName());
      }
    }

實例

匿名內部類可以有不同的表現(xiàn)形式,下面用實例向大家展示一下:
繼承式的匿名內部類:

    abstract class Car{
      public abstract void drive();
    }
    class Test{
        public static void main(String[] args){
            Car car = new Car(){
                public void drive(){
                    System.out.println("Driving another car!");
                }
            };
            car.drive();
        }
    
    }

輸出結果:
Driving another Car!
引用變量不是應用Car對象,而是Car匿名子類的對象
??建立匿名內部類的關鍵點事重寫父類的一個或多個方法.再強調一下,是重寫的方法,而不是創(chuàng)建新的方法.因為用父類的引用不可能調用父類本身沒有的方法,創(chuàng)建新的方法時多余的.
?
接口式的匿名內部類:

  interface Vehicle{
      public void drive();
  }
  class Test{
       public static void main(String[] args){
          Vehicle vehicle = new Vehicle(){
              public void drive(){
                System.out.println("Driving a car!");
              }
            }
            vehicle.drive();
      }
  }

輸出結果:
Driving a car!
上面的代碼很怪,好像是在實例化一個接口.事實并非如此,接口式的匿名內部類是實現(xiàn)了一個接口的匿名類.而且只能實現(xiàn)一個接口.

 //參數(shù)是的匿名內部類:
  abstract class Bar{
      void doStuff(Foo f){}
  }
  class BarOne extends Bar{
      void doStuff(Foo f){}
  }
  interface Foo{
      void foo();
  }
  class Test{
        static void go(){
            Bar b = new BarOne();
            b.doStuff(new Foo(){
              public void foo(){
                System.out.println("foofy");
              }
            })
        }
  }

?由上面的三個例子可以看出,只要一個類是抽象的或是一個接口,那么其子類中的方法都可以使用匿名內部類來實現(xiàn).最常用的情況就是多線程的實現(xiàn)上,因為要實現(xiàn)多線程必須繼承Thread類或是實現(xiàn)Runnable接口
Thread類的匿名內部類實現(xiàn):

  public class Demo{
        public static void main(String[] args){
              Thread t = new Thread(){
                      public void run(){
                             for(int i = 1; i <= 5; i++){
                                    System.out.print(i +" ");
                              }
                       }
               };
              t.start();
        }
  }

Runnable接口的匿名內部類實現(xiàn):

public class Demo{
    public static void main(String[] args){
          Runnable r = new Runnable(){
                public void run(){
                        for(int i = 1; i <= 5; i++){
                                System.out.print(i + " ");
                          }
                }
          };
        Thread t = new Thread(r);
        t.start();
    }

}
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末腺律,一起剝皮案震驚了整個濱河市塘揣,隨后出現(xiàn)的幾起案子掂为,更是在濱河造成了極大的恐慌卦溢,老刑警劉巖,帶你破解...
    沈念sama閱讀 221,635評論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件冬耿,死亡現(xiàn)場離奇詭異儡羔,居然都是意外死亡嘴瓤,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,543評論 3 399
  • 文/潘曉璐 我一進店門轴猎,熙熙樓的掌柜王于貴愁眉苦臉地迎上來嵌莉,“玉大人,你說我怎么就攤上這事捻脖∪袂停” “怎么了中鼠?”我有些...
    開封第一講書人閱讀 168,083評論 0 360
  • 文/不壞的土叔 我叫張陵,是天一觀的道長沿癞。 經常有香客問我援雇,道長,這世上最難降的妖魔是什么椎扬? 我笑而不...
    開封第一講書人閱讀 59,640評論 1 296
  • 正文 為了忘掉前任惫搏,我火速辦了婚禮,結果婚禮上盗舰,老公的妹妹穿的比我還像新娘晶府。我一直安慰自己,他們只是感情好钻趋,可當我...
    茶點故事閱讀 68,640評論 6 397
  • 文/花漫 我一把揭開白布川陆。 她就那樣靜靜地躺著,像睡著了一般蛮位。 火紅的嫁衣襯著肌膚如雪较沪。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 52,262評論 1 308
  • 那天失仁,我揣著相機與錄音尸曼,去河邊找鬼。 笑死萄焦,一個胖子當著我的面吹牛控轿,可吹牛的內容都是我干的。 我是一名探鬼主播拂封,決...
    沈念sama閱讀 40,833評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼茬射,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了冒签?” 一聲冷哼從身側響起在抛,我...
    開封第一講書人閱讀 39,736評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎萧恕,沒想到半個月后刚梭,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經...
    沈念sama閱讀 46,280評論 1 319
  • 正文 獨居荒郊野嶺守林人離奇死亡票唆,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 38,369評論 3 340
  • 正文 我和宋清朗相戀三年朴读,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片惰说。...
    茶點故事閱讀 40,503評論 1 352
  • 序言:一個原本活蹦亂跳的男人離奇死亡磨德,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情典挑,我是刑警寧澤酥宴,帶...
    沈念sama閱讀 36,185評論 5 350
  • 正文 年R本政府宣布,位于F島的核電站您觉,受9級特大地震影響拙寡,放射性物質發(fā)生泄漏。R本人自食惡果不足惜琳水,卻給世界環(huán)境...
    茶點故事閱讀 41,870評論 3 333
  • 文/蒙蒙 一肆糕、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧在孝,春花似錦诚啃、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,340評論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至仔燕,卻和暖如春造垛,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背晰搀。 一陣腳步聲響...
    開封第一講書人閱讀 33,460評論 1 272
  • 我被黑心中介騙來泰國打工五辽, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人外恕。 一個月前我還...
    沈念sama閱讀 48,909評論 3 376
  • 正文 我出身青樓杆逗,卻偏偏與公主長得像,于是被迫代替她去往敵國和親鳞疲。 傳聞我的和親對象是個殘疾皇子髓迎,可洞房花燭夜當晚...
    茶點故事閱讀 45,512評論 2 359