2017-10-12

這是我學(xué)習(xí)Java內(nèi)部類的筆記

1.為什么使用內(nèi)部類?

使用內(nèi)部類最吸引人的原因是:每個(gè)內(nèi)部類都能獨(dú)立地繼承一個(gè)(接口的)實(shí)現(xiàn),所以無論外圍類是否已經(jīng)繼承了某個(gè)(接口的)實(shí)現(xiàn),

對(duì)于內(nèi)部類都沒有影響

1.1.使用內(nèi)部類最大的優(yōu)點(diǎn)就在于它能夠非常好的解決多重繼承的問題,使用內(nèi)部類還能夠?yàn)槲覀儙砣缦绿匦?

(1)、內(nèi)部類可以用多個(gè)實(shí)例,每個(gè)實(shí)例都有自己的狀態(tài)信息,并且與其他外圍對(duì)象的信息相互獨(dú)。

(2)、在單個(gè)外圍類中,可以讓多個(gè)內(nèi)部類以不同的方式實(shí)現(xiàn)同一個(gè)接口,或者繼承同一個(gè)類。

(3)、創(chuàng)建內(nèi)部類對(duì)象的時(shí)刻并不依賴于外圍類對(duì)象的創(chuàng)建。

(4)、內(nèi)部類并沒有令人迷惑的“is-a”關(guān)系,他就是一個(gè)獨(dú)立的實(shí)體。

(5)、內(nèi)部類提供了更好的封裝,除了該外圍類,其他類都不能訪問。

2.內(nèi)部類分類:

(一).成員內(nèi)部類:

public class Outer{

private int age = 99;

String name = "Coco";

public class Inner{

String name = "Jayden";

public void show(){

System.out.println(Outer.this.name);

System.out.println(name);

System.out.println(age);

}

}

public Inner getInnerClass(){

return new Inner();

}

public static void main(String[] args){

Outer o = new Outer();

Inner in = o.new Inner();

in.show();

}

} 1.Inner 類定義在 Outer 類的內(nèi)部,相當(dāng)于 Outer 類的一個(gè)成員變量的位置,Inner 類可以使用任意訪問控制符,

如 public 、 protected 、 private 等

2.Inner 類中定義的 show() 方法可以直接訪問 Outer 類中的數(shù)據(jù),而不受訪問控制符的影響,

如直接訪問 Outer 類中的私有屬性age

3.定義了成員內(nèi)部類后,必須使用外部類對(duì)象來創(chuàng)建內(nèi)部類對(duì)象,而不能直接去 new 一個(gè)內(nèi)部類對(duì)象,

即:內(nèi)部類 對(duì)象名 = 外部類對(duì)象.new 內(nèi)部類( );

4.編譯上面的程序后,會(huì)發(fā)現(xiàn)產(chǎn)生了兩個(gè) .class 文件: Outer.class,Outer$Inner.class{}

5.成員內(nèi)部類中不能存在任何 static 的變量和方法,可以定義常量:

(1).因?yàn)榉庆o態(tài)內(nèi)部類是要依賴于外部類的實(shí)例,而靜態(tài)變量和方法是不依賴于對(duì)象的,僅與類相關(guān),

簡而言之:在加載靜態(tài)域時(shí),根本沒有外部類,所在在非靜態(tài)內(nèi)部類中不能定義靜態(tài)域或方法,編譯不通過;

非靜態(tài)內(nèi)部類的作用域是實(shí)例級(jí)別

(2).常量是在編譯器就確定的,放到所謂的常量池了

友情提示:

1.外部類是不能直接使用內(nèi)部類的成員和方法的,可先創(chuàng)建內(nèi)部類的對(duì)象,然后通過內(nèi)部類的對(duì)象來訪問其成員變量和方法;

2.如果外部類和內(nèi)部類具有相同的成員變量或方法,內(nèi)部類默認(rèn)訪問自己的成員變量或方法,如果要訪問外部類的成員變量,

