零基礎學Java第十八講---抽象類和接口(3)

?????????續接上一講

目錄

一、內部類

1、內部類的分類

2、靜態內部類

3、實例內部類---未被static修飾的成員內部類

4、局部內部類

5、匿名內部類

二、Object類

1、獲取對象信息

2、equals方法

3、hashcode方法


一、內部類

????????當?個事物的內部,還有?個部分需要?個完整的結構進行描述,而這個內部的完整的結構又只為外部事物提供服務,那么這個內部的完整結構最好使用內部類。在Java中,可以將?個類定義在另?個類或者?個方法的內部,前者稱為內部類,后者稱為外部類。內部類也是封裝的?種體現。

 public class OutClass {class InnerClass{}}// OutClass是外部類 // InnerClass是內部類 

#注:

(1)定義在class類名{ }花括號外部的,即使是在?個文件里,都不能稱為內部類

public class A{}class B{}// A 和 B是兩個獨?的類,彼此之前沒有關系 

(2)內部類和外部類共用同?個java源文件,但是經過編譯之后,內部類會形成單獨的字節碼文件

1、內部類的分類

public class OutClass {// 成員位置定義:未被static修飾 --->實例內部類 public class InnerClass1{}// 成員位置定義:被static修飾 ---> 靜態內部類 static class InnerClass2{}public void method(){// ?法中也可以定義內部類 ---> 局部內部類:?乎不? class InnerClass5{}}
}

根據內部類定義的位置不同,?般可以分為以下幾種形式:

(1)成員內部類(普通內部類:未被static修飾的成員內部類和靜態內部類:被static修飾的成員內部類)

(2)局部內部類(不談修飾符)、匿名內部類

#注:內部類其實日常開發中使用并不是非常多,大家在看?些庫中的代碼時候可能會遇到的比較 多,日常開始中使用最多的是匿名內部類。

2、靜態內部類

public class OutClass {public int a;public static int b;// 靜態內部類:被static修飾的成員內部類 static class InnerClass{public void methodInner(){// 在內部類中只能訪問外部類的靜態成員 // a = 100;      // 編譯失敗,因為a不是類成員變量 b =200;}}public static void main(String[] args) {// 靜態內部類對象創建 & 成員訪問 OutClass.InnerClass innerClass = new OutClass.InnerClass();innerClass.methodInner();}}

#注:

(1)在靜態內部類中只能訪問外部類中的靜態成員

? ? ? ? ? 如果確實想訪問,我們該如何做?

方法一:通過外部類實例傳遞

class OuterClass {private int nonStaticField = 10;private static int staticField = 20;static class StaticInnerClass {private OuterClass outer;  // 持有外部類實例的引用public StaticInnerClass(OuterClass outer) {this.outer = outer;  // 通過構造函數傳入外部類實例}public void accessNonStaticField() {System.out.println(outer.nonStaticField);  // 通過實例訪問非靜態成員System.out.println(staticField);  // 可以直接訪問靜態成員}}
}// 使用方式
OuterClass outer = new OuterClass();
OuterClass.StaticInnerClass inner = new OuterClass.StaticInnerClass(outer);
inner.accessNonStaticField();

方法二:通過方法傳參傳遞

class OuterClass {private int nonStaticField = 10;static class StaticInnerClass {public void printField(OuterClass outer) {System.out.println(outer.nonStaticField);  // 通過參數訪問}}
}// 使用方式
OuterClass outer = new OuterClass();
OuterClass.StaticInnerClass inner = new OuterClass.StaticInnerClass();
inner.printField(outer);

(2)創建靜態內部類對象時,不需要先創建外部類對象

3、實例內部類---未被static修飾的成員內部類

public class OutClass {public int a;public static int b;public  int c;//  實例內部類:未被static修飾 class InnerClass{int c;public void methodInner(){// 在實例內部類中可以直接訪問外部類中:任意訪問限定符修飾的成員 a = 100;b =200;// 如果外部類和實例內部類中具有相同名稱成員時,優先訪問的是內部類??的c = 300;System.out.println(c);// 如果要訪問外部類同名成員時候,必須:外部類名稱.this.同名成員名字 OutClass.this.c = 400;System.out.println(OutClass.this.c);}}public static void main(String[] args) {// 外部類:對象創建 以及 成員訪問 OutClass outClass = new OutClass();System.out.println(outClass.a);System.out.println(OutClass.b);System.out.println(outClass.c);System.out.println("=============實例內部類的訪問=============");// 要訪問實例內部類中成員,必須要創建實例內部類的對象 // ?普通內部類定義與外部類成員定義位置相同,因此創建實例內部類對象時必須借助外部類// 創建實例內部類對象 OutClass.InnerClass innerClass1 = new OutClass().new InnerClass();// 上述語法?較怪異,也可以先將外部類對象先創建出來,然后再創建實例內部類對象 OutClass.InnerClass innerClass2 = outClass.new InnerClass();innerClass2.methodInner();}
}

#注:

(1)外部類中的任何成員都可以在實例內部類方法中直接訪問

(2)實例內部類所處的位置與外部類成員位置相同,因此也受public、private等訪問限定符的約束

(3)在實例內部類方法中訪問同名的成員時,優先訪問自己的,如果要訪問外部類同名的成員,必須:外部類名稱.this.同名成員來訪問

(4)實例內部類對象必須在先有外部類對象前提下才能創建

(5)實例內部類的非靜態方法中包含了?個指向外部類對象的引用

(6)外部類中,不能直接訪問實例內部類中的成員,如果要訪問必須先要創建內部類的對象。

4、局部內部類

????????定義在外部類的方法體或者{ }中,該種內部類只能在其定義的位置使用,?般使?的非常少,此處簡單了解下語法格式。

