Java內部類

1、定義

一、即在一個類的內部定義的另外一個類,內部類能直接訪問外部內的全部變量,便可與外部類連接保持通訊;內部類提供了某種進入其外部類的容器。
二、使用內部類的一大緣由是:內部類能獨立地繼承自一個接口的實現,而不管外部類是否已經繼承,對於內部類都沒有影響。這間接實現了繼承多個類。
三、內部類能夠在一個類、方法等任意做用域內定義
四、在另外一個類裏實例一個類的非靜態內部類使用.new。擁有外部類對象以前是不可能建立內部類對象的,因此須要先實例外部類。若是內部類是靜態類,則和普通的靜態類同樣,能夠直接調用。
五、接口中的內部類, 接口中能夠放置內部類,接口中的任何類都自動是public static的,因此至關於放置了一個static公共方法;
六、內部類是面向對象的閉包
七、內部類能夠被繼承,繼承時不用繼承外部類;
八、內部類被編譯後會生成一個獨立的.class文件,命名規則爲:外部類的名字加上$,再加上內部類的名字。若是內部類是匿名的,編譯器會簡單的生成一個數字做爲其標識符。
示例:閉包

public class StudyTest {
    StudyTest(){
      System.out.println("construct StudyTest");
    }
    private String study = "study";
    
    public class InnerClass{
      public StudyTest outClass(){
          System.out.println(study);
          return StudyTest.this;  //使用.this直接調用當前類的父類
      }
    }

    public static void main(String[] args) {
          InnerClass innerClass = new StudyTest().new InnerClass(); //實例內部類
          innerClass.outClass();
    }
}

運行結果:ide

construct StudyTest
studythis

2、應用

一、內部類用於隱藏實現細節示例

接口與調用:編碼

public interface StudyInterface {
    String getValue();
}
public class MainClass {
    public static void main(String[] args) {
        StudyInterface studyInterface = new StudyTest().instance();
        System.out.println(studyInterface.getValue());
    }
}

實現:spa

public class StudyTest {
    StudyTest(){
      System.out.println("construct StudyTest");
    }
    private String study = "study";

    //此內部類對外不可見,不可實例不可繼承.
    private class InnerClass implements StudyInterface{
        @Override
        public String getValue() {
            return study;
        }
    }
    public StudyInterface instance(){
        return new InnerClass();
    }
}

經過這種方式能夠徹底阻止任何依賴於類型的編碼,而且徹底隱藏了實現細節。從調用方的角度看,因爲不能訪問任何新增長的、本來不屬於公共接口的方法,因此擴展接口是沒有價值的。code

二、匿名內部類

public class StudyTest {
    private String name = "study";
    public String getName(){return this.name;}
}
public class MainClass {
    public StudyTest studyTestPlus(){
        return new StudyTest(){
            private String nameplus = "studyTestPlus";
            public String getName(){return  nameplus;}
        }; //注意此處有分號,不能省略
    }
    public static void main(String[] args) {
        StudyTest studyTest = new MainClass().studyTestPlus();
        System.out.println(studyTest.getName());
 }
//----------studyTestPlus()處至關於對StudyTest類進行了繼承拓展,效果和下邊的代碼同樣:----------
    public class StudyTestPlus extends StudyTest{
        private String nameplus = "studyTestPlus";
        public String getName(){return  nameplus;}
    }
    public StudyTest studyTestPlus(){
        return new StudyTestPlus();
    }

匿名內部類既能夠擴展類,也能夠實現接口,但不能二者兼備,若是實現接口也只能實現一個。對象

三、匿名內部類與工廠模式結合

public interface Service{ void printName();}
public interface ServiceFactory{Service getService();}
public class Factory{
    public static void serviceConsumer(ServiceFactory factory){
        factory.getService().printName();
    }
}

public class Implements1 implements Service{
    public void printName(){System.out.println("Implements1");}
    public static ServiceFactory factory =new ServiceFactory() {
        public Service getService() {
            return new Implements1();
        }
    };
}
public class Implements2 implements Service{ 
    public static ServiceFactory factory =new ServiceFactory() {
        public Service getService() {
            return new Implements2();
        }
    };
}
//使用
public static void main(String[] args) {
    Factory.serviceConsumer(Implements1.factory);
    Factory.serviceConsumer(Implements2.factory);
}
相關文章
相關標籤/搜索