Java類和對象(五)—— 抽象類、接口、Object類和內部類

抽象類

在繼承體系下,父類有些方法可能是要被重寫的,如果我們事先就知道某些方法需要重寫的話,我們可以不用在父類里面具體實現這個方法,這時候我們會用到抽象方法,這時候我們會用到關鍵字abstract關鍵字來修飾

public abstract class Animal {protected abstract void eat();
}

例如上面的Animal 類,每一個動物都會吃,但是每一個動物卻吃的食物不同,父類的eat方法無法完全描述某個對象,這時候子類就需要重寫這個方法,如果我們不想在父類具體實現這個eat方法的話,我們可以寫成抽象方法~~

說完抽象方法,我們來類比一下抽象類:

如果一個類中沒有包含足夠的信息來描繪一個具體的對象,這樣的類就是抽象類

抽象類也是用abstract 修飾的~~

注意要點

有抽象方法的類,一定是抽象類,所以如果方法被abstract修飾,那類也必須由abstract修飾,否則編譯報錯

抽象類是不能進行實例化的,但是可以有繼承的向上轉型和向下轉型~~

被private、static、final 修飾的方法不能是抽象方法
因為抽象方法就是為了被子類重寫的,根據重寫的規則,被private、static、final修飾的方法確實不能被重寫

抽象類被繼承后,繼承后子類要重寫父類中的抽象方法除非子類也是抽象類,必須要使用 abstract 修飾,無論是誰繼承了抽象類都必須重寫所有的抽象方法,否則編譯報錯~~

在這里插入圖片描述

在這里插入圖片描述
當Dog繼承Animal,必須重寫Aniaml所有的抽象方法~~


在這里插入圖片描述

在這里插入圖片描述

如果Dog還是抽象類,Cat 繼承 Dog,并且在 Cat 不是抽象的情況下,我們要在 Cat 這個類重寫所有的抽象方法(即包括 Animal 也包括 Dog 的抽象方法)

抽象類的作用

抽象類就是用來被繼承的
誰繼承了抽象類,都必須重寫抽象方法,否則編譯報錯,這也是為了多加一層編譯器的校驗

接口

接口就是公共的行為規范標準,大家在實現時,只要符合規范標準,就可以通用。
在Java中,接口可以看成是:多個類的公共規范,是一種引用數據類型

我們使用 intarface 來定義接口,就是把class替換成interface

,

public interface Ieat {void eat();
}

接口雖然不是類,但是接口編譯完成后字節碼文件的后綴格式也是.class
在這里插入圖片描述

接口的使用規則

接口的成員方法是默認都是public static final 修飾的
接口的成員方法默認都是 public abstract 修飾的

當你在接口里定義了一個成員變量的時候,你必須對其進行初始化!!!
在這里插入圖片描述

如果你想具體實現某些方法,你可以使用 static 或者 default 來進行修飾

