一、即在一個類的內部定義的另外一個類,內部類能直接訪問外部內的全部變量,便可與外部類連接保持通訊;內部類提供了某種進入其外部類的容器。
二、使用內部類的一大緣由是:內部類能獨立地繼承自一個接口的實現,而不管外部類是否已經繼承,對於內部類都沒有影響。這間接實現了繼承多個類。
三、內部類能夠在一個類、方法等任意做用域內定義
四、在另外一個類裏實例一個類的非靜態內部類使用.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
接口與調用:編碼
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); }