java內部類的區(qū)別(成員內部類怕品、靜態(tài)嵌套類妇垢、方法內部類、匿名內部類)

一、什么是內部類

  內部類是指在一個外部類的內部再定義一個類闯估。內部類作為外部類的一個成員灼舍,并且依附于外部類而存在的。內部類可為靜態(tài)涨薪,可用protected和private修飾(而外部類只能使用public和缺省的包訪問權限)骑素。

 內部類主要有一下幾種:成員內部類、局部內部類刚夺、靜態(tài)內部類献丑、匿名內部類

二侠姑、內部類的共性

(1)创橄、內部類仍然是一個獨立的類,在編譯之后內部類會被編譯成獨立的.class文件莽红,但是前面冠以外部類的類名和$符號 妥畏。

(2)、內部類不能用普通的方式訪問安吁。

(3)咖熟、內部類聲明成靜態(tài)的,就不能隨便的訪問外部類的成員變量了柳畔,此時內部類只能訪問外部類的靜態(tài)成員變量 馍管。

(4)、外部類不能直接訪問內部類的的成員薪韩,但可以通過內部類對象來訪問

三确沸、為什么需要內部類

其主要原因有以下幾點:

  1、內部類方法可以訪問該類定義所在的作用域的數(shù)據俘陷,包括私有的數(shù)據

  2罗捎、內部類可以對同一個包中的其他類隱藏起來,一般的非內部類,是不允許有 private 與protected權限的拉盾,但內部類可以

  3桨菜、可以實現(xiàn)多重繼承

  4、當想要定義一個回調函數(shù)且不想編寫大量代碼時捉偏,使用匿名內部類比較便捷

使用內部類最吸引人的原因是:

  每個內部類都能獨立地繼承自一個(接口的)實現(xiàn)倒得,所以無論外圍類是否已經繼承了某個(接口的)實現(xiàn),對于內部類都沒有影響夭禽。大家都知道Java只能繼承一個類霞掺,它的多重繼承在我們沒有學習內部類之前是用接口來實現(xiàn)的。但使用接口有時候有很多不方便的地方讹躯。比如我們實現(xiàn)一個接口就必須實現(xiàn)它里面的所有方法菩彬。而有了內部類就不一樣了缠劝。它可以使我們的類繼承多個具體類或抽象類。

四骗灶、內部類分類

1惨恭、成員內部類

即在一個類中直接定義的內部類,成員內部類與普通類的成員沒什么區(qū)別耙旦,可以與普通成員一樣進行修飾和限制喉恋。成員內部類不能含有static的變量和方法。

package com.test;

?

public class Outer {

?? private static int number = 100;

?? private int j = 20;

?? private String name = "Java";

?

?? public static void outer_funOne(){

? ? ?? System.out.println("外部類Outer的靜態(tài)方法:outer_funOne");

?? }

?

?? public void outer_funTwo(){

? ? ?? System.out.println("外部類的普通方法:outer_funTwo");

?? }

?

?? //成員內部類母廷,可以訪問外部類的所有成員

?? class Demo{

? ? ?? //內部類不允許定義靜態(tài)變量

? ? ?? //static int demo_i = 100;

? ? ?? int j =50; //內部類和外部類的實例變量可以共存

?

? ? ?? //成員內部類中的方法定義

? ? ?? public void demo_funOne(){

? ? ? ? ?? //內部類中訪問內部類自己的變量直接用變量名

? ? ? ? ?? //也可以用? this.j

? ? ? ? ?? System.out.println(j);

?

? ? ? ? ?? //內部類中訪問外部類的成員變量語法:外部類類名.this.變量名

? ? ? ? ?? System.out.println("內部類訪問外部類變量:"+Outer.this.j);

?

? ? ? ? ?? //如果內部類中沒有與外部類中有相同的變量,則可以直接用變量名使用

? ? ? ? ?? System.out.println(name);

?

? ? ? ? ?? //內部類調用外部類方法

? ? ? ? ?? outer_funOne();? //靜態(tài)方法

? ? ? ? ?? outer_funTwo();? //非靜態(tài)方法

?

? ? ?? }

?

?? }

?

?? public static void outer_funThree(){

? ? ?? //外部類靜態(tài)方法訪問成員內部類

? ? ?? // 1糊肤、建立外部類對象

? ? ?? Outer out = new Outer();

? ? ?? //? 2琴昆、根據外部類建立內部類對象

? ? ?? Demo demo = out.new Demo();

? ? ?? // 訪問內部類方法

? ? ?? demo.demo_funOne();

? ? ?? //訪問內部類字段

? ? ?? System.out.println("內部類成員字段:"+demo.j);

?? }

?

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

? ? ?? //調用內部類的方法

? ? ?? // 1、創(chuàng)建外部類對象

? ? ?? Outer out = new Outer();

? ? ?? // 2馆揉、通過外部類對象創(chuàng)建內部類對象

? ? ?? Outer.Demo demo = out.new Demo();

?

? ? ?? // 1业舍、2步簡寫

? ? ?? // Outer.Demo demo1 = new Outer().new Demo();

?

? ? ?? //方法調用

? ? ?? demo.demo_funOne();

?

?? }