可以使用 this 關(guān)鍵字,如:Outer.this.name

(二).靜態(tài)內(nèi)部類: 是 static 修飾的內(nèi)部類,

1.靜態(tài)內(nèi)部類不能直接訪問外部類的非靜態(tài)成員,但可以通過 new 外部類().成員 的方式訪問

2.如果外部類的靜態(tài)成員與內(nèi)部類的成員名稱相同,可通過“類名.靜態(tài)成員”訪問外部類的靜態(tài)成員;

如果外部類的靜態(tài)成員與內(nèi)部類的成員名稱不相同,則可通過“成員名”直接調(diào)用外部類的靜態(tài)成員

3.創(chuàng)建靜態(tài)內(nèi)部類的對(duì)象時(shí),不需要外部類的對(duì)象,可以直接創(chuàng)建 內(nèi)部類 對(duì)象名 = new 內(nèi)部類();

public class Outer{

private int age = 99;

static String name = "Coco";

public static class Inner{

String name = "Jayden";

public void show(){

System.out.println(Outer.name);

System.out.println(name);

}

}

public static void main(String[] args){

Inner i = new Inner();

i.show();

}

} (三).方法內(nèi)部類:訪問僅限于方法內(nèi)或者該作用域內(nèi)

(1).局部內(nèi)部類就像是方法里面的一個(gè)局部變量一樣,是不能有 public、protected、private 以及 static 修飾符的

(2).只能訪問方法中定義的 final 類型的局部變量,因?yàn)?

當(dāng)方法被調(diào)用運(yùn)行完畢之后,局部變量就已消亡了。但內(nèi)部類對(duì)象可能還存在,

直到?jīng)]有被引用時(shí)才會(huì)消亡。此時(shí)就會(huì)出現(xiàn)一種情況,就是內(nèi)部類要訪問一個(gè)不存在的局部變量;

==>使用final修飾符不僅會(huì)保持對(duì)象的引用不會(huì)改變,而且編譯器還會(huì)持續(xù)維護(hù)這個(gè)對(duì)象在回調(diào)方法中的生命周期.

局部內(nèi)部類并不是直接調(diào)用方法傳進(jìn)來的參數(shù),而是內(nèi)部類將傳進(jìn)來的參數(shù)通過自己的構(gòu)造器備份到了自己的內(nèi)部,

自己內(nèi)部的方法調(diào)用的實(shí)際是自己的屬性而不是外部類方法的參數(shù);

防止被篡改數(shù)據(jù),而導(dǎo)致內(nèi)部類得到的值不一致

? /*

使用的形參為何要為 final???

在內(nèi)部類中的屬性和外部方法的參數(shù)兩者從外表上看是同一個(gè)東西,但實(shí)際上卻不是,所以他們兩者是可以任意變化的,

也就是說在內(nèi)部類中我對(duì)屬性的改變并不會(huì)影響到外部的形參,而然這從程序員的角度來看這是不可行的,

畢竟站在程序的角度來看這兩個(gè)根本就是同一個(gè),如果內(nèi)部類該變了,而外部方法的形參卻沒有改變這是難以理解

和不可接受的,所以為了保持參數(shù)的一致性,就規(guī)定使用 final 來避免形參的不改變

*/

public class Outer{

public void Show(){

final int a = 25;

int b = 13;

class Inner{

int c = 2;

public void print(){

System.out.println("訪問外部類:" + a);

System.out.println("訪問內(nèi)部類:" + c);

}

}

Inner i = new Inner();

i.print();

}

public static void main(String[] args){

Outer o = new Outer();

o.show();

}

}? ?

(3).注意:在JDK8版本之中,方法內(nèi)部類中調(diào)用方法中的局部變量,可以不需要修飾為 final,匿名內(nèi)部類也是一樣的,主要是JDK8之后增加了 Effectively final 功能

http://docs.oracle.com/javase/tutorial/java/javaOO/localclasses.html