public interface Ieat {static void eat(){//...}default void eat2(){//...}
}

訪問權限也是和之前講的是一樣的,被static就是默認權限的靜態方法,被default 修飾就是默認訪問權限。


接口不能有實例化代碼塊、靜態代碼塊,也不能有構造方法~~

在這里插入圖片描述


如果類沒有實現接口中的所有的抽象方法,則類必須設置為抽象類,如果被繼承就必須重寫所有的抽象方法!!!
這個和抽象類是類似的~~

在這里插入圖片描述


軟性規則:

創建接口時, 接口的命名一般以大寫字母 I 開頭.
接口的命名一般使用 “形容詞” 詞性的單詞.
阿里編碼規范中約定, 接口中的方法和屬性不要加任何修飾符號, 保持代碼的簡潔性.

接口的繼承

接口與接口之間可以多繼承。即:用接口可以達到多繼承的目的。
接口可以繼承一個或者多個接口, 達到復用的效果. 使用 extends 關鍵字

interface IA{void eat();
}interface IB{void sleep();
}interface C extends IA,IB{}

接口的作用

解決了 Java 不能多繼承的問題!!!
意味著一個類可以有多個接口!!!

如果子類由繼承父類還有多個接口的時候,我們要先繼承后接口(先extends 再 implements)

在這里插入圖片描述

快捷鍵(搭建接口當中的抽象方法)

IDEA 中使用 ctrl + i 快速搭建接口當中的抽象方法~~

或者使用 alt + enter 進行選擇implements methods 進行快速搭建接口,你選擇Make ‘Dog’ abstract 的話就是講這個類變為抽象類~~
在這里插入圖片描述

接口的好處

public class Animal {protected String name;protected int age;
}public interface Irun {void run();
}public class Cat extends Animal implements Irun{public Cat(String name, int age) {this.name = name;this.age = age;}@Overridepublic void run() {System.out.println(this.name + "正在跑步");}
}public class Dog extends Animal implements Irun{public Dog(String name, int age) {this.name = name;this.age = age;}@Overridepublic void run() {System.out.println(this.name + "正在跑步");}
}public class Test {public static void walk(Irun irun){irun.run();}public static void main(String[] args) {walk(new Dog("旺財",11));walk(new Cat("小咪",10));}
}

在這里插入圖片描述

接口也可以有動態綁定和多態~~
由于接口可以實現多態,所以程序員可以不關注類型,只要有這個接口的類,都能調用里面的接口方法,而不用去關心這是什么類。

Object 類

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

在這里插入圖片描述
我們這里先重點關注一下上面標出來的三個方法:toString,equals,hashCode,

toString(打印對象)

class Person{public String name;public int age;}public class Test {public static void main(String[] args) {Person person = new Person();System.out.println(person);}
}

我們在數組里知道直接打印數組名的話會出現包含數組的地址的一串字符串~~
如果直接打印對象的話,也會出現和數組類似的情況,這是為什么?

Java所有的類都會繼承Object類,在調用println的時候,我們來看看一共調用了哪些方法:

首先println 方法如下:

在這里插入圖片描述

之后無論是走if 語句還是else 語句,都會調用toString方法

在這里插入圖片描述
在這里插入圖片描述
最后就會來到toString 方法,這里getClass.getName()就是類名,然后加@符號,最后調用hashCode找到地址。


但是如果我們重寫了 toString 方法的話,根據前面的知識,優先調用子類的方法來打印對象內容。

class Person{public String name;public int age;@Overridepublic String toString() {return "Person{" +"name='" + name + '\'' +", age=" + age +'}';}
}

這樣的話,我們就會優先調用子類自己的toString 方法

在這里插入圖片描述


我們可以使用編譯器自動生成toString方法:

在這里插入圖片描述

在這里插入圖片描述

和之前搭建getter、setter還有構造方法是一樣的,只是這里選擇的是toString()

class A{public String name;public int age;@Overridepublic String toString() {return "A{" +"name='" + name + '\'' +", age=" + age +'}';}
}

equals

在Java當中,如果使用 == 來進行比較時
如果比較的是基本數據類型的話,就是比較兩個的數值相不相同
如果比較的是引用數據類型,就會比較他們的地址相不相同

來我們看一下源碼:

在這里插入圖片描述

還是一樣的,直接調用equals方法,還是比較兩個對象的地址,所以如果想比較兩個對象的內容相不相同就必須重寫equals方法~~

