中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

怎么理解Java編程中的內部類

發布時間:2021-11-20 16:23:48 來源:億速云 閱讀:97 作者:柒染 欄目:編程語言

怎么理解Java編程中的內部類,針對這個問題,這篇文章詳細介紹了相對應的分析和解答,希望可以幫助更多想解決這個問題的小伙伴找到更簡單易行的方法。

內部類:在其它類內定義的類,不同于組合。雖然看上去象某種代碼隱藏機制,但可以實現更多功能 -了解包含它的類并可與之交換數據,而且內部類的代碼可以更優雅、清晰。

內部類定義:包含在其它類內。使用與非內部類沒有太大區別。

典型用法:outer class通過方法返回inner class的引用。

區別之一:內部類名嵌套在外部類(outer class)內,在Out class的non-static方法之外用OuterClassName.InnerClassName的形式定義內部類對象。

注意,非static內部類只能在Out class的non-static方法中生成對象;在其它類中,也必須使用Out class的外部類對象實例。這就保證了下面所說的鏈接問題。

區別之二:內部類可以為private和protected。

Inner Class只是一種名稱隱藏(name-hiding)和組織代碼方式?NO。

內部類對象有一個到創建它的外部類對象的鏈接(link to the enclosing object that made it),因而可以直接的、沒有任何限制地訪問該外部類對象的成員,而且內部類可以訪問outer class的所有成員(包括private)(C++的嵌套類沒有這個特性);而outer class訪問inner class的成員,必須創建Inner class的對象,可以訪問任何成員(包括private)。

內部類對象中隱式包含了一個外部類對象的引用。內部類對象構建需要outer class對象的引用,如果沒有,編譯報錯(非靜態inner class)。

.this和.new:前者用來返回Outer class引用,編譯期可知道和檢查正確類型,無運行時開銷;后者用來由outer class對象創建其內部類的對象,OutClassObject.new InnerClassName ()(注意,不能用outClassObj.new OutClassName.InnerClassName())。

嵌套類(nested class):static inner class,其對象創建不需要outer class對象引用,也可在static方法中創建。

內部類與upcasting

類實現了接口(interface),其它方法就可以用該interface作為參數,而不一定必須用該類(包括類對象定義)(類似繼承)。可以利用upcasting->interface。

upcasting內部類->基類或者接口(尤其是后者),使內部類有了用武之地。實現接口內部類可以完全不可見、不可用(通過private或protected),所獲得的只是基類或接口的引用(通過private,無法進行downcasting,protected,同一個包內,或者繼承類可以進行downcasting),方便隱藏實現細節。

接口成員自動為public

private內部類可以阻止任何依賴于類型的代碼,進行所有實現細節的隱藏。而且,擴展接口也沒有任何意義,因為無法訪問pubic接口之外的方法,這可以使JAVA產生更有效率的代碼 。

inner class可以在任意作用域內定義(如方法內)。

兩個理由:1. 實現一個接口

2. 需要一個不公開的類輔助解決復雜的問題

inner class形式

1. 方法內的內部類; 2. 方法中的一個作用域內的內部類; 3. 實現接口的匿名內部類; 4. 繼承的匿名內部類(基類含有參的構造器); 4. 進行成員初始化的匿名內部類; 5. 使用實例初始化塊進行構造的匿名內部類(匿名類沒有構造器)。

局部內部類(local inner class) :在方法內或方法的一個作用域中定義的內部類。局部內部類在域外不可見并不代表其對象也不可用。條件域內定義的內部類不代表它是條件創建的。

匿名內部類(anonymous inner class) :new T(){...}; {...}為匿名內部類的定義,";"不可少(;只是該語句的結束,而不是用來表示匿名內部類的結束,所以沒有什么特殊的地方),創建一個繼承自T的匿名類的對象,得到的引用可自動upcast to T。是前面定義內部類的一種簡寫,只是該類沒有名稱。

前面是基類構造器為默認構造器的情況,當基類構造器有參數時:new T(args){...};此時會調用基類相應構造器。

匿名內部類初始化 :當需要用到外部定義類的對象時,傳遞的引用參數必須為final,否則編譯報錯;匿名類不能有命名的構造器(當然不能,類本身就沒有名字),可以通過實例初始化(instance initialization)來完成構造器的功能。由于實例初始化不能重載(不代表只能有一個Instance initialization clause),所以匿名內部類只能有一個構造器。

匿名內部類只能在繼承類和實現接口中2選一,且只能實現一個接口。

prefer classes to interfaces. (寧愿選擇類,而不是接口?)

嵌套類(nested class):static inner class。有點類似C++嵌套類的概念,但Java的嵌套類可以訪問outer class的所有成員(包括private,當然只能通過外部類對象訪問non-static成員)。

1. 不需要通過outer class對象來創建嵌套類對象(.new不可用?);

2. 不能通過嵌套類對象訪問non-static outer class對象(意思是像非嵌套類那樣直接訪問);

3. 嵌套類對象中不包含outer class對象引用(.this不可用)。

4. 非嵌套內部類不能有static成員、方法和嵌套類(fields、methods級別必須與class本身一致,non-static不能含有static,non-static、static內可以含有non-static)。

嵌套類可以位于接口內部,不違反接口的規則(不能定義接口實例?),只代表把嵌套類位于接口的命名空間下,位于接口內部的類自動為public static(public嵌套類),而且嵌套類本身就可以實現該接口,好處在于可以在嵌套類內編寫該接口所有實現中都要用到的代碼。

嵌套類的另一個用途:編寫測試代碼。 為每個類編寫main函數增加代碼長度,可以把main放在嵌套類內,要測試該類運行該嵌套類即可;而在發布的時候只要在打包前簡單的刪除該嵌套類的.class文件即可。

