摘要:每個內(nèi)部類都能獨立地繼承一個接口,而無論外部類是否已經(jīng)繼承了某個接口。因此,內(nèi)部類使多重繼承的解決方案變得更加完整。內(nèi)部類中的與其他類一樣是指的本身。但是靜態(tài)內(nèi)部類卻沒有。
問題:內(nèi)部類、靜態(tài)內(nèi)部類區(qū)別、使用場景?
一、什么是內(nèi)部類?(一般)1.靜態(tài)內(nèi)部類可以有靜態(tài)成員(方法,屬性),而非靜態(tài)內(nèi)部類則不能有靜態(tài)成員(方法,屬性)。
2.靜態(tài)內(nèi)部類只能夠訪問外部類的靜態(tài)成員,而非靜態(tài)內(nèi)部類則可以訪問外部類的所有成員(方法,屬性)。
3.實例化方式不同:
(1)實例化成員內(nèi)部類“”
通過外部類對象創(chuàng)建
OutClassTest oc1 = new OutClassTest();
OutClassTest.InnerClass no_static_inner = oc1.new InnerClass();
(2)實例化靜態(tài)內(nèi)部類:
OutClassTest.InnerStaticClass inner = new OutClassTest.InnerStaticClass();3.訪問內(nèi)部類成員屬性不同:
(1)外部類訪問內(nèi)部類屬性和方法:
外部類可以通過內(nèi)部類引用間接訪問內(nèi)部類元素 類似:new IN().inMessage()
(2)外部類訪問靜態(tài)內(nèi)部類:
調(diào)用內(nèi)部靜態(tài)類的方法或靜態(tài)變量,通過類名直接調(diào)用
OutClassTest.InnerStaticClass.static_value
OutClassTest.InnerStaticClass.getMessage()
6.為何要用內(nèi)部類?內(nèi)部類可以訪問外部類的所有成員,包括私有屬性。
方便將存在一定邏輯關系的類組織在一起,又可以對外界隱藏。
每個內(nèi)部類都能獨立地繼承一個接口,而無論外部類是否已經(jīng)繼承了某個接口。因此,內(nèi)部類使多重繼承的解決方案變得更加完整。
7.內(nèi)部類的使用場景:
詳情查看:http://blog.csdn.net/hivon/ar...
場景一:當某個類除了它的外部類,不再被其他的類使用時
場景二:解決一些非面向對象的語句塊
場景三:一些多算法場合
場景四:適當使用內(nèi)部類,使得代碼更加靈活和富有擴展性
在一個類Out的內(nèi)部定義一個類in,這個類就是內(nèi)部類,相應的Out就成為外部類。
二、內(nèi)部類與外部類的聯(lián)系1、內(nèi)部類是一個編譯時概念,編譯后外部類及其內(nèi)部類會生成兩個獨立的class文件: OuterClass.class和OuterClass$InnerClass.class三、內(nèi)部類的分類2、內(nèi)部類可以直接訪問外部類的元素,但是外部類不可以直接訪問內(nèi)部類的元素
3、外部類可以通過內(nèi)部類引用間接訪問內(nèi)部類元素
4、對于靜態(tài)內(nèi)部類來說,靜態(tài)內(nèi)部類是不依賴于外部類的,也就說可以在不創(chuàng)建外部類對象的情況下創(chuàng)建內(nèi)部類的對象。另外,靜態(tài)內(nèi)部類是不持有指向外部類對象的引用的
成員內(nèi)部類、局部內(nèi)部類、匿名內(nèi)部類、靜態(tài)內(nèi)部類。
成員內(nèi)部類就是普通的內(nèi)部類,內(nèi)部類可以聲明public、protected、private等訪問限制,可以聲明 為abstract的供其他內(nèi)部類或外部類繼承與擴展,或者聲明為static、final的,也可以實現(xiàn)特定的接口。如果成員內(nèi)部類用private修飾,則只能在外部類的內(nèi)部訪問,如果用public修飾,則任何地方都能訪問;如果用protected修飾,則只能在同一個包下或者繼承外部類的情況下訪問;
如果是默認訪問權限,則只能在同一個包下訪問。這一點和外部類有一點不一樣,外部類只能被public和包訪問兩種權限修飾。外部類按常規(guī)的類訪問方式使用內(nèi)部類,唯一的差別是外部類可以訪問內(nèi)部類的所有方法與屬性,包括私有方法與屬性。
內(nèi)部類中的this與其他類一樣是指的本身。創(chuàng)建內(nèi)部類對象時,它會與創(chuàng)造它的外圍對象有了某種聯(lián)系,于是能訪問外圍類的所有成員,不需任何特殊條件,可理 解為內(nèi)部類鏈接到外部類。 用外部類創(chuàng)建內(nèi)部類對象時,此內(nèi)部類對象會秘密的捕獲一個指向外部類的引用,于是,可以通過這個引用來訪問外圍類的成員。
局部內(nèi)部類是定義在一個方法或者一個作用域里面的類,它和成員內(nèi)部類的區(qū)別在于局部內(nèi)部類的訪問僅限于方法內(nèi)或者該作用域內(nèi)。
匿名內(nèi)部類其實就是一個沒有名字的方法內(nèi)部類,所以它符合方法內(nèi)部類的所有約束,初次之外,還有一些地方需要注意:匿名內(nèi)部類是沒有訪問修飾符的。
匿名內(nèi)部類必須繼承一個抽象類或者實現(xiàn)一個接口
匿名內(nèi)部類中不能存在任何靜態(tài)成員或方法
匿名內(nèi)部類是沒有構造方法的,因為它沒有類名。
一般使用匿名內(nèi)部類的場景是,要繼承或實現(xiàn)的接口只有一個抽象方法:
代碼來自[https://www.cnblogs.com/CodingAndRiding/p/7441438.html][2] public class Test { public static void main(String[] args) { //4.匿名內(nèi)部類 //主要是針對那些不能直接創(chuàng)建對象的抽象類和接口而來的 Student stu=new Student(); System.out.println(stu.getClass());//class com.aowin.noname.Student //4.1.通過實體類創(chuàng)建匿名內(nèi)部類對象 //相當于創(chuàng)建該類的一個子類對象 Person p=new Person(){ public void eat(){ System.out.println("吃八元套餐"); } }; p.eat(); System.out.println(p.getClass());//class com.aowin.noname.Test$1//系統(tǒng)自動為子類命名Test$1 Dog dog=new Dog(); dog.bark(); //4.2.通過抽象類創(chuàng)建匿名內(nèi)部類對象 //相當于定義了該抽象類的一個子類對象,并重寫了抽象類中所有的抽象方法 Animal an=new Animal(){ public void bark(){ System.out.println("汪汪汪..."); } }; an.bark(); //返回的是包名加類名 System.out.println(an.getClass());//class com.aowin.noname.Test$2 //4.3.通過接口創(chuàng)建匿名內(nèi)部類對象 //相當于定義了該接口的一個實現(xiàn)類對象,并重寫了接口中所有的抽象方法 Sportable s=new Sportable(){ public void sport(){ System.out.println("打籃球"); } }; s.sport(); System.out.println(s.getClass());//class com.aowin.noname.Test$3 } } //實體類 class Person{ public void eat(){ System.out.println("吃飯"); } } class Student extends Person{ public void eat(){ System.out.println("吃八元套餐"); } } //抽象類 abstract class Animal{ public abstract void bark(); } class Dog extends Animal{ public void bark() { System.out.println("汪汪..."); } } //接口 interface Sportable{ public abstract void sport(); }
關鍵字static可以修飾成員變量、方法、代碼塊,其實它還可以修飾內(nèi)部類,使用static修飾的內(nèi)部類我們稱之為靜態(tài)內(nèi)部類。
靜態(tài)內(nèi)部類與非靜態(tài)內(nèi)部類之間存在一個最大的區(qū)別,我們知道非靜態(tài)內(nèi)部類在編譯完成之后會隱含地保存著一個引用,該引用是指向創(chuàng)建它的外圍內(nèi)。
但是靜態(tài)內(nèi)部類卻沒有。沒有這個引用就意味著:靜態(tài)內(nèi)部類的創(chuàng)建是不需要依賴于外圍類,可以直接創(chuàng)建
靜態(tài)內(nèi)部類不可以使用任何外圍類的非static成員變量和方法,而內(nèi)部類則都可以
private static String outerName; public int age; static class InnerClass1{ /* 在靜態(tài)內(nèi)部類中可以存在靜態(tài)成員 */ public static String _innerName = "static variable"; public void display(){ /* * 靜態(tài)內(nèi)部類只能訪問外部類的靜態(tài)成員變量和方法 * 不能訪問外部類的非靜態(tài)成員變量和方法 */ System.out.println("OutClass name :" + outerName); } } class InnerClass2{ /* 非靜態(tài)內(nèi)部類中不能存在靜態(tài)成員 */ public String _innerName = "no static variable"; /* 非靜態(tài)內(nèi)部類中可以調(diào)用外部類的任何成員,不管是靜態(tài)的還是非靜態(tài)的 */ public void display(){ System.out.println("OuterClass name:" + outerName); System.out.println("OuterClass age:" + age); } } public void display(){ /* 外部類能直接訪問靜態(tài)內(nèi)部類靜態(tài)元素 */ System.out.println(InnerClass1._innerName); /* 靜態(tài)內(nèi)部類可以直接創(chuàng)建實例不需要依賴于外部類 */ new InnerClass1().display(); /* 非靜態(tài)內(nèi)部的創(chuàng)建需要依賴于外部類 */ OuterClass.InnerClass2 inner2 = new OuterClass().new InnerClass2(); /* 非靜態(tài)內(nèi)部類的成員需要使用非靜態(tài)內(nèi)部類的實例訪問 */ System.out.println(inner2._innerName); inner2.display(); } public static void main(String[] args) { OuterClass outer = new OuterClass(); outer.display(); } }四、內(nèi)部類和外部類的相互訪問
1、內(nèi)部類訪問外部類成員
當成員內(nèi)部類擁有和外部類同名的成員變量或者方法時,會發(fā)生隱藏現(xiàn)象,即默認情況下訪問的是成員內(nèi)部類的成員。如果要訪問外部類的同名成員,需要以下面的形式進行訪問:
外部類.this.成員變量
外部類.this.成員方法
但是靜態(tài)內(nèi)部類,只能訪問外部類的靜態(tài)成員
2、外部類訪問內(nèi)部類成員
外部類可以通過內(nèi)部類引用間接訪問內(nèi)部類元素
外部類中如果要訪問成員內(nèi)部類的成員,必須先創(chuàng)建一個成員內(nèi)部類的對象,再通過指向這個對象的引用來訪問:
外部類訪問內(nèi)部類: new In().inMessage(); //必須先創(chuàng)建內(nèi)部類的對象,再訪問 class In{ //內(nèi)部類 public void inMessage() { System.out.println("外部類訪問"); //外部類的private成員 } }
3、靜態(tài)內(nèi)部類與外部類的訪問(相當于嵌套類)
(1)靜態(tài)內(nèi)部類訪問外部類: 只能訪問外部類的靜態(tài)成員,不能訪問非靜態(tài)成員!
(2)外部類訪問靜態(tài)內(nèi)部類成員:可以直接訪問,內(nèi)部類名.屬性(方法)
參考:
https://www.cnblogs.com/latte...
http://blog.csdn.net/hivon/ar...
文章版權歸作者所有,未經(jīng)允許請勿轉載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉載請注明本文地址:http://systransis.cn/yun/68600.html
摘要:對于一個名為的外圍類和一個的內(nèi)部類,在編譯成功后,會出現(xiàn)這樣兩個文件和。 Java知識點總結(三個步驟) @(Java知識點總結)[Java, Java面向對象] [toc] 1-定義類 修飾符 訪問修飾符: public protected default private 其他修飾符 abstract:抽象類不能實例化,專門用于繼承的類final:最終類不能被繼承 類名(駝峰命名...
摘要:方法內(nèi)部類就是局部內(nèi)部類,一般定義在類的局部位置,它可以訪問當前代碼塊及外部類的所有變量。 今天溫習一下 Java 中的內(nèi)部類,內(nèi)部類一般有如下幾種:靜態(tài)內(nèi)部類、成員內(nèi)部類、匿名內(nèi)部類和方法內(nèi)部類,下文中將主要介紹靜態(tài)內(nèi)部類和成員內(nèi)部類,主要內(nèi)容如下: 概述 靜態(tài)內(nèi)部類 成員內(nèi)部類 匿名內(nèi)部類和方法內(nèi)部類 總結 概述 顧名思義內(nèi)部類就是在一個類內(nèi)部定義的類,它是內(nèi)部類是一個獨立的類...
摘要:基礎問題的的性能及原理之區(qū)別詳解備忘筆記深入理解流水線抽象關鍵字修飾符知識點總結必看篇中的關鍵字解析回調(diào)機制解讀抽象類與三大特征時間和時間戳的相互轉換為什么要使用內(nèi)部類對象鎖和類鎖的區(qū)別,,優(yōu)缺點及比較提高篇八詳解內(nèi)部類單例模式和 Java基礎問題 String的+的性能及原理 java之yield(),sleep(),wait()區(qū)別詳解-備忘筆記 深入理解Java Stream流水...
閱讀 3110·2021-08-03 14:05
閱讀 2154·2019-08-29 15:35
閱讀 691·2019-08-29 13:30
閱讀 3180·2019-08-29 13:20
閱讀 2545·2019-08-23 18:15
閱讀 1810·2019-08-23 14:57
閱讀 2230·2019-08-23 13:57
閱讀 1325·2019-08-23 12:10