???????????????????????????????????????????????????????????????????? Inner Class
a> 在一個類中定義一個類,這個類就叫做內部類或者內置類(inner class).
b> 內部類可以讓我們將邏輯上相關的一組類組織起來,并由外部類(outer class)
?? 來控制內部類的可見性.
c> 當我們建立一個inner class的時候,其對象就擁有了與外部類對象之間的一種關系,
?? 這是通過一個特殊的this inference形成的,使得內部類對象可以隨意的訪問外部
?? 類中的所有成員。
d> 在內部類中可以訪問外部類的私有成員變量,也就是在內部類中可以隨意的訪問
?? 外部類中的所有的成員方法和變量
e> 可以把內部類放到一個方法中來定義,但是它的使用范圍必須是在這個方法里
f> 當我們在一個方法中定義一個內部類時,如果我們需要在方法中內部類去訪問這個
?? 本地變量(方法中聲明的變量)時,我們必須把這個變量聲明為final才行,不然
?? 編譯器會報錯
eg:
?void fn(int final a)
?{
??if(true)
??{
???class Middle
???{
????private int index=70;
????class Inner
????{
?????private int index=60;
?????void print()
?????{
??????int index=80;
??????System.out.println(index);? //訪問print()方法中的index=80變量
??????System.out.println(this.index); //訪問Inner類的成員變量index=60;
??????System.out.println(Middle.this.index); //訪問Middle類的成員變量index=70;
??????System.out.println(Outer.this.index);? //訪問Outer類的成員變量index=100;
?????}
????}
???}
??}
?}
f> 對于Inner類的訪問權限我們可以聲明為所有的(protected,private,public,default)。
h> 對于內部類來說,如果起訪問權限為protected,那么他可以在同一個類被訪也可以在同
?? 一個包中被訪問。而如果聲明為private的那么那只能在Outer這個外部類被訪問。我們
?? 可以把它生命為abstract(這個時候不能用Inner直接去實例化一個內部類),我們可以在
?? 外部類中定義一個類,從Inner派生出來,直接實例化。當我們聲明為final,那就不能再
?? 派生了,對于內部類來說還可以聲明為static,那么這個時候就可以不需要同時存在外部
?? 類的對象,那么這個時候我們也不能訪問外部類的非靜態的成員變量和方法。相當于切斷
?? 了與外部內對象的聯系。非靜態的內部類不能在內部類本身中定義靜態的方法(反之可以)。
?? 非static的內部類中的成員變量不能聲明為static的,只在頂層類或static的內部類中可以
?? 聲明為static的。
g> 為什么要使用內部類?
?? 1.在內部類(inner class)中可以隨意訪問外部類中的成員,讓我們更好的管理和組織我們
?? 的代碼。增強代碼的可讀性。
?? 2.內部類用于創建適配器類,適配器類是用于實現接口的類,使用內部類來實現接口,可以
?? 更好的定位與接口關聯的方法在代碼中的位置。
?? 3.其他的用法
?? a> 我們可以通過把內部類聲明為private來隱藏接口的實現細節
?? b> 我們需要派生一個類,同時又需要去實現一個接口,如果基類中有個方法和接口中的方法
?? 同名,但是他們的用法不一樣,我們就可以用內部類來解決。
=============================================================================
內部類的一般用法:
class Outer??????????? //Outer class
{
?private int index=100;? //私有的變量
?/*
?class Inner?????????? //Inner Class,independence individual
?{???????????????????? //可以整體的把Inner類看成是Outer類的一個成員
??private int index=50;
??void print()
??{
???int index=30;
???System.out.println(index);
???System.out.println(this.index);
???System.out.println(Outer.this.index);
??}
?}*/
?/*
?*Inner類不管嵌套層次有多深,都可以隨意的訪問外部的成員變量
?*當我們在一個方法中定義一個內部類時,如果我們需要在方法中內部類去訪問這個
? *本地變量(方法中聲明的變量)時,我們必須把這個變量聲明為final才行,不然
? *編譯器會報錯
?void fn(final int a)
?{
??final int b=1;
??if(true)
??{
???class Middle
???{
????private int index=70;
????class Inner
????{
?????private int index=60;
?????void print()
?????{
??????int index=80;
??????System.out.println(index);? //訪問print()方法中的index=80變量
??????System.out.println(this.index); //訪問Inner類的成員變量index=60;
??????System.out.println(Middle.this.index); //訪問Middle類的成員變量index=70;
??????System.out.println(Outer.this.index);? //訪問Outer類的成員變量index=100;
??????System.out.println(a);
??????System.out.println(b);
?????}
????}
???}
??}
?}
/*
?*我們可以把內部類放到一個方法中,但是它的使用范圍也定在了這個方法的范圍里,甚至可以放到if()塊
?*代碼塊中{}中,它告訴我們,不管我們把Inner()嵌套有多深,它都可以隨意的訪問外部類中的所有成員
? void fn()
? {
? class Inner??????????
? {???????????????????
??private int index=50;
??void print()
??{
???int index=30;
???System.out.println(index);
???System.out.println(this.index);
???System.out.println(Outer.this.index);
??}
? }? ?
? }
? */
? static class Inner??????
?{??????????????????
??private int index=50;
??void print()
??{
????int index=80;
????System.out.println(index);? //訪問print()方法中的index=80變量
????System.out.println(this.index); //訪問Inner類的成員變量index=60;
????System.out.println(Outer.this.index);? //訪問Outer類的成員變量index=100;
??}
?}
?
?void print()
?{
??//Inner inner=new Inner();
??//inner.print();
?}
?/*
?Inner getInner()
?{
??return new Inner();
?}
?*/
?/*
?public static void main(String[] args)
?{
??Outer outer=new Outer();
??//outer.print();
??//Inner in=outer.getInner();這是一句錯誤的代碼,因為Inner是定義在Outer類的內部的,所以對外是
??//不可見的,這個時候需要我們,使用外部類名來調用
??Inner in=outer.getInner(); //因為現在main()方法在Outer類里,這個時候Inner類對于main()方法來說是可見的
??Inner in=new Inner();
??in.print();
?}*/
}
class Test
{
?/*public static void main(String[] args)
?{
??Outer outer=new Outer();
??//outer.print();
??//Inner in=outer.getInner();這是一句錯誤的代碼,因為Inner是定義在Outer類的內部的,所以對外是
??//不可見的,這個時候需要我們,使用外部類名來調用
??Outer.Inner in=outer.getInner();
??in.print();
?}*/
?public static void main(String[] args)
?{
??Outer outer=new Outer();
??//outer.print();
??//Inner in=outer.getInner();這是一句錯誤的代碼,因為Inner是定義在Outer類的內部的,所以對外是
??//不可見的,這個時候需要我們,使用外部類名來調用
??//Outer.Inner in=outer.getInner();
??Outer.Inner in=outer.new Inner();? //用外部類對象來產生
??in.print();
?}
}
*****************************************************************************
從內部類派生的用法:
/*
?*從內部類派生的用法
*/
class Car
{
?class Wheel
?{
?}
}
class PlaneWheel extends Car.Wheel
{
?PlaneWheel(Car car)
?{
??car.super();? //建立內部類對象到子類的引用
?}
?public static void main(String[] args)
?{
??Car car=new Car();
??PlaneWheel pw=new PlaneWheel(car);
?}
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
內部類實現接口:
//用內部類實現接口,接口不能被實例化
interface Animal
{
?void eat();
?void sleep();
}
class Zoo
{
?private class Tiger implements Animal
?{
??public void eat()
??{
???System.out.println("Tiger eat!");
??}
??public void sleep()
??{
???System.out.println("Tiger sleep!");
??}
?}
?
?Animal getAnimal()
?{
??return new Tiger();
?}
?/*
?Animal getAnimal()
?{
??return new Animal()
??{?????????????????????? //這是就是匿名的類
???public void eat()
???{
????System.out.println("Animal eat!");
???}
???public void sleep()
???{
????System.out.println("Animal sleep!");
???}
??};?????????????????? //這是就是匿名的類
?}*/
}
class DoTest
{
?public static void main(String[] args)
?{
??Zoo z=new Zoo();
??Animal an=z.getAnimal();
??an.eat();
??an.sleep();
?}
}
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
基類中有個方法和接口中的方法,同名,但是他們的用法不一樣:
//基類中有個方法和接口中的方法,同名,但是他們的用法不一樣
interface Machine
{
?void run();
}
class Person
{
?public void run()
?{
??System.out.println("run");
?}
}
class Robot extends Person
{
?private class MachineHeart implements Machine
?{
??public void run()
??{
???System.out.println("heart run");
??}
?}
?Machine getMachine()
?{
??return new MachineHeart();
?}
}
class Work
{
?public static void main(String[] args)
?{
?? Robot robot=new Robot();
?? Machine m=robot.getMachine();
?? m.run();
?? robot.run();??
?}
}