嵌套類
Java編程語言允許你在另一個類中定義類,這樣的類稱為嵌套類,如下所示:
class OuterClass { ... class NestedClass { ... } }
術(shù)語:嵌套類分為兩類:靜態(tài)和非靜態(tài),聲明為static的嵌套類稱為靜態(tài)嵌套類,非靜態(tài)嵌套類稱為內(nèi)部類。
class OuterClass { ... static class StaticNestedClass { ... } class InnerClass { ... } }
嵌套類是其封閉類的成員,非靜態(tài)嵌套類(內(nèi)部類)可以訪問封閉類的其他成員,即使它們被聲明為private,靜態(tài)嵌套類無權(quán)訪問封閉類的其他成員。作為OuterClass的成員,可以將嵌套類聲明為private、public、protected或包私有(回想一下,外部類只能聲明為public或包私有)。
為什么使用嵌套類?使用嵌套類的令人信服的理由包括:
這是一種邏輯分組僅在一個地方使用的類的方法:如果一個類只對另一個類有用,那么將它嵌入該類并將兩者保持在一起是合乎邏輯的,嵌套這樣的“幫助類”使得它們的包更加簡化。
它增加了封裝:考慮兩個頂級類A和B,其中B需要訪問A的成員,否則這些成員將被聲明為private,通過將類B隱藏在類A中,可以將A的成員聲明為私有,并且B可以訪問它們,另外,B本身也可以不被外界發(fā)現(xiàn)。
它可以使代碼更具可讀性和可維護(hù)性:在頂級類中嵌套小類會使代碼更接近于使用它的位置。
靜態(tài)嵌套類與類方法和變量一樣,靜態(tài)嵌套類與其外部類相關(guān)聯(lián),和靜態(tài)類方法一樣,靜態(tài)嵌套類不能直接引用其封閉類中定義的實(shí)例變量或方法:它只能通過對象引用來使用它們。
注意:靜態(tài)嵌套類與其外部類(和其他類)的實(shí)例成員交互,就像任何其他頂級類一樣,實(shí)際上,靜態(tài)嵌套類在行為上是一個頂級類,它已嵌套在另一個頂級類中以方便打包。
使用封閉的類名訪問靜態(tài)嵌套類:
OuterClass.StaticNestedClass
例如,要為靜態(tài)嵌套類創(chuàng)建對象,請使用以下語法:
OuterClass.StaticNestedClass nestedObject = new OuterClass.StaticNestedClass();內(nèi)部類
與實(shí)例方法和變量一樣,內(nèi)部類與其封閉類的實(shí)例相關(guān)聯(lián),并且可以直接訪問該對象的方法和字段,此外,由于內(nèi)部類與實(shí)例相關(guān)聯(lián),因此本身無法定義任何靜態(tài)成員。
作為內(nèi)部類的實(shí)例的對象存在于外部類的實(shí)例中,考慮以下類:
class OuterClass { ... class InnerClass { ... } }
InnerClass的實(shí)例只能存在于OuterClass的實(shí)例中,并且可以直接訪問其封閉實(shí)例的方法和字段。
要實(shí)例化內(nèi)部類,必須首先實(shí)例化外部類,然后,使用以下語法在外部對象中創(chuàng)建內(nèi)部對象:
OuterClass.InnerClass innerObject = outerObject.new InnerClass();
有兩種特殊的內(nèi)部類:局部類和匿名類。
遮蔽如果特定范圍(例如內(nèi)部類或方法定義)中的類型聲明(例如成員變量或參數(shù)名稱)與封閉范圍中的另一個聲明具有相同的名稱,然后聲明會影響封閉范圍的聲明,你不能僅通過其名稱引用遮蔽的聲明,以下示例ShadowTest演示了這一點(diǎn):
public class ShadowTest { public int x = 0; class FirstLevel { public int x = 1; void methodInFirstLevel(int x) { System.out.println("x = " + x); System.out.println("this.x = " + this.x); System.out.println("ShadowTest.this.x = " + ShadowTest.this.x); } } public static void main(String... args) { ShadowTest st = new ShadowTest(); ShadowTest.FirstLevel fl = st.new FirstLevel(); fl.methodInFirstLevel(23); } }
以下是此示例的輸出:
x = 23 this.x = 1 ShadowTest.this.x = 0
此示例定義了三個名為x的變量:ShadowTest類的成員變量、內(nèi)部類FirstLevel的成員變量、以及方法methodInFirstLevel中的參數(shù)。變量x定義為方法methodInFirstLevel的參數(shù)遮蔽內(nèi)部類FirstLevel的變量,因此,當(dāng)你在方法methodInFirstLevel中使用變量x時,它引用方法參數(shù),要引用內(nèi)部類FirstLevel的成員變量,請使用關(guān)鍵字this來表示封閉范圍:
System.out.println("this.x = " + this.x);
引用成員變量,這些成員變量根據(jù)所屬的類名包含更大的作用域,例如,以下語句從方法methodInFirstLevel訪問類ShadowTest的成員變量:
System.out.println("ShadowTest.this.x = " + ShadowTest.this.x);序列化
強(qiáng)烈建議不要對內(nèi)部類(包括局部類和匿名類)進(jìn)行序列化,當(dāng)Java編譯器編譯某些構(gòu)造(如內(nèi)部類)時,它會創(chuàng)建合成構(gòu)造,這些是類、方法、字段和其他在源代碼中沒有相應(yīng)構(gòu)造的構(gòu)造。合成構(gòu)造使Java編譯器能夠在不更改JVM的情況下實(shí)現(xiàn)new的Java語言功能,但是,合成構(gòu)造可以在不同的Java編譯器實(shí)現(xiàn)之間變化,這意味著.class文件也可以在不同的實(shí)現(xiàn)之間變化。因此,如果序列化內(nèi)部類,然后使用其他JRE實(shí)現(xiàn)反序列化,則可能存在兼容性問題,有關(guān)在編譯內(nèi)部類時生成的合成構(gòu)造的更多信息,請參閱獲取方法參數(shù)名稱一節(jié)中的隱式和合成參數(shù)部分。
內(nèi)部類示例要看內(nèi)部類的使用,首先要考慮一個數(shù)組,在下面的示例中,你將創(chuàng)建一個數(shù)組,用整數(shù)值填充它,然后僅按升序輸出數(shù)組的偶數(shù)索引值。
下面的DataStructure.java示例包括:
DataStructure外部類,它包含一個構(gòu)造函數(shù),用于創(chuàng)建DataStructure的實(shí)例,該實(shí)例包含一個數(shù)組,該數(shù)組填充了連續(xù)的整數(shù)值(0、1、2、3等等),以及一個方法,該方法打印具有偶數(shù)索引值的數(shù)組元素。
EvenIterator內(nèi)部類,它實(shí)現(xiàn)了繼承了Iterator< Integer>接口的DataStructureIterator接口,迭代器用于逐步執(zhí)行數(shù)據(jù)結(jié)構(gòu),通常有方法來測試最后一個元素,檢索當(dāng)前元素,然后移動到下一個元素。
實(shí)例化DataStructure對象(ds)的main方法,然后調(diào)用printEven方法來打印具有偶數(shù)索引值的數(shù)組arrayOfInts的元素。
public class DataStructure { // Create an array private final static int SIZE = 15; private int[] arrayOfInts = new int[SIZE]; public DataStructure() { // fill the array with ascending integer values for (int i = 0; i < SIZE; i++) { arrayOfInts[i] = i; } } public void printEven() { // Print out values of even indices of the array DataStructureIterator iterator = this.new EvenIterator(); while (iterator.hasNext()) { System.out.print(iterator.next() + " "); } System.out.println(); } interface DataStructureIterator extends java.util.Iterator{ } // Inner class implements the DataStructureIterator interface, // which extends the Iterator interface private class EvenIterator implements DataStructureIterator { // Start stepping through the array from the beginning private int nextIndex = 0; public boolean hasNext() { // Check if the current element is the last in the array return (nextIndex <= SIZE - 1); } public Integer next() { // Record a value of an even index of the array Integer retValue = Integer.valueOf(arrayOfInts[nextIndex]); // Get the next even element nextIndex += 2; return retValue; } } public static void main(String s[]) { // Fill the array with integer values and print out only // values of even indices DataStructure ds = new DataStructure(); ds.printEven(); } }
輸出是:
0 2 4 6 8 10 12 14
請注意,EvenIterator類直接引用DataStructure對象的arrayOfInts實(shí)例變量。
你可以使用內(nèi)部類來實(shí)現(xiàn)輔助類,例如本示例中所示的類,要處理用戶界面事件,你必須知道如何使用內(nèi)部類,因為事件處理機(jī)制會廣泛使用它們。
局部和匿名類還有兩種類型的內(nèi)部類,你可以在方法體內(nèi)聲明內(nèi)部類,這些類稱為局部類,你還可以在方法體內(nèi)聲明內(nèi)部類,而無需命名該類,這些類稱為匿名類。
修飾符你可以對用于外部類的其他成員的內(nèi)部類使用相同的修飾符,例如,你可以使用訪問修飾符private、public和protected來限制對內(nèi)部類的訪問,就像你使用它們來限制對其他類成員的訪問一樣。
上一篇:類的更多方面 下一篇:局部類文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/72337.html
使用包成員 組成包的類型稱為包成員。 要從其包外部使用公共包成員,你必須執(zhí)行以下操作之一: 通過其完全限定名稱引用該成員 導(dǎo)入包成員 導(dǎo)入成員的整個包 每種情況都適用于不同的情況,如以下各節(jié)所述。 通過其完全限定名稱引用包成員 到目前為止,本教程中的大多數(shù)示例都通過簡單名稱引用類型,例如Rectangle和StackOfInts,如果你編寫的代碼與該成員位于同一個包中,或者已導(dǎo)入該成員,則可以...
繼承 在前面的課程中,你已經(jīng)多次看到了繼承,在Java語言中,類可以從其他類派生,從而從這些類繼承字段和方法。 定義:從另一個類派生的類稱為子類(也是派生類,擴(kuò)展類或子類),派生子類的類稱為超類(也是基類或父類)。 除了Object沒有超類,每個類都有一個且只有一個直接超類(單繼承),在沒有任何其他顯式超類的情況下,每個類都隱式地是Object的子類。 類可以從派生自類的類派生的類派生,依此類推,...
摘要:所以看出和兩個的對應(yīng)指針數(shù)一樣,一個為一個為這就引出了變量的知識點(diǎn),如手工畫的圖二為啥強(qiáng)制子類父類變量名不同阿里巴巴手冊是這樣寫的強(qiáng)制避免在子父類的成員變量之間或者不同代碼塊的局部變量之間采用完全相同的命名方式,那會導(dǎo)致代碼可讀性降低。 摘要: 原創(chuàng)出處 https://www.bysocket.com 「公眾號:泥瓦匠BYSocket 」歡迎關(guān)注和轉(zhuǎn)載,保留摘要,謝謝! 目錄 父子...
Java? 教程 Java教程是為JDK 8編寫的,本頁面中描述的示例和實(shí)踐沒有利用在后續(xù)版本中引入的改進(jìn)。 Java教程是希望使用Java編程語言創(chuàng)建應(yīng)用程序的程序員的實(shí)用指南,其中包括數(shù)百個完整的工作示例和數(shù)十個課程,相關(guān)課程組被組織成教程。 覆蓋基礎(chǔ)知識的路徑 這些教程以書籍的形式提供,如Java教程,第六版,前往Amazon.com購買。 入門 介紹Java技術(shù)和安裝Java開發(fā)軟件并使用...
閱讀 950·2021-11-22 12:09
閱讀 3715·2021-09-27 13:36
閱讀 1407·2021-08-20 09:37
閱讀 4030·2019-12-27 12:22
閱讀 2367·2019-08-30 15:55
閱讀 2373·2019-08-30 13:16
閱讀 2832·2019-08-26 17:06
閱讀 3443·2019-08-23 18:32