反編譯jdk8編譯之后的class文件,發(fā)現(xiàn)內(nèi)部類引用外部的局部變量都是 final 修飾的

(四).匿名內(nèi)部類:

(1).匿名內(nèi)部類是直接使用 new 來生成一個(gè)對(duì)象的引用;

(2).對(duì)于匿名內(nèi)部類的使用它是存在一個(gè)缺陷的,就是它僅能被使用一次,創(chuàng)建匿名內(nèi)部類時(shí)它會(huì)立即創(chuàng)建一個(gè)該類的實(shí)例,

該類的定義會(huì)立即消失,所以匿名內(nèi)部類是不能夠被重復(fù)使用;

(3).使用匿名內(nèi)部類時(shí),我們必須是繼承一個(gè)類或者實(shí)現(xiàn)一個(gè)接口,但是兩者不可兼得,同時(shí)也只能繼承一個(gè)類或者實(shí)現(xiàn)一個(gè)接口;

(4).匿名內(nèi)部類中是不能定義構(gòu)造函數(shù)的,匿名內(nèi)部類中不能存在任何的靜態(tài)成員變量和靜態(tài)方法;

(5).匿名內(nèi)部類中不能存在任何的靜態(tài)成員變量和靜態(tài)方法,匿名內(nèi)部類不能是抽象的,它必須要實(shí)現(xiàn)繼承的類或者實(shí)現(xiàn)的接口的所有抽象方法

(6).匿名內(nèi)部類初始化:使用構(gòu)造代碼塊!利用構(gòu)造代碼塊能夠達(dá)到為匿名內(nèi)部類創(chuàng)建一個(gè)構(gòu)造器的效果

? public class OuterClass {

? ? ? ? ? ? public InnerClass getInnerClass(final int? num,String str2){

? ? ? ? ? ? ? ? return new InnerClass(){

? ? ? ? ? ? ? ? ? ? int number = num + 3;

? ? ? ? ? ? ? ? ? ? public int getNumber(){

? ? ? ? ? ? ? ? ? ? ? ? return number;

? ? ? ? ? ? ? ? ? ? }

? ? ? ? ? ? ? ? };? ? ? ? /* 注意:分號(hào)不能省 */

? ? ? ? ? ? }

? ? ? ? ? ? public static void main(String[] args) {

? ? ? ? ? ? ? ? OuterClass out = new OuterClass();

? ? ? ? ? ? ? ? InnerClass inner = out.getInnerClass(2, "chenssy");

? ? ? ? ? ? ? ? System.out.println(inner.getNumber());

? ? ? ? ? ? }

? ? ? ? }

? ? ? ? interface InnerClass {

? ? ? ? ? ? int getNumber();

? ? ? ? }? ? ? ? ? ? ?

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • Java 內(nèi)部類 分四種:成員內(nèi)部類、局部內(nèi)部類、靜態(tài)內(nèi)部類和匿名內(nèi)部類。 1、成員內(nèi)部類: 即作為外部類的一個(gè)成...
    ikaroskun閱讀 1,349評(píng)論 0 13
  • 1. Java基礎(chǔ)部分 基礎(chǔ)部分的順序:基本語法,類相關(guān)的語法,內(nèi)部類的語法,繼承相關(guān)的語法,異常的語法,線程的語...
    子非魚_t_閱讀 34,624評(píng)論 18 399
  • Advanced Language Features 知識(shí)點(diǎn):一. static修飾符 static修飾符可以用來...
    風(fēng)景涼閱讀 505評(píng)論 0 0
  • 一:java概述:1,JDK:Java Development Kit,java的開發(fā)和運(yùn)行環(huán)境,java的開發(fā)工...
    ZaneInTheSun閱讀 2,800評(píng)論 0 11
  • Win7下如何打開DOS控制臺(tái)? a:開始--所有程序--附件--命令提示符 b:開始--搜索程序和文件--cmd...
    逍遙嘆6閱讀 1,697評(píng)論 4 12

友情鏈接更多精彩內(nèi)容