定義在一個(gè)類(lèi)內(nèi)部的類(lèi)叫內(nèi)部類(lèi),包含內(nèi)部類(lèi)的類(lèi)稱(chēng)為外部類(lèi)。內(nèi)部類(lèi)可以聲明public、protected、private等訪問(wèn)限制,可以聲明為abstract的供其他內(nèi)部類(lèi)或外部類(lèi)繼承與擴(kuò)展,或者聲明為static、final的,也可以實(shí)現(xiàn)特定的接口。static的內(nèi)部類(lèi)行為上象一個(gè)獨(dú)立的類(lèi),非static在行為上類(lèi)似類(lèi)的屬性或方法且禁止聲明static的方法。內(nèi)部類(lèi)可以訪問(wèn)外部類(lèi)的所有方法與屬性,但static的內(nèi)部類(lèi)只能訪問(wèn)外部類(lèi)的靜態(tài)屬性與方法。
外部類(lèi)按常規(guī)的類(lèi)訪問(wèn)方式使用內(nèi)部類(lèi),唯一的差別是外部類(lèi)可以訪問(wèn)內(nèi)部類(lèi)的所有方法與屬性,包括私有方法與屬性。如:
pinner p = new pinner();
p.index = 20;
p.Print();
---- 這種方式適合外部類(lèi)的非static方法;
pouter po = new pouter();
pinner pi = po.new pinner();
pi.index = 40;
pi.Print();
---- 這種方式適合外部類(lèi)的static方法;
內(nèi)部類(lèi)類(lèi)似外部類(lèi)的屬性,因此訪問(wèn)內(nèi)部類(lèi)對(duì)象時(shí)總是需要一個(gè)創(chuàng)建好的外部類(lèi)對(duì)象。內(nèi)部類(lèi)對(duì)象通過(guò)‘外部類(lèi)名.this.xxx’的形式訪問(wèn)外部類(lèi)的屬性與方法。如:
System.out.println("Print in inner Outer.index=" + pouter.this.index);
System.out.println("Print in inner Inner.index=" + this.index);
如果需要在其他類(lèi)中訪問(wèn)內(nèi)部類(lèi),可以使用:
(1)外部類(lèi)提供創(chuàng)建內(nèi)部類(lèi)的方法供其他類(lèi)使用。如:
// 外部類(lèi)
pinner getInner()
{
return new pinner();
}
// 其他類(lèi)
pouter.pinner pi = po.getInner();
pi.Print();
(2)直接創(chuàng)建內(nèi)部類(lèi)的對(duì)象。如:
pouter po = new pouter();
pouter.pinner pi = po.new pinner();
pi.Print();
內(nèi)部類(lèi)可以聲明在外部類(lèi)的方法中或語(yǔ)句塊中。如果內(nèi)部類(lèi)需要訪問(wèn)包含它的外部類(lèi)方法或語(yǔ)句塊的局部變量或參數(shù),則該局部變量或參數(shù)必須是final的。外部類(lèi)的其他方法、其他類(lèi)無(wú)法訪問(wèn)聲明在方法內(nèi)部或塊內(nèi)部的內(nèi)部類(lèi)。
如果一個(gè)類(lèi)繼承內(nèi)部類(lèi),則創(chuàng)建該類(lèi)的對(duì)象時(shí)需提供一個(gè)外部類(lèi)的對(duì)象作為構(gòu)造方法的參數(shù)。如:
class Car
{
class Wheel
{
}
}
class SuperWheel extends Car.Wheel
{
SuperWheel(Car car)
{
car.super();
}
public static void main(String [] args)
{
Car car = new Car();
SuperWheel wl = new SuperWheel(car);
}
}
如果創(chuàng)建命名的內(nèi)部類(lèi)沒(méi)有多少實(shí)際意義時(shí),可以創(chuàng)建匿名的內(nèi)部類(lèi)。比如使用內(nèi)部類(lèi)實(shí)現(xiàn)接口的功能(如事件處理器、適配器等),而功能的差異較大,需要根據(jù)實(shí)際的情況創(chuàng)建相應(yīng)的內(nèi)部類(lèi)時(shí),可以使用匿名內(nèi)部類(lèi)。簡(jiǎn)單的示例如下:
interface WebView
{
void doGet();
}
class A
{
WebView ShowName()
{
return new WebView()
{
void doGet()
{
System.out.println("Name");
}
};
}
WebView ShowCode()
{
return new WebView()
{
void doGet()
{
System.out.println("Code");
}
};
}
}
最后,JAVA 內(nèi)部類(lèi)還有一個(gè)作用,那就是實(shí)現(xiàn)JAVA的多繼承。JAVA本身是不允許多繼承的,如果我們想一個(gè)類(lèi)繼承多個(gè)基類(lèi),就可以使用內(nèi)部類(lèi)。通過(guò)內(nèi)部類(lèi)分別繼承一個(gè)基類(lèi),外部類(lèi)創(chuàng)建內(nèi)部類(lèi)的對(duì)象,并使用內(nèi)部類(lèi)的方法,變相地實(shí)現(xiàn)了多繼承。