爲何要使用內部類java
主要有如下緣由:ide
若是一個類只有另一個類在使用它,其它的類都沒有用到它,能夠把這個類定義爲一個內部類。學習
這裏又有產生了一個問題?咱們幹嗎不把一個類的修飾符設置爲private的呢?ui
結果是沒有這種語法。一個類不能被設置爲private權限的(內部類固然能夠用private修飾了)。this
java中的類是(接口是能夠有多繼承的)沒有多繼承機制,可是在某些特殊狀況下是要實現多繼承的,這個時候咱們就能夠考慮到使用內部類,由於每個內部類均可以獨立的繼承自一個(接口的)實現,因此不管外部類是否已經繼承了某個(接口的)實現,對於內部類來講都沒有影響。spa
內部類的一些特性:code
內部類訪問它所在的外部類(方法或者是屬性),外部類不能方法該內部類,緣由是內部類持有外部類的引用。對象
學習內部類的關鍵點:不要把內部類當作一個類,就把他當作外部類的一個屬性或者方法。繼承
內部類的分類:接口
成員內部類
clclass OuterCalzz { private int age = 100; class InnerClazz{ private int age = 20; public void show(){ System.out.println(age); //訪問外部類的屬性 System.out.println(new OuterCalzz().age); //訪問外部類的方法 new OuterCalzz().test(); } } public void test(){ System.out.println("OuterClazz"); } } //訪問成員內部類的過程 public class InnerTest{ public static void main(String[] args) { OuterCalzz outerCalzz = new OuterCalzz(); outerCalzz.new InnerClazz().show(); } }
靜態內部類
class OuterCalzz { //靜態類,不能訪問非靜態的變量,因此這裏age設置成爲了static private static int age = 100; //成員內部類,是一個類的成員 static class InnerClazz{ public void show(){ System.out.println(age); } } public void test(){ System.out.println("OuterClazz"); } } //訪問靜態內部類的過程 public class InnerTest{ public static void main(String[] args) { //靜態能夠直接用類名來訪問 OuterCalzz.InnerClazz in = new OuterCalzz.InnerClazz(); in.show(); } }
局部內部類(定義在方法中的類)
注意:局部內部類訪問局部變量的時候,這個局部變量必定要定義爲final,爲何呢?
方法在執行完成以後,它裏邊的變量就會被銷燬,當你再次使用的時候沒有了,因此就要用final修飾,讓定義的變量變成不變的值
class OuterCalzz { //test()方法不能反回內部類,緣由是方法沒有執行前不可以建立內部類對象 public Object test(){ final int age = 30; class InnerClazz{ public void show(){ System.out.println("InnerClazz"); System.out.println(age); } public String toString(){ return "fff"; } } return new InnerClazz(); } }
匿名內部類
匿名內部類裏邊定義的屬性在初始化塊裏邊初始化
class OuterCalzz { public Person test(final String name_, final int age_){ /** * 內部類構建一個相似的javaBean */ return new Person() { private String name; private int age; { name = name_; age = age_; } @Override public String run(String name) { return name; } public String getName(){ return this.name; } public int getAge(){ return this.age; } }; } } interface Person{ public abstract String run(String name); public abstract String getName(); public abstract int getAge(); } //匿名內部類的使用 public class InnerTest{ @Test public void myJunit(){ OuterCalzz outerCalzz = new OuterCalzz(); Person p = outerCalzz.test("quincy",23); p.getAge(); } }
嵌套類
class MNA{
class A{
private void f(){}
public class B{
private void g(){}
void h(){
g();
f();
}
}
}
}
使用
public class MultiInnerClass {
public static void main(String[] args) {
MNA mna = new MNA();
MNA.A mnaa = mna.new A();
MNA.A.B mnaab = mnaa.new B();
}
}
局部代碼塊的做用是控制局部變量的釋放時間,節省內存
public void test(){ { int count = 0; while(count < 10){ count ++; } } //其餘的代碼 } count變量只會在,代碼塊中有效,在代碼塊外就會被釋放