?

}

2、局部內部類

    在方法中定義的內部類稱為局部內部類升酣。與局部變量類似舷暮,局部內部類不能有訪問說明符,因為它不是外圍類的一部分噩茄,但是它可以訪問當前代碼塊內的常量下面,和此外圍類所有的成員。

需要注意的是:

  (1)绩聘、局部內部類只能在定義該內部類的方法內實例化沥割,不可以在此方法外對其實例化。

  (2)凿菩、局部內部類對象不能使用該內部類所在方法的非final局部變量机杜。

package com.test;

?

public class Outer {

?? private static int number = 100;

?? private int j = 20;

?? private String name = "Java";

?

?? //定義外部類方法

?? public void outer_funOne(int k){

? ? ?? final int number = 100;

? ? ?? int j = 50;

?

? ? ?? //方法內部的類(局部內部類)

? ? ?? class Demo{

? ? ? ? ?? public Demo(int k){

? ? ? ? ? ? ?? demo_funOne(k);

? ? ? ? ?? }

?

? ? ? ? ?? int number = 300; //可以定義與外部類同名的變量

? ? ? ? ?? // static int j = 10;? //不可以定義靜態(tài)變量

?

? ? ? ? ?? //內部類的方法

? ? ? ? ?? public void demo_funOne(int k){

? ? ? ? ? ? ?? System.out.println("內部類方法:demo_funOne");

? ? ? ? ? ? ?? //訪問外部類的變量,如果沒有與內部類同名的變量衅谷,則可直接用變量名

? ? ? ? ? ? ?? System.out.println(name);

? ? ? ? ? ? ?? //訪問外部類與內部類同名的變量

? ? ? ? ? ? ?? System.out.println(Outer.this.number);

? ? ? ? ? ? ?? System.out.println("內部類方法傳入的參數(shù)是:"+k);

? ? ? ? ?? }

? ? ?? }

?

? ? ?? new Demo(k);

?? }

?

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

? ? ?? //訪問內部類必須要先有外部類對象

? ? ?? Outer out = new Outer();

? ? ?? out.outer_funOne(11);

?? }

?

}

3椒拗、靜態(tài)內部類(嵌套類)

  如果你不需要內部類對象與其外圍類對象之間有聯(lián)系,那你可以將內部類聲明為static获黔。這通常稱為嵌套類(nested class)蚀苛。想要理解static應用于內部類時的含義,你就必須記住玷氏,普通的內部類對象隱含地保存了一個引用枉阵,指向創(chuàng)建它的外圍類對象。然而预茄,當內部類是static的時兴溜,就不是這樣了侦厚。嵌套類意味著:

  1、 要創(chuàng)建嵌套類的對象拙徽,并不需要其外圍類的對象刨沦。

2、不能從嵌套類的對象中訪問非靜態(tài)的外圍類對象膘怕。

package com.test;

?

public class Outer {

?? private static int number = 100;

?? private int j = 20;

?? private String name = "Java";

?

?? public static void outer_funOne(){

? ? ?? System.out.println("外部類靜態(tài)方法:outer_funOne");

?? }

?

?? public void outer_funTwo(){

?

?? }

?

?? //靜態(tài)內部類可以用public想诅、protected、private修飾

?? //靜態(tài)內部類可以定義靜態(tài)類或非靜態(tài)內部類

?? private static class Demo{

? ? ?? static int j = 100;

? ? ?? String name = "C#";

?

? ? ?? //靜態(tài)內部類里的靜態(tài)方法

? ? ?? static void demo_funOne(){

? ? ? ? ?? //靜態(tài)內部類只能訪問外部類的靜態(tài)成員(靜態(tài)變量岛心、靜態(tài)方法)

? ? ? ? ?? System.out.println("靜態(tài)內部類訪問外部類靜態(tài)變量:"+number);

? ? ? ? ?? outer_funOne();//訪問外部類靜態(tài)方法

?

? ? ?? }

?

? ? ?? //靜態(tài)內部類非靜態(tài)方法

? ? ?? void demo_funTwo(){

?

? ? ?? }

?

?? }

?

?? public void outer_funThree(){

? ? ?? //外部類訪問內部類靜態(tài)成員:內部類.靜態(tài)成員

? ? ?? System.out.println(Demo.j);

? ? ?? //訪問靜態(tài)方法

? ? ?? Demo.demo_funOne();

? ? ?? //訪問靜態(tài)內部類的非靜態(tài)成員来破,實例化內部類即可

? ? ?? Demo demo = new Demo();

? ? ?? //訪問非靜態(tài)變量

? ? ?? System.out.println(demo.name);

? ? ?? //訪問非靜態(tài)方法

? ? ?? demo.demo_funTwo();

?

?? }

?

?

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

? ? ?? new Outer().outer_funThree();

?? }

?

}

4、匿名內部類

匿名內部類就是沒有名字的內部類忘古。什么情況下需要使用匿名內部類徘禁?如果滿足下面的一些條件,使用匿名內部類是比較合適的:

  1髓堪、只用到類的一個實例送朱。

  2、類在定義后馬上用到干旁。

  3驶沼、類非常小(SUN推薦是在4行代碼以下)

  4争群、給類命名并不會導致你的代碼更容易被理解回怜。