    public boolean equals(Object o) {if (this == o) return true;if (o == null || getClass() != o.getClass()) return false;Person person = (Person) o;return age == person.age && Objects.equals(name, person.name);}
class Person{public String name;public int age;public Person(String name, int age) {this.name = name;this.age = age;}@Overridepublic String toString() {return "Person{" +"name='" + name + '\'' +", age=" + age +'}';}@Overridepublic boolean equals(Object o) {if (this == o) return true;if (o == null || getClass() != o.getClass()) return false;Person person = (Person) o;return age == person.age && Objects.equals(name, person.name);}
}public class Test {public static void main(String[] args) {Person person1 = new Person("張三",10);Person person2 = new Person("張三",10);System.out.println(person1.equals(person2));}
}

在這里插入圖片描述

比較對象中內容是否相同的時候,一定要重寫equals方法。

hashCode

源碼:

在這里插入圖片描述

native 說明這是本地方法,這個是有C/C++代碼編寫的,我們是看不到的


簡單來說,hashCode方法可以找到對象的內存地址

public class Test {public static void main(String[] args) {Person person1 = new Person("張三",10);Person person2 = new Person("張三",10);System.out.println(person1.hashCode());System.out.println(person2.hashCode());}
}

在這里插入圖片描述

由于這是兩個不同的對象,所以他們的內存地址是不一樣的~~

但是如果我們認為當兩個對象的內容是一樣的,那地址就應該是一樣的話,我們就需要重寫hashCode 方法~~

    @Overridepublic int hashCode() {return Objects.hash(name, age);}

在這里插入圖片描述

這樣他們的地址就會是一樣的顯示~~


快捷鍵搭建

以上三個方法都能使用快捷鍵快速搭建:

在這里插入圖片描述

內部類

內部類就是在類里面再定義一個類,這個類定義的位置和外部類的成員是相同的。

靜態內部類

static修飾的內部成員類稱為靜態內部類。

class A{public int age;public static int price;public A(){System.out.println("A()......");}public void methodA1(){System.out.println("methodA1()......");}public static void methodA2(){System.out.println("methodA2()......");}static class B{public void methodB(){//age = 10;//err,靜態內部類只能訪問外部類的靜態成員//A();//不要在靜態內部類中調用外部類的構造方法,構造方法是沒有靜態的,所以構造方法一定不是靜態方法//methodA1(); //err,靜態內部類只能訪問外部類的靜態成員,methodA1不是類方法(靜態成員方法)price = 10;methodA2();}}//.....
}

注意事項

靜態內部類只能訪問外部類的靜態成員

創建靜態內部類

A.B b = new A.B();

我們可以將靜態內部類當成外部類的一個靜態成員,靜態成員的訪問不需要創建對象,我們可以通過類名來訪問,于是我們通過 A.B 就訪問到了靜態內部類,然后就通過new A.B 就可以完成創建了

實例內部類

未被static 修飾的實例內部類就是實例內部類

實例內部類可以自由訪問外部類的任意成員,如果實例內部類和外部類有重名的成員時,在內部類中優先訪問自己的,如果真的相訪問外部類同名的成員時,我們可以使用 外部類類名.this.成員 即可~~

class A{public int age;public static int price;public A(){System.out.println("A()......");}public void methodA1(){System.out.println("methodA1()......");}public static void methodA2(){System.out.println("methodA2()......");}public void methodA3(){System.out.println("methodA3()......");}class C{public int age = 10;public void methodC(){System.out.println(age);methodA3();System.out.println(A.this.age);methodA1();A.this.methodA1();}public void methodA1(){System.out.println("C::methodA1()......");}}//.....
}public class Test{public static void main(String[] args) {A.C c = new A().new C();c.methodC();}
}

在這里插入圖片描述


創建實例內部類

我們要先創建外部類,再去創建實例內部類

A.C c = new A().new C();

當然也可以分部去寫:

A a = new A();
A.C c = a.new C();

注意事項

1.外部類中的任何成員都 可以在實例內部類方法中直接訪問
2.實例內部類所處的位置與外部類成員位置相同,因此也受public、private等訪問限定符的約束
3.在實例內部類方法中訪問同名的成員時,優先訪問自己的,如果要訪問外部類同名的成員,必須:外部類名
稱.this.同名成員 來訪問
4.實例內部類對象必須在先有外部類對象前提下才能創建
5.實例內部類的非靜態方法中包含了一個指向外部類對象的引用
6.外部類中,不能直接訪問實例內部類中的成員,如果要訪問必須先要創建內部類的對象。


匿名內部類

class A{public void test1(){System.out.println("heihei");}
}public class Test{public static void main(String[] args) {new A(){}.test1();}}

在這里插入圖片描述

通過后面的 .方法 來調用相應的方法。


我們也可以重寫匿名內部類的方法

在這里插入圖片描述
在這里插入圖片描述


在這里插入圖片描述
但是要注意不能使用對象來接收匿名內部類


接口也可以使用:

interface A{void test1();
}public class Test{public static void main(String[] args) {new A(){public void test1(){System.out.println("haha");}};}}

和上面不一樣的是,接口是一定要重寫其中的抽象方法的,并且花括號后面是不能直接 .方法 的,而是要通過被接收后,然后去再去調用相應的方法~~

因此接口是可以被接收的,接收后也是可以繼續使用的:

在這里插入圖片描述
在這里插入圖片描述

局部內部類

局部內部類是定義在方法里的,因此它的生命周期和方法是一樣。

