摘要:外部類也可以直接訪問內(nèi)部類的所有屬性和方法。匿名內(nèi)部類為局部內(nèi)部類,所以局部內(nèi)部類的所有限制同樣對匿名內(nèi)部類生效。創(chuàng)建內(nèi)部類對象的時刻并不依賴于外圍類對象的創(chuàng)建。內(nèi)部類并沒有令人迷惑的關(guān)系,他就是一個獨立的實體。
基本概念
可以將一個類定義在另一個類里面或者一個方法里面,這樣的類稱為內(nèi)部類。
廣泛意義上的內(nèi)部類一般來說包括這四種:
成員內(nèi)部類
局部內(nèi)部類
靜態(tài)內(nèi)部類
匿名內(nèi)部類
成員內(nèi)部類成員內(nèi)部類是最普通的內(nèi)部類,它的定義為位于另一個類的內(nèi)部,形如下面的形式:
public class testDemo { public static void main(String[] args ) { Outer t = new Outer(); Outer.Inner in = t.new Inner(); // 必須先有外部類對象,才能創(chuàng)建內(nèi)部類 t.fun(); in.print(); } } class Outer { //外部類 private String msg = "hello world"; public void fun(){ Inner in = new Inner(); System.out.println(in.info); //外部類直接訪問內(nèi)部類的私有屬性 } class Inner{ //定義了一個成員內(nèi)部類 private String info = "世界,你好!"; public void print(){ System.out.println(msg); //內(nèi)部類直接訪問外部類的private屬性 } } }
成員內(nèi)部類可以無條件訪問外部類的所有屬性和方法(包括private成員和靜態(tài)成員)。外部類也可以直接訪問內(nèi)部類的所有屬性和方法。
成員內(nèi)部類是依附外部類而存在的,也就是說,如果要創(chuàng)建成員內(nèi)部類的對象,前提是必須存在一個外部類的對象
在外部類中如果要訪問成員內(nèi)部類的成員,必須先創(chuàng)建一個成員內(nèi)部類的對象,再通過指向這個對象的引用來訪問。
不過要注意的是,當成員內(nèi)部類擁有和外部類同名的成員變量或者方法時,會發(fā)生隱藏現(xiàn)象,即默認情況下訪問的是成員內(nèi)部類的成員。如果要訪問外部類的同名成員,需要以下面的形式進行訪問:
外部類.this.成員變量 外部類.this.成員方法局部內(nèi)部類
局部內(nèi)部類是定義在一個方法或者一個作用域里面的類,它和成員內(nèi)部類的區(qū)別在于局部內(nèi)部類的作用域僅限于方法內(nèi)或者該作用域內(nèi)。
public class testDemo { public static void main(String[] args ) { new Outer().fun(); } } class Outer { //外部類 private String msg = "hello world"; public void fun(){ class Inner{ //在方法中定義了一個局部內(nèi)部類 public void print(){ System.out.println(Outer.this.msg); //直接訪問外部類的private屬性 } } new Inner().print(); } }
注意:局部內(nèi)部類就像是方法里面的一個局部變量一樣。
在jdk1.7或之前的版本,如果局部內(nèi)部類要訪問方法中定義的參數(shù)、局部變量,那么參數(shù)和變量前一定要加上"final"修飾符。jdk1.8以及更新的版本則沒有這個限制。
public class testDemo { public static void main(String[] args ) { new Outer().fun(100); } } class Outer { //外部類 private String msg = "hello world"; public void fun(final int num){ final double score = 99.9; class Inner{ //在方法中定義了一個局部內(nèi)部類 public void print(){ System.out.println("屬性:"+Outer.this.msg); //直接訪問外部類的private屬性 System.out.println("方法參數(shù)"+ num); System.out.println("方法局部變量"+ score); } } new Inner().print(); } }靜態(tài)內(nèi)部類
使用static修飾的成員內(nèi)部類叫靜態(tài)內(nèi)部類。靜態(tài)內(nèi)部類是不需要依賴于外部類的,這點和類的靜態(tài)成員屬性有點類似,并且它不能訪問外部類的非static成員變量或者方法。
public class testDemo { public static void main(String[] args ) { Outer.Inner in = new Outer.Inner(); //靜態(tài)內(nèi)部類可以使用"外部類.內(nèi)部類"的方式使用 in.print(); } } class Outer { //外部類 static class Inner{ //定義了一個靜態(tài)內(nèi)部類 private String info = "世界,你好!"; public void print(){ System.out.println(info); } } }匿名內(nèi)部類
當某個子類只使用唯一一次的時候,沒有必要多帶帶定義出來,可以使用匿名內(nèi)部類的方法簡化代碼。
匿名內(nèi)部類就是沒有名字的局部內(nèi)部類。創(chuàng)建格式如下:
new 父類構(gòu)造器(參數(shù)列表)| 要實現(xiàn)的接口 () { //匿名內(nèi)部類的類體部分 //.... }
匿名內(nèi)部類是在抽象類和接口的基礎上發(fā)展而來的,其最大的好處是幫助減少了類的定義。
在使用匿名內(nèi)部類的過程中,我們需要注意如下幾點:
使用匿名內(nèi)部類時,我們必須是繼承一個類或者實現(xiàn)一個接口,但是兩者不可兼得,同時也只能繼承一個類或者實現(xiàn)一個接口。
匿名內(nèi)部類中是不能定義構(gòu)造函數(shù)的。
匿名內(nèi)部類中不能存在任何的靜態(tài)成員變量和靜態(tài)方法。
匿名內(nèi)部類為局部內(nèi)部類,所以局部內(nèi)部類的所有限制同樣對匿名內(nèi)部類生效。
匿名內(nèi)部類不能是抽象的,它必須要實現(xiàn)繼承的類或者實現(xiàn)的接口的所有抽象方法。
當所在的方法的形參需要被內(nèi)部類里面使用時,該形參必須為final(jdk1.8之后可省略)。
示例:
//接口 interface Inner { public String say(); } //抽象類 abstract class Inner1 implements Inner{ } //普通類 class Inner2 implements Inner{ public String say(){ return "this is Inner2"; } } class Outer { public void method1(Inner inner) { System.out.println(inner.say()); } } public class testDemo { public static void main(String[] args) { Outer outer = new Outer(); // 測試1,Inner為接口 outer.method1(new Inner() { String s1 = "this is s1 in Inner"; public String say() { // 外部類和匿名函數(shù)類中有同名變量s1 return s1; } }); // 測試2,Inner1為抽象類 outer.method1(new Inner1() { String s2 = "this is s2 in Inner1"; public String say() { // 外部類和匿名函數(shù)類中有同名變量s2 return s2; } }); //測試3, Inner2為普通類 outer.method1(new Inner2() { public String say() { return "this is inner2 overrite"; } }); } } 輸出結(jié)果: this is s1 in Inner this is s2 in Inner1 this is inner2 overrite內(nèi)部類的作用
為什么要使用內(nèi)部類?在《Think in java》中有這樣一句話:使用內(nèi)部類最吸引人的原因是:每個內(nèi)部類都能獨立地繼承一個(接口的)實現(xiàn),所以無論外圍類是否已經(jīng)繼承了某個(接口的)實現(xiàn),對于內(nèi)部類都沒有影響。
在我們程序設計中有時候會存在一些使用接口很難解決的問題,這個時候我們可以利用內(nèi)部類提供的、可以繼承多個具體的或者抽象的類的能力來解決這些程序設計問題。可以這樣說,接口只是解決了部分問題,而內(nèi)部類使得多重繼承的解決方案變得更加完整。內(nèi)部類最大的優(yōu)點就在于它能夠非常好的解決多重繼承的問題.
內(nèi)部類還能夠為我們帶來如下特性:
內(nèi)部類可以用多個實例,每個實例都有自己的狀態(tài)信息,并且與其他外圍對象的信息相互獨立。
在單個外圍類中,可以讓多個內(nèi)部類以不同的方式實現(xiàn)同一個接口,或者繼承同一個類。
創(chuàng)建內(nèi)部類對象的時刻并不依賴于外圍類對象的創(chuàng)建。
內(nèi)部類并沒有令人迷惑的“is-a”關(guān)系,他就是一個獨立的實體。
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://m.specialneedsforspecialkids.com/yun/73532.html
摘要:目錄介紹問題匯總具體問題好消息博客筆記大匯總年月到至今,包括基礎及深入知識點,技術(shù)博客,學習筆記等等,還包括平時開發(fā)中遇到的匯總,當然也在工作之余收集了大量的面試題,長期更新維護并且修正,持續(xù)完善開源的文件是格式的同時也開源了生活博客,從年 目錄介紹 00.Java問題匯總 01.具體問題 好消息 博客筆記大匯總【16年3月到至今】,包括Java基礎及深入知識點,Android技...
摘要:鄙人最近嘗試著翻譯了自己的第一篇英文技術(shù)文檔。如果我們需要在其他外部類中使用內(nèi)部類,則一定要將嵌套類聲明為或者。方法中的會覆蓋掉內(nèi)部類中的。因此,對于一個內(nèi)部類序列化后,使用不同的進行反序列化的話,可能會存在兼容性的問題。 鄙人最近嘗試著翻譯了自己的第一篇英文技術(shù)文檔。Java Nested Classes Reference From Oracle Documentation 嵌套類...
摘要:拆箱將包裝類型轉(zhuǎn)換為基本類型的過程。否則會拋出異常。默認采用單鏈表解決沖突,如果鏈表長度超過,將單鏈表轉(zhuǎn)換為紅黑樹。內(nèi)部使用紅黑樹實現(xiàn),存儲映射。紅黑樹減弱了對平衡的要求,降低了保持樹平衡需要的開銷,在實際應用中,統(tǒng)計性能超過平衡二叉樹。 引言 showImg(https://segmentfault.com/img/bVbv7Mr?w=242&h=410); 在學習《Java編程的邏...
摘要:可實現(xiàn)單例模式代碼塊初始化靜態(tài)變量,只被執(zhí)行一次內(nèi)部類不能與外部類重名,只能訪問外部類靜態(tài)數(shù)據(jù)包括私有多分支選擇整型或字符類型變量或整數(shù)表達式開始支持。 前言 大學期間接觸 Java 的時間也不短了,不論學習還是實習,都讓我發(fā)覺基礎的重要性。互聯(lián)網(wǎng)發(fā)展太快了,各種框架各種技術(shù)更新迭代的速度非常快,可能你剛好掌握了一門技術(shù)的應用,它卻已經(jīng)走在淘汰的邊緣了。 而學習新技術(shù)總要付出一定的時間...
摘要:請注意,應用程序類加載器的模型與此略有不同,如下所述,但主要原則是相同的。此類由加載器搜索的位置中的屬性定義。該服務器類加載器是唯一到內(nèi)部可見,并且是應用程序完全不可見。 Tomcat 7 類加載器是如何實現(xiàn)的 概述 與許多服務器應用程序一樣,Tomcat安裝了各種類加載器(即實現(xiàn)的類java.lang.ClassLoader),以允許容器的不同部分和容器上運行的Web應用程序訪問可用...
閱讀 3869·2023-04-26 00:36
閱讀 2676·2021-11-16 11:44
閱讀 1102·2021-11-15 17:58
閱讀 1674·2021-09-30 09:47
閱讀 1216·2019-08-30 13:05
閱讀 1550·2019-08-30 12:55
閱讀 2417·2019-08-30 11:02
閱讀 2739·2019-08-29 17:01