JAVA:內(nèi)部類和匿名內(nèi)部類

接口中的內(nèi)部類

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

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

2.普通成員內(nèi)部類的實(shí)例化

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

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

運(yùn)行結(jié)果:

接口中可定義普通成員內(nèi)部類
接口中可定義普通成員內(nèi)部類
接口中可定義普通成員內(nèi)部類

3.抽象成員內(nèi)部類的實(shí)例化

    // 創(chuàng)建接口的實(shí)現(xiàn)類AbClassDemo
    package com.diandian.inter;
    // 實(shí)現(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("重寫接口中抽象內(nèi)部類中的抽象方法");
              }
         }
    }

獲取抽象內(nèi)部類對(duì)象,調(diào)用方法

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

運(yùn)行結(jié)果:
重寫抽象類中的抽象方法
接口中可定義抽象成員內(nèi)部類
========================
重寫接口中抽象類中的抽象方法
接口中可以定義抽象成員內(nèi)部類

匿名內(nèi)部類

概念

匿名內(nèi)部類也及時(shí)沒有名字的內(nèi)部類
正因?yàn)闆]有名字,所以匿名內(nèi)部類只能使用一次,它通常用來簡(jiǎn)化代碼編寫但使用匿名內(nèi)部類還有個(gè)前提條件:必須繼承一個(gè)父類或者一個(gè)接口
注意事項(xiàng):

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

匿名內(nèi)部類初始化

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

    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_;
              // 構(gòu)造代碼塊完成初始化工作
              {
                    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());
      }
    }

實(shí)例

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

    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();
        }
    
    }

輸出結(jié)果:
Driving another Car!
引用變量不是應(yīng)用Car對(duì)象,而是Car匿名子類的對(duì)象
??建立匿名內(nèi)部類的關(guān)鍵點(diǎn)事重寫父類的一個(gè)或多個(gè)方法.再?gòu)?qiáng)調(diào)一下,是重寫的方法,而不是創(chuàng)建新的方法.因?yàn)橛酶割惖囊貌豢赡苷{(diào)用父類本身沒有的方法,創(chuàng)建新的方法時(shí)多余的.
?
接口式的匿名內(nèi)部類:

  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();
      }
  }

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

 //參數(shù)是的匿名內(nèi)部類:
  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");
              }
            })
        }
  }

?由上面的三個(gè)例子可以看出,只要一個(gè)類是抽象的或是一個(gè)接口,那么其子類中的方法都可以使用匿名內(nèi)部類來實(shí)現(xiàn).最常用的情況就是多線程的實(shí)現(xiàn)上,因?yàn)橐獙?shí)現(xiàn)多線程必須繼承Thread類或是實(shí)現(xiàn)Runnable接口
Thread類的匿名內(nèi)部類實(shí)現(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接口的匿名內(nèi)部類實(shí)現(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();
    }

}
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

友情鏈接更多精彩內(nèi)容