在使用匿名內部類時,要記住以下幾個原則:

  1换薄、 匿名內部類不能有構造方法鹉戚。

  2、 匿名內部類不能定義任何靜態(tài)成員专控、方法和類抹凳。

  3、 匿名內部類不能是public,protected,private,static伦腐。

  4赢底、 只能創(chuàng)建匿名內部類的一個實例。

  5柏蘑、? 一個匿名內部類一定是在new的后面幸冻,用其隱含實現(xiàn)一個接口或實現(xiàn)一個類。

  6咳焚、 因匿名內部類為局部內部類洽损,所以局部內部類的所有限制都對其生效。

public????class????Demo{

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

//我們要求是調用PersonDemo中的method方法

PersonDemo????pd=new????PersonDemo();

//這里要求我們傳一個抽象類對象革半,但是抽象類對象不能夠初始化碑定。

//所以要我們傳一個匿名內部類進去,這里不能直接傳抽象類對象流码,我們可以

//傳兩種,要么傳有名的子類對象延刘,要么傳匿名內部對象

// ? ? ?? Person p = new Student();

// ? ? ?? pd.method(p);

?

//我們用匿名內部類來做一下--匿名內部類當做參數(shù)傳遞漫试,把匿名內部類當做一個對象

pd.method(new????Person(){

//重寫show()方法

public????void????show(){

System.out.println("匿名內部類實現(xiàn)");

? ? ? ? ?? }

? ? ?? });

?

?? }

}

?

//寫個抽象類

abstract????class????Person{

public????abstract????void????show();

}

?

//普通類

class Person Demo{

public????void????method(Person????p){

p.show();

?? }

}

//再創(chuàng)建個子類對象去繼承抽象類

class????Student????extends????Person{

public????void????show(){

System.out.println("我是一個有名的子類");

?? }

}

?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市碘赖,隨后出現(xiàn)的幾起案子驾荣,更是在濱河造成了極大的恐慌,老刑警劉巖普泡,帶你破解...
    沈念sama閱讀 221,198評論 6 514
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件播掷,死亡現(xiàn)場離奇詭異,居然都是意外死亡撼班,警方通過查閱死者的電腦和手機歧匈,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,334評論 3 398
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來权烧,“玉大人,你說我怎么就攤上這事伤溉“懵耄” “怎么了?”我有些...
    開封第一講書人閱讀 167,643評論 0 360
  • 文/不壞的土叔 我叫張陵乱顾,是天一觀的道長板祝。 經常有香客問我,道長走净,這世上最難降的妖魔是什么券时? 我笑而不...
    開封第一講書人閱讀 59,495評論 1 296
  • 正文 為了忘掉前任,我火速辦了婚禮伏伯,結果婚禮上橘洞,老公的妹妹穿的比我還像新娘。我一直安慰自己说搅,他們只是感情好炸枣,可當我...
    茶點故事閱讀 68,502評論 6 397
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著弄唧,像睡著了一般适肠。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上候引,一...
    開封第一講書人閱讀 52,156評論 1 308
  • 那天侯养,我揣著相機與錄音,去河邊找鬼澄干。 笑死逛揩,一個胖子當著我的面吹牛柠傍,可吹牛的內容都是我干的。 我是一名探鬼主播息尺,決...
    沈念sama閱讀 40,743評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼携兵,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了搂誉?” 一聲冷哼從身側響起徐紧,我...
    開封第一講書人閱讀 39,659評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎炭懊,沒想到半個月后并级,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經...
    沈念sama閱讀 46,200評論 1 319
  • 正文 獨居荒郊野嶺守林人離奇死亡侮腹,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 38,282評論 3 340
  • 正文 我和宋清朗相戀三年嘲碧,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片父阻。...
    茶點故事閱讀 40,424評論 1 352
  • 序言:一個原本活蹦亂跳的男人離奇死亡愈涩,死狀恐怖,靈堂內的尸體忽然破棺而出加矛,到底是詐尸還是另有隱情履婉,我是刑警寧澤,帶...
    沈念sama閱讀 36,107評論 5 349
  • 正文 年R本政府宣布斟览,位于F島的核電站毁腿,受9級特大地震影響,放射性物質發(fā)生泄漏苛茂。R本人自食惡果不足惜已烤,卻給世界環(huán)境...
    茶點故事閱讀 41,789評論 3 333
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望妓羊。 院中可真熱鬧胯究,春花似錦、人聲如沸躁绸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,264評論 0 23
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽涨颜。三九已至费韭,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間庭瑰,已是汗流浹背星持。 一陣腳步聲響...
    開封第一講書人閱讀 33,390評論 1 271
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留弹灭,地道東北人督暂。 一個月前我還...
    沈念sama閱讀 48,798評論 3 376
  • 正文 我出身青樓揪垄,卻偏偏與公主長得像,于是被迫代替她去往敵國和親逻翁。 傳聞我的和親對象是個殘疾皇子饥努,可洞房花燭夜當晚...
    茶點故事閱讀 45,435評論 2 359