多重嵌套的類(non-static和static)可以沒有限制的訪問任何外層類的所有對象。

為什么用內部類?

不是總是直接和接口打交道,有時候需要用的是接口的實現。(可以實現多個接口,但不能繼承多個類)

理由:每個內部類可以獨立繼承自一個實現,不受outer class是否已經繼承另一實現的限制。從效果上來說,inner class提供了多繼承(multiple-inheritance,繼承自多個類)的能力,提供了另一種實現多個接口的方法(相比多繼承,這個似乎沒那么重要,因為多繼承只能通過內部類來實現)。

額外特性:

1. 內部類可以有多個實例,每個實例可以擁有獨立于outer class對象的不同信息;

2. 一個outer class可以有多個內部類,每個內部類可以以不同的方式實現同一個接口或者繼承同一個類(參見習題22,兩個內部類不同方式實現同一個接口,只有內部類才能完成這些);

3. 內部類實例創建時間并不受到外部類對象創建的限制;

4. 用內部類不會制造"is-a"關系的混亂,每個內部類都是個實體。

閉包(closure)和回調(callback)

閉包是一種可調用的對象,它記錄了來自創建它的作用域的一些信息。

內部類是一種面向對象的閉包,不僅包含了外部類的信息,而且通過包含一個指向外部類對象的引用,可以操作所有成員,包括private。

回調,通過其它對象攜帶的信息,可以在稍后的某個時刻調用初始對象。

Java不支持指針類型,不能通過指針來實現回調。但內部類提供的閉包是種比較好的解決方案,更靈活,更安全(參見例callbacks)。

private class Closure implements Incrementable {       public void increment() {       // Specify outer-class method, otherwise       // you’d get an infinite recursion:           Callee2.this.increment();       }   }

回調的價值在于靈活性,可以在運行時決定需要調用的方法。 GUI編程將體現得更明顯。

內部類與控制框架(control frameworks)

一個應用程序框架(application framework)是指一個用來解決一個特定類型問題的類或類的集合。典型的應用方法是,繼承其中一個或多個類,重寫某些方法。重寫方法的代碼將通用解決方案特殊化,來解決特定問題。例如模板函數模式。 設計模式將不變的和變化的事情分開。

控制框架是用來響應事件的一類特殊的應用程序框架 。主要用來響應事件的系統稱為事件驅動系統(event-driven system),如GUI。

內部類使得控制框架的創建和使用變得簡單 。控制框架本身不包括要控制的事物的特定信息。這些信息在繼承過程中,由算法的action()部分實現時提供。控制框架中變化的事情是各種事件對象的不同action,這通過創建不同event繼承類來實現。(例event)

控制事件用abstract類代替接口?

內部類在控制框架中兩個作用:

1. 用來表示解決問題所需的各種不同的action()。

2. 內部類可以直接訪問外部類的所有成員,因而使得實現變得更靈活。

參見greenhouse(溫室)的例子。

內部類的繼承

內部類指向outer class object的引用必須初始化,而在它的繼承類中并不存在要聯接的缺省對象,必須使用特殊的語法明確指出這種關聯。

繼承自內部類的類構造器不能是默認構造器,要有個outer class的引用作為參數,而且必須加上enclosingClassReference.super();語句,編譯才能通過。

內部類能override?繼承outer class,像重寫方法一樣重寫內部類并不起作用,此時兩個內部類只是兩個獨立的實體。可以顯式指定內部類的繼承關系,然后通過復寫base inner class的方法,來實現多態。 參見例BigEgg2.

//: innerclasses/BigEgg2.java   // Proper inheritance of an inner class.   import static net.mindview.util.Print.*;   class Egg2 {       protected class Yolk {         public Yolk() { print("Egg2.Yolk()"); }         public void f() { print("Egg2.Yolk.f()");}   }       private Yolk y = new Yolk();       public Egg2() { print("New Egg2()"); }       public void insertYolk(Yolk yy) { y = yy; }       public void g() { y.f(); }   }   public class BigEgg2 extends Egg2 {       public class Yolk extends Egg2.Yolk {           public Yolk() { print("BigEgg2.Yolk()"); }           public void f() { print("BigEgg2.Yolk.f()"); }   }       public BigEgg2() { insertYolk(new Yolk()); }       public static void main(String[] args) {           Egg2 e2 = new BigEgg2();           e2.g();   }   } /* Output:   Egg2.Yolk()   New Egg2()   Egg2.Yolk()   BigEgg2.Yolk()   BigEgg2.Yolk.f()   *///:~

局部內部類

局部內部類(local inner class)不能有訪問限定符;有訪問局部final變量和outer class所有類的權限;可以有命名的構造器;在方法外不能訪問。

絕大部分情況下,可以用匿名類來替代局部內部類,除非:

1. 需要命名的構造器,或者需要重載構造器

2. 需要多個內部類的對象

此時就要用Local Inner class。

關于怎么理解Java編程中的內部類問題的解答就分享到這里了,希望以上內容可以對大家有一定的幫助,如果你還有很多疑惑沒有解開,可以關注億速云行業資訊頻道了解更多相關知識。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

武穴市| 独山县| 襄汾县| 南部县| 白银市| 高平市| 司法| 界首市| 介休市| 赤峰市| 宣化县| 班戈县| 宁都县| 贵南县| 宜宾市| 时尚| 淄博市| 璧山县| 兴和县| 郁南县| 贵德县| 潞城市| 湖南省| 海口市| 邻水| 潞西市| 乌拉特前旗| 襄垣县| 孟州市| 新昌县| 南部县| 新野县| 聂荣县| 如东县| 濉溪县| 汽车| 喀喇| 贺州市| 溆浦县| 尚志市| 和田市|