一般情況,我們把類定義成獨立的單元。有些情況下,我們把一個類放在另一個類的內部定義,稱為內部類(innerclasses)。
內部類的作用
1.內部類提供了更好的封裝。只能讓外部類直接訪問,不允許同一個包中的其他類直接訪問。
2.內部類可以直接訪問外部類的私有屬性,內部類被當成其外部類的成員。?但外部類不能訪問內部類的內部屬性。
內部類的使用場合
由于內部類提供了更好的封裝特性,并且可以很方便的訪問外部類的屬性。所以,通常內部類在只為所在外部類提供服務的情況下優先使用。
內部類的分類
成員內部類(可以使用private、proteted、public任意進行修飾。?類文件:外部類$內部類.class)
a)???非靜態內部類(外部類里使用非靜態內部類和平時使用其他類沒什么不同)
i.??非靜態內部類必須寄存在一個外部類對象里。因此,如果有一個非靜態內部類對象那么一定存在對應的外部類對象。?非靜態內部類對象單獨屬于外部類的某個對象。
ii.非靜態內部類可以使用外部類的成員,但是外部類不能直接訪問非靜態內部類成員。
iii.非靜態內部類不能有靜態方法、靜態屬性、靜態初始化塊。
iv.靜態成員不能訪問非靜態成員:外部類的靜態方法、靜態代碼塊不能訪問非靜態內部類,包括不能使用非靜態內部類定義變量、創建實例。
?v.?成員變量訪問要點:
? 1.?內部類里方法的局部變量:變量名
? 2.?內部類屬性:this.變量名
? 3.?外部類屬性:外部類名.this.變量名
【示例1】成員變量的訪問要點
public?class?Outer {
????private?int?age=10;
????class?Inner{
???????int?age=20;
???????public?void?show(){
???????????int?age=30;
?????????? System.out.println("內部類方法里的局部變量age:"+age);
?????????? System.out.println("內部類的成員變量age:"+this.age);
?????????? System.out.println("外部類的成員變量age:"+Outer.this.age);
?????? }
??? }
}
vi.內部類的訪問:
1.?外部類中定義內部類:new InnerClass()
2.??外部類以外的地方使用非靜態內部類:?
Outer.inner varname = OuterObject.new Inner()
【示例2】內部類的訪問
public?static?void?main(String[] args) {
??? Outer.Inner inner=new?Outer().new?Inner();
??? inner.show();
??? Outer?outer=new?? Outer();
??? Outer.Inner inn=outer.new?? Inner();
??? inn.show();
}?
示例2?運行效果圖
b)???靜態內部類
i.定義方式:
static? class?? ? ClassName {
//類體
}?
ii.?使用要點:
1.當一個靜態內部類對象存在,并不一定存在對應的外部類對象。?因此,靜態內部類的實例方法不能直接訪問外部類的實例方法。
2.??靜態內部類看做外部類的一個靜態成員。?因此,外部類的方法中可以通過:靜態內部類.名字,訪問靜態內部類的靜態成員。通過?new?靜態內部類()訪問靜態內部類的實例。
【示例3】靜態內部類的訪問
public?class?Test {
????public?static?void?main(String[] args) {
?????? Outer.Inner inner =new?Outer.Inner();
??? }
}
class?Outer{
????static?class?Inner{
??? }
}
c)???匿名內部類
適合那種只需要使用一次的類。比如:鍵盤監聽操作等等。
語法:
new? ??父類構造器(實參類表) \實現接口?() {
??? ???? ? ?? //匿名內部類類體!
}?
【示例4】匿名內部類的使用
this.addWindowListener(new WindowAdapter(){
?????????? @Override
?????????? public ? void windowClosing(WindowEvent e) {
????????????? System.exit(0);
?????????? }
??????? ? ?
??????? ? }
);
this.addKeyListener(new KeyAdapter(){
?????????? @Override
?????????? public ? void keyPressed(KeyEvent e) {
????????????? // ? TODO Auto-generated method stub
????????????? myTank.keyPressed(e);
?????????? }
?
?????????? @Override
?????????? public ? void keyReleased(KeyEvent e) {
????????????? // ? TODO Auto-generated method stub
????????????? myTank.keyReleased(e);
?????????? }
}
);
d)??局部內部類
定義在方法內部。作用域只限于本方法。用的非常少。
【示例5】方法中的內部類
public?class?Test {
????public?void?show(){
???????class?Inner{
???????????public?void?fun(){
????????????? System.out.println("helloworld");
?????????? }
?????? }
???????new?Inner().fun();
??? }
????public?static?void?main(String[] args) {
???????new?Test().show();
??? }
}
「全棧Java筆記」是一部能幫大家從零到一成長為全棧Java工程師系列筆記。筆者江湖人稱 Mr. G,10年Java研發經驗,曾在神州數碼、航天院某所研發中心從事軟件設計及研發工作,從小白逐漸做到工程師、高級工程師、架構師。精通Java平臺軟件開發,精通JAVAEE,熟悉各種流行開發框架。
筆記包含從淺入深的六大部分:
A-Java入門階段
B-數據庫從入門到精通
C-手刃移動前端和Web前端
D-J2EE從了解到實戰
E-Java高級框架精解
F-Linux和Hadoop?