日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > java >内容正文

java

【Java】6.7 内部类

發布時間:2025/3/20 java 18 豆豆
生活随笔 收集整理的這篇文章主要介紹了 【Java】6.7 内部类 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

目錄

非靜態內部類

靜態內部類

使用內部類

局部內部類

匿名內部類


【內部類是什么?】

內部類 ——?就是把一個類放在類里面定義

內部類 -?寄生類

外部類 -?宿主類

內部類,由于踏上一級程序單元是類,因此他完全可以使用?private |?protected |?默認 |?public?這四個訪問控制符

由于內部的上一級程序單元是類,可以用 static?修飾。有?static?修飾的類屬于外部類本身;沒有?static?修飾的類屬于外部類的實例。

【為什么要引入內部類?】

  • 為了更好地封裝,可以把內部類隱藏在外部類中,不允許同一個包內其他類來訪該類(在該類內有效,在其他類無用處)
  • 內部類成員可以直接訪問外部類的私有數據
  • 匿名內部類適合用于創建那些僅需要使用一次的類
  • 【注意】非靜態外部類不能擁有靜態內部類。(為什么?)【注釋4】

    ?

    【如何使用內部類?】

    非靜態內部類

    內部類有一個好處:他可以直接訪問外部類的?private?成員(field/方法/構造器);反過來,外部類不能訪問內部類成員

    • 若是沒有?static?修飾的內部類的實例,必須寄生在“外部類”的對象里。
    • 若有 static?修飾的內部類的實例,寄生在“外部類”的類本身里

    以下代碼表明。調用寄生實例方法之前,必須創建宿主實例

    /** * @ClassName: Cow* @description: * @author:FFIDEAL* @Date: 2020年2月27日22:30:24*/ public class Cow {private double weight;public Cow() {}public Cow(double weight) {this.weight = weight;}// 定義一個非靜態內部類private class CowLeg {// 定義兩個非靜態類實例private double length;private String color;public CowLeg() {}public CowLeg(double length, String color) {this.length = length;this.color = color;}public double getLength() {return length;}public void setLength(double length) {this.length = length;}public String getColor() {return color;}public void setColor(String color) {this.color = color;}// 創建非靜態內部類的實例方法public void info() {System.out.println("當前牛腿的顏色是" + color + ",牛腿的長度為" + length);// 可以調用當前外部類的private修飾的成員變量System.out.println("當前牛的體重是:" + weight);}}// 在非靜態內部類中,要創建內部類的實例,首先要創建宿主實例public void test() {CowLeg c1 = new CowLeg(1.12, "黃色");c1.info();}public static void main(String[] args) {Cow cow = new Cow(112.6);cow.test();} }

    非靜態內部類,也屬于非靜態成員 ——?因為不能被外部靜態成員所訪問

    【若查找某個變量時】

    當在非靜態內部類的方法訪問某個變量時:在該方法內查找 ->?在方法所在類中查找 ->?在該類的外部類查找 ->系統出現編譯錯誤

    /** * @ClassName: DiscernVariable* @description: 描述內部類調用外部類成員變量、內部類成員變量和局部成員變量時的語句* @author: FFIDEAL* @Date: 2020年2月27日 下午10:37:29*//*** @author dell**/ public class DiscernVariable {private String prop = "我在早上學習Java!";// 創建內部類private class InClass {private String prop = "我在中午學習Java!";// 創建內部類的一個測試方法public void info() {String prop = "我在晚上學習Java!";// 通過外部類名.this.varName訪問外部類實例變量System.out.println("外部類的實例變量值為" + DiscernVariable.this.prop);// 通過this.varName訪問外部類實例變量System.out.println("內部類的實例變量值為" + this.prop);// 直接訪問局部變量System.out.println("局部變量值為" + prop);}}// 創建一個方法用于創建內部類的實例public void test() {InClass ic = new InClass();ic.info();}// 創建一個宿主實例,用宿主實例調用上述方法public static void main(String[] args) {DiscernVariable dv = new DiscernVariable();dv.test();} }

    【注意】在非靜態內部類中,所有的方法、成員變量都屬于實例的。所以在創建內部實例之前,若沒有外部類,則無法獲得外部宿主實例。反之,在static修飾的內部類中,在運行時,已經加載了外部類,存在了宿主類,就可以創建內部靜態類的對象,該對象寄生在外部類中

    ?

    靜態內部類

    靜態內部類有?static?修飾,寄生在“外部類”的類本身里,而不屬于任何外部類的實例。靜態內部類可以包含靜態成員,也可以包含非靜態成員。但是靜態內部類的實例方法,也是屬于靜態成員,因此他不能訪問外部類的非靜態成員。

    • 以上為什么不能用類名調用?【注釋5】
    /** * @ClassName: StaticInnerClassTest* @description:靜態內部類的實例方法也不能訪問外部類的實例方法,只能訪問外部類的靜態成員* @author: FFIDEAL* @Date: 2020年2月27日 下午11:02:48*/public class StaticInnerClassTest {private String str1 = "這是非靜態字符串";private static String str2 = "這是靜態字符串";static class StaticInnerClass {// 靜態內部類可以包含靜態成員private static int age;public void access() {// System.out.println(str1);代碼錯誤。靜態內部類不能訪問外部類的非靜態成員變量System.out.println(str2);}}public static void main(String[] args) {new StaticInnerClass().access();} }

    ?

    使用內部類

  • 定義變量
  • 創建實例
  • 訪問它的類?field/類方法
  • 【在外部類以內使用內部類】

    若在外部類的里面,使用內部類。并沒有太多需要注意的地方。只需要指導不要在外部類的靜態成員中使用非靜態外部類,因為靜態成員不能訪問非靜態成員。

    【在外部類以外使用非靜態內部類】

  • 聲明變量:外部類.內部類?變量名
  • 創建非靜態內部類的實例:在此之前,必須先創建外部類的實例 ——?必須先創建宿主。接下來用“宿主.new?外部類構造器()”
  • 非靜態內部類派生子類:由于子類的構造器,必須調用父類的構造器一次,因此必須在子類構造器中使用宿主對象去調用非靜態內部類的構造器
  • /** * @ClassName: CreateInnerInstance* @description: 在外部類以外使用非靜態內部類* @author: FFIDEAL* @Date: 2020年2月29日 下午1:00:46*/class Out{//創建一個非靜態內部類class In{public In(String msg) {System.out.println("調用一個內部類構造器,傳進的參數是:"+msg);}} } public class CreateInnerInstance {public static void main(String[] args) {Out.In in = new Out().new In("在學習Java的時候不要忘記學習Java虛擬機");/*Out類中的in類,先new一個Out類的對象,在new一個In的對象,這樣就有宿主了* 相當于* 使用OutClass.InnerClass的形式調用內部類變量* Out.In in;* 創建外部類宿主對象* Out out = new Out();* 通過外部類實例和new來調用內部類構造器創建非靜態內部類實例* in = out.new In("在學習Java的時候不要忘記學習Java虛擬機");*/} }

    【在外部類以外使用非靜態內部類】

  • 靜態內部類它是寄生外部類的類本身里面的,所以一般不需要程序員去理會宿主,可以把外部類當做靜態內部類的包就行了。只需要外部類就可以調用構造器了。
  • /** * @ClassName: CreateStaticInnerClassTest* @description: 測試在外部類以外使用靜態內部類* @author: FFIDEAL* @Date: 2020年2月29日 下午1:17:32*/class StaticOut{//創建一個靜態內部類static class StaticInner{public StaticInner() {System.out.println("靜態內部類構造器");}} }public class CreateStaticInnerClassTest {public static void main(String[] args) {new StaticOut.StaticInner();} }

    局部內部類

    局部內部類是一個局部成員,和局部變量相似,因此不能用 static 、訪問控制符修飾。局部內部類用?final?修飾是可以的,辨明該局部內部類不能被繼承。局部內部類的作用域實在是太有限了 ——?除了方法就不能使用了。由于局部內部類只能在當前方法中使用,因此使用起來比較簡單。局部內部類的class名為:外部類$N個內部類.class(為什么要有N)【見注釋1】

    ?

    匿名內部類

    它是沒有名字的內部類,所以程序以后無法再訪問這個“匿名內部類”。當程序創建匿名內部類時,會立即創建匿名內部類的實例。

    //匿名內部類的語法new 接口() | 父類構造器(參數){//類主體 }// —— 上述語法格式實際上返回匿名內部類的實例。程序以后只能使用匿名內部類的實例

    ?

    /** * @ClassName: AnonymousTest* @description: 實現接口來創建內部類:new 實現接口* @author: FFIDEAL* @Date: 2020年2月29日 下午2:33:10*/interface Products{public double getPrice();public String getName(); }public class AnonymousTest {//需要傳入一個Product實例public void test(Products p) {System.out.println("購買一個"+p.getName()+",話費了"+p.getPrice());}public static void main(String[] args) {AnonymousTest at = new AnonymousTest();at.test(new Products() {public double getPrice() {return 5560;}public String getName(){return "華為手機";}});} }

    ?

    /** * @ClassName: AnonymousInner* @description: 繼承父類創建內部類:new 實現接口,匿名內部類將擁有和父類相似的構造器* @author: FFIDEAL* @Date: 2020年2月29日 下午6:30:06*/ abstract class Device{private String name;public abstract double getPrice();public Device() {}public Device(String name) {this.name = name;}public void setName(String name) {this.name = name;}public String getName() {return name;}}public class AnonymousInner {public void test(Device d) {System.out.println("又買了一個"+d.getName()+",花掉了"+d.getPrice());}public static void main(String[] args) {AnonymousInner ai = new AnonymousInner();//調用有參數的構造器創建Device的匿名類實例對象ai.test(new Device("示波器"){public double getPrice() {return 55.6;}});//調用無參數的構造器Device d = new Device() {//初始化塊{System.out.println("匿名內部類的初始化塊");}//實現抽象方法public double getPrice() {return 56.2;}//重寫父類的方法public String getName() {return "鍵盤";}};ai.test(d);} }

    【匿名內部類的規則】

  • 匿名內部類必須顯式繼承一個父類,或實現【一個】接口
  • 匿名內部類必須實現接口或抽象類中所有抽象方法(為什么?)【見注釋2】
  • 匿名內部類不能有構造器?(為什么?)【見注釋3】
  • 【注釋1】因為一個外部類,不同方法中可以定義多個同名的局部內部類

    【注釋2】因為匿名內部類需要立即創建市里,因此他不能是抽象的

    【注釋3】因為匿名內部類沒有名字,構造器名字不能確定

    【注釋4】首先靜態成員不能訪問非靜態成員。若靜態內部類位于非靜態外部類之內,那么靜態內部類不能訪問外部類,且那就失去了靜態內部類存在的意義。

    【注釋5】因為類中的static是屬于類本身的。但是static修飾類就與里面非static修飾的方法無關。該方法依然是非靜態方法。靜態內部類屬于外部類而已。非靜態內部類屬于內部類實例。但創建這個內部類實例之前,要確保有外部類的實例這個宿主存在

    總結

    以上是生活随笔為你收集整理的【Java】6.7 内部类的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。