 public class OutClass {int a = 10;public void method(){int b = 10;// 局部內部類:定義在?法體內部// 不能被public、static等訪問限定符修飾 class InnerClass{public void methodInnerClass(){System.out.println(a);System.out.println(b);}}// 只能在該?法體內部使?,其他位置都不能? InnerClass innerClass = new InnerClass();innerClass.methodInnerClass();}public static void main(String[] args) {// OutClass.InnerClass innerClass = null; 編譯失敗 }}

#注:

(1)局部內部類只能在所定義的方法體內部使用

(2)不能被public、static等修飾符修飾

(3)編譯器也有自己獨立的字節碼文件,命名格式:外部類名字$數字內部類名字.class

(4)幾乎不會使用

5、匿名內部類

????????匿名內部類是Java中?種特殊的嵌套類,它沒有類名,在聲明的同時完成實例化。匿名內部類通常用于創建只需使用?次的類

語法形式:

 new SuperType(constructor-arguments) {   //類體 };

SuperType 可以是接口、抽象類或具體類。

示例代碼:

 interface Greeting {void greet();}public class Test  {public static void main(String[] args) {Greeting greeting = new Greeting() {@Overridepublic void greet() {System.out.println("Hello!");}};greeting.greet();}}

????????匿名內部類當中可以定義和正常類?樣的成員變量,但是和正常類?樣都不能直接包含執行語句

interface Greeting {void greet();
}public class Derived  extends Base   {public static void main(String[] args) {Greeting greeting = new Greeting() {public static int a = 10;a = 100;//error@Overridepublic void greet() {System.out.println("Hello!"+a);}};greeting.greet();}}

二、Object類

????????Object是Java默認提供的?個類。Java里面除了Object類,所有的類都是存在繼承關系的。默認會繼承Object父類。即所有類的對象都可以使用Object的引用進行接收。

????????使用Object可以接收所有類的對象,所以在開發之中,Object類是參數的最高統?類型。但是Object類也存在有定義好的?些方法。

????????對于整個Object類中的方法需要實現全部掌握。 我們主要來熟悉這幾個方法:toString()方法,equals()方法,hashcode()方法

1、獲取對象信息

????????如果要打印對象中的內容,可以直接重寫Object類中的toString()方法,之前已經講過了,此處不再贅述啦。

// Object類中的toString()?法實現: 
public String toString() {return getClass().getName() + "@" + Integer.toHexString(hashCode());
}

2、equals方法

在Java中,==進行比較時:

a.如果 == 左右兩側是基本類型變量,比較的是變量中值是否相同

b.如果 == 左右兩側是引用類型變量,比較的是引用變量地址是否相同

c.如果要比較對象中內容,必須重寫Object中的equals方法,因為equals方法默認也是按照地址比較的:

// Object類中的equals?法 
public boolean equals(Object obj) {return (this == obj);   // 使?引?中的地址直接來進??較  
}
class Person{private String name ; private int age ; public Person(String name, int age) {this.age = age ; this.name = name ;}
}
public class Test {public static void main(String[] args) {Person p1 = new Person("gaobo", 20) ; Person p2 = new Person("gaobo", 20) ; int a = 10;int b = 10;System.out.println(a == b);             // 輸出trueSystem.out.println(p1 == p2);           // 輸出falseSystem.out.println(p1.equals(p2));      // 輸出false}
}

????????Person類重寫equals方法后,然后比較:

class Person{...@Overridepublic boolean equals(Object obj) {if (obj == null) {return false ; }if(this == obj) {return true ; }// 不是Person類對象 if (!(obj instanceof Person)) {return false ; }Person person = (Person) obj ; // 向下轉型,?較屬性值 return this.name.equals(person.name) && this.age==person.age ; }
}

????????因此,比較對象中內容是否相同的時候,?定要重寫equals方法!!!

3、hashcode方法

回憶剛剛的toString方法的源碼:

 public String toString() {return getClass().getName() + "@" + Integer.toHexString(hashCode());}

????????我們看到了hashCode()這個方法,他幫我算了?個具體的對象位置,這里面涉及數據結構,但是我們還沒講到數據結構,沒法講述,所以我們只能說它是個內存地址。然后調用Integer.toHexString()方法, 將這個地址以16進制輸出。

hashcode方法源碼:

 public native int hashCode();

該方法是?個native方法,底層是由C/C++代碼寫的。我們看不到。

????????我們認為兩個名字相同,年齡相同的對象,將存儲在同?個位置,如果不重寫hashcode()方法,我們可以來看示例代碼:

 class Person {public String name;public int age;public Person(String name, int age) {this.name = name;this.age = age;}}public class TestDemo {public static void main(String[] args) {Person per1 = new Person("gaobo", 20) ;Person per2 = new Person("gaobo", 20) ;System.out.println(per1.hashCode());System.out.println(per2.hashCode());}}//執?結果 4601419581163157884

#注:兩個對象的hash值不?樣。

????????像重寫equals方法?樣,我們也可以重寫hashcode()方法。此時我們再來看看。

 class Person {public String name;public int age;public Person(String name, int age) {this.name = name;this.age = age;}@Overridepublic int hashCode() {return Objects.hash(name, age);}}public class TestDemo4 {public static void main(String[] args) {Person per1 = new Person("gaobo", 20) ;Person per2 = new Person("gaobo", 20) ;System.out.println(per1.hashCode());System.out.println(per2.hashCode());}}//執?結果 460141958460141958

#注:哈希值?樣。

總結:

(1)hashcode方法用來確定對象在內存中存儲的位置是否相同

(2)事實上hashCode()在散列表中才有用,在其它情況下沒用。在散列表中hashCode()的作用是獲取對象的散列碼,進而確定該對象在散列表中的位置。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/pingmian/93566.shtml
繁體地址,請注明出處:http://hk.pswp.cn/pingmian/93566.shtml
英文地址,請注明出處:http://en.pswp.cn/pingmian/93566.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

字節數據流

記錄 干貨|8000字長文,深度介紹Flink在字節跳動數據流的實踐 字節跳動基于Flink的MQ-Hive實時數據集成

Vision Master的C#腳本與opencv聯合編程

需要在VM的C#腳本設置string類型Out變量和float類型OutF變量,python的輸出信息會在Out變量顯示 using System; using System.IO; using Script.Methods; using System.Diagnostics; using System.Net.Sockets; using System.Text; using System.Threading;public pa…

運維工作架構流程搭建

前言 在解決了運維是干什么的,運維的工作的意義后,這一章我們系統性的講講運維工作流程搭建,希望大家能通過我的分享有所收獲,這一章干貨滿滿。 一、網絡服務器架構 按照一般的訪問方式,按照我自己的理解畫了一個網絡服…

安全存儲之 SAES+HUK 使用技巧和常見問題 LAT1543

關鍵字:AES,SAES, HUK, DHUK, 安全存儲 引言 近年來,嵌入式設備信息安全被越來越多地提及,從智能穿戴產品、智能工業設備到物聯網產品都對設備信息安全提出了要求,比如基礎的安全啟動,安全升級&#xff0…

ubuntu 20.04 搭建多用戶遠程桌面共享及同時在線使用

使用效果: 物理機: 遠程桌面用戶: 實現過程: 1.使用腳本安裝xrdp并修改配置及啟動服務 setup_xrdp.sh sudo apt update sudo apt install xrdp -ysudo systemctl enable xrdp sudo systemctl start xrdp#sudo vim /etc/xrdp/startwm.sh #unset DBUS_SESSION_BUS_ADDRES…

[激光原理與應用-287]:理論 - 波動光學 - 電磁波既能承載能量,又能承載信息?

電磁波既能承載能量,又能承載信息,這一特性源于其物理本質和調制技術的結合。以下從能量承載和信息承載兩方面進行詳細解析:一、電磁波如何承載能量?電磁波的能量承載源于其電場和磁場的周期性振蕩,具體機制如下&#…

哪里找最新AI工具官網?如何快速對比ChatGPT替代品?AI工具導航指南 - AIbase

你是否曾有這樣的經歷: 聽聞某款新AI工具爆火,翻遍網絡卻找不到可靠官網或真實評測? 面對功能相似的ChatGPT替代品,參數對比表格散落各處,決策耗時耗力? 想緊跟AI領域突破,卻淹沒在海量資訊碎…

第一階段C#基礎-15:面向對象梳理

面向對象對象三(四)大特征:封裝,繼承,多態,(抽象)1_封裝(1)封裝是指將數據(屬性)和行為(方法)組合在一個類中&…

中國星網發展情況全面分析

中國星網作為我國衛星互聯網領域的"國家隊"先鋒,自2021年4月成立以來已取得顯著進展。截至2025年8月,中國星網主導的GW星座已累計發射73顆衛星,形成"四天兩發"的高頻發射節奏,標志著我國低軌衛星互聯網建設進入加速期。在戰略定位上,中國星網不僅承擔…

C++ Qt 成員對象初始化與 TCP 長連接問題深度解析

文章目錄C Qt 成員對象初始化與 TCP 長連接問題深度解析1. 棧對象、堆對象與類成員對象的區別1.1 棧對象(局部變量)1.2 堆對象(動態分配)1.3 類成員對象1.4 棧對象 vs 成員對象 vs 堆對象對比表2. 為什么初始化列表必須用2.1 構造…

深度學習周報(8.11~8.17)

目錄 摘要 Abstract 1 CNN--卷積神經網絡簡介 2 CNN核心操作 2.1 卷積 2.2 池化 3 總結 摘要 本周主要學習了卷積神經網絡(CNN)的相關知識,包括概念、基本架構與應用領域等知識,了解了CNN利用其結構高效地從圖像等網格化數…

oracle dg duplicate限速

一些客戶在搭建dg的時候需要進行限速&#xff0c;不然對生產庫的影響比較大&#xff0c;例如將速度限制到200M每秒&#xff0c;語法如下&#xff1a;rman target sys/XXXX auxiliary sys/XXXXdg <<EOF run{ allocate channel d1 type disk rate 200M; allocate auxiliar…

飛算JavaAI智慧校園場景實踐:從校園管理到師生服務的全鏈路技術革新

目錄一、智慧校園核心場景的技術突破1.1 智能校園綜合管理系統1.2 智慧教學資源共享系統1.3 校園生活服務集成系統二、智慧校園系統效能升級實踐結語&#xff1a;重新定義智慧校園技術邊界在校園管理領域&#xff0c;“規模化運營”與“個性化服務”的矛盾、“管理效率”與“服…

PTPX分析中,如何處理fsdb文件過大的問題?

PTPX分析中&#xff0c;如何處理fsdb文件過大的問題&#xff1f;摘要&#xff1a;下面將基于Synopsys工具鏈&#xff08;PrimeTime PX&#xff0c;即PTPX&#xff0c;用于功耗分析&#xff1b;Verdi&#xff0c;用于波形查看&#xff09;逐一解答每個部分。這些工具在SoC功耗驗…

004.Redis 數據持久化概述及實戰

文章目錄Redis持久化說明Redis持久化RDB持久化AOF持久化混合持久化save與bgsaveRedis RDB持久化Redis 安裝Redis RDB配置手動觸發RDB持久化模擬寫入測試數據模擬進程異常RDB的優缺點優勢劣勢Redis AOF持久化Redis 安裝Redis AOF配置AOF持久化模擬寫入測試數據模擬進程異常AOF的…

Kubernetes(K8s)常用命令全解析:從基礎到進階

Kubernetes&#xff08;K8s&#xff09;常用命令全解析&#xff1a;從基礎到進階 引言&#xff1a;為什么掌握K8s命令是云原生時代的必備技能&#xff1f; Kubernetes&#xff08;簡稱K8s&#xff09;作為容器編排的事實標準&#xff0c;已成為云原生應用部署、擴展和管理的核…

深入解析StatefulSet與K8s服務管理

目錄 一、Statefulset控制器&#xff1a;概念、原理解讀 有狀態服務 無狀態服務 StatefulSet部分組成 Headless service 二、Statefulset資源清單文件編寫技巧 三、Statefulset使用案例&#xff1a;部署web站點 四、Statefulset管理pod&#xff1a;擴容、縮容、更新 St…

GaussDB常用術語縮寫及釋義

序號 術語全稱釋義1ACLAccess Control List訪問控制列表&#xff0c;被授權訪問某一資源的實體及其訪問權限的列表。2APIApplication Programming Interface應用程序接口&#xff0c;一些預先定義的接口&#xff08;如函數&#xff0c;http接口&#xff09;或指軟件系統不同組…

工業一體機5G通訊IC/ID刷卡讓MES系統管理更智能

在智能制造升級過程中&#xff0c;MES 系統作為生產執行的核心樞紐&#xff0c;其數據采集的實時性、準確性與管理安全性直接決定管理效能。傳統 MES 系統常面臨數據傳輸滯后、設備對接繁瑣、權限管理粗放等問題&#xff0c;而工業一體機憑借 5G 通訊與 IC/ID 刷卡功能&#xf…

電腦開機幾秒后就停止然后再循環是怎么回事

硬件問題電源問題&#xff1a;電源內部的濾波電容若出現鼓包或漏液現象&#xff0c;會導致電源供電不足&#xff0c;從而使電腦開機后自動停止并重新啟動。另外&#xff0c;電源線連接不良、插座無電或電源供應器故障&#xff0c;也可能引發此問題。CPU 散熱問題&#xff1a;如…