    public void A() {//...class D{ //......}//...}

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

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

相關文章

BatBot智慧能源管理平臺,更加有效地管理能源

隨著能源消耗的不斷增加,能源管理已成為全球面臨的重要問題。BatBot智慧能源管理作為一種的能源管理技術,促進企業在用能效率及管理有著巨大的提升。 BatBot智慧能源管理是一種基于人工智能技術的能源管理系統,通過智能分析和優化能源使用&…

【JAVA |再談接口、Object、內部類】Object類中子類重寫,Cloneable 接口、比較器、內部類

??謝謝大家捧場,祝屏幕前的小伙伴們每天都有好運相伴左右,一定要天天開心哦!?? 🎈🎈作者主頁: 🎈丠丠64-CSDN博客🎈 ?? 帥哥美女們,我們共同加油!一起…

Internet動態路由選擇—RIP與OSPF

剛做完網絡層動態路由選擇的實驗,寫下此篇記錄實驗過程,鞏固學習成果。 參考書目:《計算機網絡》北京理工大學出版社-劉陽老師編 路由選擇可分為兩種策略: - 靜態路由選擇策略 - 動態路由選擇策略 靜態路由即管理員手動配置路由…

Java 商品入庫系統 案例

測試類 package 練習.商品入庫系統;import java.util.ArrayList; import java.util.Scanner; public class Test {public static final int Enrool 1;public static final int Search 2;public static final int Delect 3;public static final int Exit 4;public static…

在docker上部署postgresSQL主從

文章目錄 一、主從規劃二、創建PostgresSQL的Docker鏡像三、主庫部署1、建立pgsql主庫的data地址2、啟動docker鏡像3、docker內操作4、修改配置文件 四、部署從數據庫1、建立psql備庫的data地址2、啟動docker鏡像3、備庫從主庫同步4、檢查是否同步 五、測試主從數據庫 一、主從…

#2495. 滑動窗口 /【模板】單調隊列

題目描述 有一個長為 ( n ) 的序列 ( a ),以及一個大小為 ( k ) 的窗口。現在這個窗口從左邊開始向右滑動,每次滑動一個單位,求出每次滑動后窗口中的最大值和最小值。例如: 數組是 ([1, 3, -1, -3, 5, 3, 6, 7]), ( …

【深度強化學習】關于同一設備上cuda和gpu計算結果不一致問題

文章目錄 問題描述關于seed: 跟原文一致補充:萬能seed 問題結論cpu和gpu差異來源分析浮點數精度的差異補充報錯:Expected all tensors to be on the same device!常見運算上的差異累加運算的差異exp運算的差異matmul運算的差異 forward上的差異&#xff…

【LeetCode 隨筆】面試經典 150 題【中等+困難】持續更新中。。。

文章目錄 189. 輪轉數組122. 買賣股票的最佳時機 II55. 跳躍游戲45. 跳躍游戲 II274. H 指數 🌈你好呀!我是 山頂風景獨好 💝歡迎來到我的博客,很高興能夠在這里和您見面! 💝希望您在這里可以感受到一份輕松…

機器學習云環境搭建

在 https://support.huaweicloud.com/browsertg-obs/obs_03_1003.html 下載對應版本的 OBS Broswer 軟件,如圖,紅框內的為安裝文件,藍色框內的為對應安裝文件的校驗文件(無需下載) 以 64 位機為例,下載完…

景源暢信電商:抖店需要的成本高嗎?

在數字化時代的浪潮中,短視頻平臺迅速崛起,成為連接用戶與商家的新橋梁。抖音作為其中的佼佼者,不僅改變了人們的娛樂方式,也催生了新型的電商模式——抖店。許多人好奇,入駐這樣一個充滿活力的平臺,需要承…

618知識狂歡,挑本好書,點亮智慧生活!

618精選編程書單:提升你的代碼力 一年一度的618又到啦!今年的618就不要亂買啦,衣服買多了會被淘汰,電子產品買多了會過時,零食買多了會增肥,最后怎么看都不劃算。可是如果你購買知識,堅持閱讀&a…

第N2周:Embeddingbag與Embedding詳解

🍨 本文為🔗365天深度學習訓練營 中的學習記錄博客🍖 原作者:K同學啊 | 接輔導、項目定制🚀 文章來源:K同學的學習圈子 目錄 什么是詞嵌入? Embedding與EmbeddingBag詳解 Embedding Embeddi…

代碼隨想錄算法訓練營第十七天|LeetCode110 平衡二叉樹、LeetCode257 二叉樹的所有路徑

題1: 指路:LeetCode110 平衡二叉樹 思路與代碼: 左右子樹的高度差小于等于1。對于這個題,遞歸比迭代方便太多,我也想過迭代,但是我沒有寫出來,大家可以自己試一下。遞歸代碼如下:…

如何為ChatGPT編寫有效的提示詞:軟件開發者的指南

作為一名軟件開發者,特別是使用Vue進行開發的開發者,與ChatGPT等AI助手高效互動,可以極大地提升你的開發效率。本文將深入探討如何編寫有效的提示詞,以便從ChatGPT中獲取有用的信息和幫助。 1. 明確目標 在編寫提示詞之前&#…

后端之路第二站(正片)——SprintBoot之:分層解耦

很抽象,我自己也不好理解,僅作為一個前端轉后端的個人理解 一、先解釋一個案例,以這個案例來分析“三層架構” 這里我先解釋一下黑馬程序員里的這個案例,兄弟們看視頻的可以跳過這節課:Day05-08. 請求響應-響應-案例_…

【webrtc】m98:Call的創建及Call對音頻接收處理

call中多個流共享相同的輔助組件 這幾個是與外部共用的 線程傳輸send控制module 線程任務隊列工廠call的輔助組件中各種統計以及接收測的cc是自己創建的 call自己的多個輔助組件是外部傳遞來的 call 創建多個接收流 這里用一個set 來保存所有指針,并沒有要map的意思:

【因果推斷從入門到精通二】隨機實驗3

目錄 檢驗無因果效應假說 硬幣投擲的特殊性何在? 檢驗無因果效應假說 無因果效應假說認為,有些人存活,有些人死亡,但接受mAb114治療而不是ZMapp與此無關。在174例接受mAb14治療的患者中,113/17464.9%存活了28天&…

【MySQL精通之路】InnoDB(6)-磁盤結構

主要博客: 【MySQL精通之路】InnoDB存儲引擎-CSDN博客 1 表 2 索引 【MySQL精通之路】InnoDB(6)-磁盤結構(2)-索引-CSDN博客 3 表空間 【MySQL精通之路】InnoDB(6)-磁盤結構(3)-表空間-CSDN博客 4 雙寫緩沖區 【MySQL精通之路】InnoDB(6)-磁盤結構(4)-雙寫緩沖…

修改MySQL root用戶密碼

ALTER USER ‘root’‘localhost’ IDENTIFIED BY ‘new_password’; ALTER USER ‘root’‘%’ IDENTIFIED BY ‘new_password’; 》 SET GLOBAL read_only OFF; select * from mysql.user;