[Java入門]抽象類和接口

[Java入門]抽象類和接口

  • 1. 抽象類
    • 1.1 抽象類的概念
    • 1.2 抽象類語法
    • 1.3 抽象類特性
    • 1.4 抽象類的作用
  • 2. 接口
    • 2.1 接口的概念
    • 2.2 語法規則
    • 2.3 接口使用
    • 2.4 接口特性
    • 2.5 實現多個接口
    • 2.6 接口間的繼承
    • 2.7 抽象類和接口的區別
  • 3. Object類
    • 3.1 獲取對象信息
    • 3.2 對象比較equals方法

1. 抽象類

1.1 抽象類的概念

在面向對象的概念中,所有的對象都是通過類來描繪的,但是反過來,并不是所有的類都是用來描繪對象的,如果一個類中沒有包含足夠的信息來描繪一個具體的對象,這樣的類就是抽象類。 比如:

在這里插入圖片描述
【說明】

  • 從圖中可知,矩形類、圓形類、三角形類都屬于圖形類,所以三者都與Shape類是繼承關系
  • 由于Shape不是具體的圖形,該類雖然存在draw方法,但無法畫出具體圖形,即draw方法無法具體實現
  • 因此Shape類中沒有足夠的信息來描繪自己的對象,所以Shape類就能被設計為抽象類

在這里插入圖片描述

【說明】

  • 再來看這個圖,很明顯可以看出Student類、Teacher類、Waiter類都與Person類是繼承關系
  • 由于Person不是具體的人,所以無法確定職業,即使它存在career方法,那也無法具體的實現該方法
  • 因此Person類中沒有足夠的信息來描繪自己的對象,career方法也無法具體的實現,所以該類就可以被設計為抽象類

從上面兩個例子中,兩個父類Shape類和Person類 的 draw方法和career方法是無法具體實現的,只有它們的子類才會有具體的實現,像這種沒有具體實現的方法,通常設計為抽象方法(abstract method),而包含抽象方法的類稱為 抽象類(abstract class)

1.2 抽象類語法

在Java中,如果一個類被 abstract 修飾,那么這個類被稱為抽象類,而在抽象類中,存在被 abstract 修飾的方法,那么這個方法就被稱為 抽象方法。

//抽象類: 在普通類前用 abstract 修飾
//抽象類也是類 也可以定義成員變量 和 方法
public abstract class Person {public String name;public int age;public void chat(){System.out.println("在聊天!");}//抽象方法:在普通方法前用 abstract 修飾//抽象方法 可以沒有方法體public abstract void career();
}

注意:抽象類也是類,內部可以包含普通方法和屬性,甚至構造方法

1.3 抽象類特性

  1. 抽象類被 abstract 修飾
  2. 抽象類跟普通類一樣,也可以包含普通方法和屬性,還有構造方法
  3. 抽象方法被 abstract 修飾,且必須在抽象類中
  4. 抽象方法不能被 final 和 static 修飾,因為要被重寫
  5. private 和 abstract 不能同時存在
看報錯提示:private abstract void career();//Illegal combination of modifiers: 'abstract' and 'private'public static abstract void career();//Illegal combination of modifiers: 'abstract' and 'static'public final abstract void career();//Illegal combination of modifiers: 'final' and 'abstract'
  1. 抽象類被設計出來就是為了被繼承
  2. 普通類繼承抽象類 必須重寫抽象類中所有的抽象方法,否則就將普通類改為抽象類
abstract class Person {public abstract void career();
}class Student extends Person{//@Overridepublic void career() {System.out.println("我的職業是學生!");}
}
  1. 當普通類B不想重寫時,就將普通類B變成抽象類B,那么當普通類C想繼承抽象類B時,必須要重寫抽象類B 和 抽象類A 的所有抽象方法
abstract class Person {public abstract void career();
}public abstract class Student extends Person{@Overridepublic abstract void career();public abstract void homework();
}class StudentOfPrimary extends Student{@Overridepublic void career() {System.out.println("我是小學生!");}@Overridepublic void homework() {System.out.println("我在寫小學生作業!");}
}
  1. 抽象類中不一定包含抽象方法,但是有抽象方法的類一定是抽象類
  2. 抽象類中可以有構造方法,供子類創建對象時,初始化父類的成員變量

1.4 抽象類的作用

抽象類本身不能被實例化, 要想使用, 只能創建該抽象類的子類. 然后讓子類重寫抽象類中的抽象方法.

有些同學可能會說了, 普通的類也可以被繼承呀, 普通的方法也可以被重寫呀, 為啥非得用抽象類和抽象方法呢?

確實如此. 但是使用抽象類相當于多了一重編譯器的校驗.

使用抽象類的場景就如上面的代碼, 實際工作不應該由父類完成, 而應由子類完成. 那么此時如果不小心誤用成父類了, 使用普通類編譯器是不會報錯的. 但是父類是抽象類就會在實例化的時候提示錯誤, 讓我們盡早發現問題.

很多語法存在的意義都是為了 “預防出錯”, 例如我們曾經用過的 final 也是類似. 創建的變量用戶不去修改, 不就相當于常量嘛? 但是加上 final 能夠在不小心誤修改的時候, 讓編譯器及時提醒我們.

充分利用編譯器的校驗, 在實際開發中是非常有意義的.

2. 接口

2.1 接口的概念

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

2.2 語法規則

接口的定義格式與定義類的格式基本相同,將class關鍵字換成 interface 關鍵字,就定義了一個接口。

public interface Drawable {public static final int a = 0;//接口中定義變量時 public static final 是固定存在的 可以不寫public abstract void draw();//接口中定義方法時 public abstract 是固定存在的 可以不寫
}

注意:接口中的方法都是抽象方法

提示:

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

2.3 接口使用

接口不能直接使用,必須要有一個"實現類"來"實現"該接口,實現接口中的所有抽象方法。 模板:

public class 類名 implements 接口名{
}

比如:

public interface Drawable {public abstract void draw();
}public abstract class Shape {public abstract void getArea();
}public class Circle extends Shape implements Drawable{@Overridepublic void getArea() {System.out.println("圓的面積");}@Overridepublic void draw() {System.out.println("圓");}
}public class Main {public static void main(String[] args) {Circle circle = new Circle();circle.getArea();circle.draw();}
}

2.4 接口特性

  1. 接口中定義變量時 public static final 是固定存在的 可以不寫
  2. 接口中定義方法時 public abstract 是固定存在的 可以不寫
  3. 接口中的方法都是抽象方法
  4. 接口中的方法不能在接口中實現,只能在實現該接口的類中實現
  5. 若接口中的方法被static修飾,那么可以在接口中有具體的實現
public interface Drawable {public static final int a = 0;public abstract void draw();static void draw1(){System.out.println("畫畫");}
}
//Circle類 實現 Drawable接口
public class Circle implements Drawable{@Overridepublic void draw() {System.out.println("圓");}
}
  1. 接口是引用類型,但不能通過 new 來實例化
Drawable drawable = new Drawable();
報錯:'Drawable' is abstract; cannot be instantiated
  1. 在重寫接口中的方法時,必須加上public
  2. 接口中不能有構造方法和代碼塊

2.5 實現多個接口

在Java中,類和類之間是單繼承的,一個類只能有一個父類,即Java中不支持多繼承,但是一個類可以實現多個接口。舉例說明:

一個動物類
public abstract class Animal {private String name;private int age;public Animal(String name, int age) {this.name = name;this.age = age;}public String getName() {return name;}public int getAge() {return age;}public abstract void makeSound();
}兩個接口
public interface Swimming {public void swim();
}public interface Trainbale {public void train();
}兩個子類:
貓
public class Cat extends Animal implements Trainbale{public Cat(String name, int age) {super(name, age);}@Overridepublic void makeSound() {System.out.println(getName() + "喵喵喵!");}@Overridepublic void train() {System.out.println(getName() + "可被訓練!");}
}狗(實現了兩個接口)
public class Dog extends Animal implements Trainbale,Swimming{public Dog(String name, int age) {super(name, age);}@Overridepublic void makeSound() {System.out.println(getName() + "旺旺旺");}@Overridepublic void train() {System.out.println(getName() + "可被訓練!");}@Overridepublic void swim() {System.out.println(getName() + "會游泳!");}
}

從代碼可以看出,子類狗繼承了Animal類實現了兩個接口,這是根據它的特性實現的。這是Java中最常見的的用法:一個類繼承一個父類實現多個接口

繼承表達的含義是 is - a 語義, 而接口表達的含義是 具有 xxx 特性 .

  • 貓是一種動物,具有可被訓練的特性.
  • 狗是一種動物,具有會游泳、可被訓練的特性.

這樣設計有什么好處呢? 時刻牢記多態的好處, 讓程序猿忘記類型. 有了接口之后, 類的使用者就不必關注具體類型,而只關注某個類是否具備某種能力.

2.6 接口間的繼承

在Java中,類與類之間可以繼承,類與接口之間可以實現,那接口與接口之間呢?是可以繼承的,且可以多繼承,可以借助接口達到多繼承的目的!

public interface Flying {public void fly();
}
public interface Trainbale {public void train();
}
//接口與接口之間也是通過 extends 繼承,并非用 implements
//若繼承的接口中已寫有方法,那么本接口可以不用添加特有方法
public interface Merge extends Flying,Trainbale{
}//Bird類 實現了 Merge接口 那么就要重寫train、fly方法
public class Bird implements Merge{@Overridepublic void train() {System.out.println("可被訓練!");}@Overridepublic void fly() {System.out.println("會飛!");}
}

接口之間的繼承相當于把多個接口合并起來。

2.7 抽象類和接口的區別

抽象類和接口都是 Java 中多態的常見使用方式. 都需要重點掌握. 同時又要認清兩者的區別(重要!!! 常見面試題).

核心區別: 抽象類中可以包含普通方法和普通字段, 這樣的普通方法和字段可以被子類直接使用(不必重寫), 而接口中不能包含普通方法, 子類必須重寫所有的抽象方法.

抽象類存在的意義是為了讓編譯器更好的校驗, 像 前面提到的Animal、Shape等 這樣的類我們并不會直接使用, 而是使用它的子類.萬一不小心創建了 Animal 或 Shape的實例, 編譯器會及時提醒我們.

在這里插入圖片描述

3. Object類

Object是Java默認提供的一個類。Java里面除了Object類,所有的類都是存在繼承關系的。默認會繼承Object父類。即所有類的對象(無論是Java自帶的還是自己設計創建的)都可以使用Object的引用進行接收。

public class A {
}public class Test {public static void main(String[] args) {A a = new A(); //自己設計的類String str = new String("123");//Java中已存在的類func(a);func(str);}
public static void func(Object o){System.out.println(o);}
}//打印結果
demo5.A@119d7047
123

所以在開發之中,Object類是參數的最高統一類型。

但是Object類也存在一些定義好的方法。如下:

在這里插入圖片描述
對于 Object 類中已存在的所有方法都需要熟悉掌握。
我們先來熟悉 toString()、 equals() 兩個方法

3.1 獲取對象信息

如果要打印對象中的內容,可以直接重寫Object類中的toString()方法,內容可以根據自己的要求修改。

這是Object類中的toString()方法具體內容,可以看出是默認打印地址
在這里插入圖片描述

3.2 對象比較equals方法

在Java中,== 進行比較時:
a.如果 == 左右兩側是基本類型變量,比較的是變量中值是否相同
b.如果 == 左右兩側是引用類型變量,比較的是引用變量地址是否相同
c.如果要比較對象中內容,必須重寫Object中的equals方法,因為equals方法默認也是按照地址比較的:

在這里插入圖片描述

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); // 輸出false 因為是兩個對象,是兩個不同的地址System.out.println(p1.equals(p2)); // 輸出false}
}

未重寫的equals() 方法的內容就是 比較兩對象地址是否相同。

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

class Person{private String name ;private int age ;public Person(String name, int age) {this.age = age ;this.name = name ;}public boolean equals(Object obj) {if (obj == null) {return false ;}if(this == obj) {return true ;}// 若不是Person類對象 返回 falseif (!(obj instanceof Person)) {return false ;}Person person = (Person) obj ; // 向下轉型,比較屬性值return this.name.equals(person.name) && this.age==person.age ;}
}//結果
System.out.println(a == b); // 輸出true
System.out.println(p1 == p2); // 輸出false 
System.out.println(p1.equals(p2)); // 輸出true

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

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

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

相關文章

聚焦數字中國|AI賦能與安全守護:Coremail引領郵件辦公智能化轉型

4月28日,第八屆數字中國建設峰會在福州拉開序幕。當天,數字中國新產品新技術發布會開講,Coremail受邀亮相現場,與與會嘉賓分享AI在郵件產品領域的最新應用成果和實踐經驗。 Coremail首席客戶代表劉子建以《AI賦能與安全守護&#…

Qt官方案例知識點總結(拖放操作——Drag And Drop Robot )

-------------------------------------------------------------------------------------------------------------------------------- QPixmap輪廓剪裁 去掉Pixmap的外圍部分,如下: QPixmap pixmap("./img"); //調用createHeuristicMas…

【LLM】MOE混合專家大模型綜述(重要模塊原理)

note 當前的 MoE 架構就是一個用顯存換訓練時長/推理延遲的架構MoE 目前的架構基本集中在于將原先 GPT 每層的 FFN 復制多份作為 n 個 expert,并增加一個 router,用來計算每個 token 對應到哪個 FFN(一般采用每個 token 固定指派 n 個 exper…

電子病歷高質量語料庫構建方法與架構項目(臨床情景理解模塊篇)

引言 隨著人工智能技術在醫療健康領域的廣泛應用,電子病歷(Electronic Medical Records,EMR)作為臨床醫療數據的重要載體,已成為醫學研究和臨床決策支持的關鍵資源。電子病歷高質量語料庫的構建為醫療人工智能模型的訓練和應用提供了基礎支撐,其中臨床情境理解模塊是連接…

大連理工大學選修課——機器學習筆記(1):概述

機器學習概述 機器學習的本質 機器學習是為了設計解決問題的算法。 為輸入與輸出建立某種映射: 類似于函數關系: Y f ( X ) Yf(X) Yf(X) 不同的映射方法體現了不同的思想。 相關概念 深度學習是機器學習的一個分支 深度學習是深層次化的神經網…

遠程 Debugger 多用戶環境下的用戶隔離實踐

遠程 Debugger 多用戶環境下的用戶隔離實踐 在現代分布式開發和云原生環境下,遠程 Debugger 的應用愈發普遍。然而,隨著多人協作和多租戶場景的出現,**遠程 Debugger 的“用戶隔離”**變得至關重要。只有實現了良好的用戶隔離,才…

畢業論文 | 基于C#開發的NMEA 0183協議上位機

以下是基于C#開發的NMEA 0183協議上位機完整實現方案,包含串口通信、數據解析與可視化功能: 基于C#開發的NMEA 0183協議上位機 一、項目結構二、核心代碼實現1. 數據模型定義2. 串口通信管理3. NMEA協議解析核心4. 主界面實現(Windows Forms)三、界面設計關鍵元素(需在窗體…

Qt -DFS可視化

博客主頁:【夜泉_ly】 本文專欄:【暫無】 歡迎點贊👍收藏?關注?? 目錄 前言關于如何sleep實現思路Pixmapspixmaps.hpixmaps.cpp MapSquaremapsquare.hmapsquare.cpp dfsthreaddfsthread.hdfsthread.cpprun dfs其他 WidgetUnit其他 Qt -DFS…

RHCSA Linux 系統 文件系統權限

1. 文件的一般權限 (1)文件權限標識解讀 drwxr - xr - x. 12 root root 144 Feb 17 16:51 usr ?d:文件類型(d 表示目錄) ?rwx:文件所有者權限(讀 r,寫 w,執行 x&am…

華為云IoT平臺與MicroPython實戰:從MQTT協議到物聯網設備開發

目錄 前言 1. 華為云 1.1. 創建實例 1.2. 創建產品 1.3. 編輯服務模型 1.4. 注冊設備 1.4.1. 復制設備連接參數 1.5. 連接參考代碼 2. micropython版-物聯網 2.1. 環境搭建 2.2. 實現步驟 2.3. 示例代碼 結語 前言 物聯網(IoT)技術的快速發…

2025-04-30 AIGC-如何做短片視頻

摘要: 2025-04-30 AIGC-如何做短片視頻 如何做短片視頻: 一、畫圖修圖 1.保存視頻(無水保存) 2.文案提取(提取文案) 3. DeepSeek(提示詞) 4.小夢Ai(圖片視頻) 5.修圖Ai 6.擴圖Ai 7.養生…

硬件工程師面試常見問題(10)

第四十六問:鎖存器,觸發器,寄存器三者的區別 觸發器:能夠存儲一位二值信號的基本單元電路統稱為 "觸發器"。(單位) 鎖存器:一位觸發器只能傳送或存儲一位數據,而在實際工…

外部訪問 Kubernetes 集群中 MQ 服務的方案

外部訪問 Kubernetes 集群中 MQ 服務的方案 當您在 Kubernetes 集群中部署了消息隊列服務(如 RabbitMQ、Kafka、ActiveMQ 等)后,以下是外部客戶端訪問這些服務的幾種可靠方法: 一、基礎訪問方案 1. NodePort 方式暴露服務 # M…

論文筆記(八十二)Transformers without Normalization

Transformers without Normalization 文章概括Abstract1 引言2 背景:歸一化層3 歸一化層做什么?4 動態 Tanh (Dynamic Tanh (DyT))5 實驗6 分析6.1 DyT \text{DyT} DyT 的效率6.2 tanh \text{tanh} tanh 和 α α α 的消融實驗…

軟考中級-軟件設計師 操作系統(手寫筆記)

第一章:基礎知識 第二章:進程管理 狀態轉換圖 進程同步機制 信號量機制 信號量題 死鎖 第三章:存儲管理 基礎知識 分頁存儲管理 分段存儲管理 段頁式存儲管理 頁面置換算法 第四章:文件管理 基礎知識 索引分配 空閑存儲空間的管…

ubuntu 部署moodle

通過地址https://download.moodle.org/releases/latest/選擇下載,下載兩種壓縮包都特別慢(有可能無法下載)。 可以使用下面git下載項目 注意圖中php、mysql等版本要求,本次采用Ubuntu22.04下 nginxphp8.2mysql8.4部署 mkdir /var…

python實戰項目67:空氣質量在線檢測平臺js逆向

python實戰項目67:空氣質量在線檢測平臺js逆向 一、需求介紹二、完整代碼一、需求介紹 項目需求是獲取某個城市(以北京市為例)歷年(2013年12月至2025年4月)的空氣質量數據,字段包括日期、AQI、質量等級、PM2.5、PM10、NO2、CO、SO2等。改網站的網址是“https://www.aqis…

【Linux】記錄一個有用PS1

PS1 是用來定義shell提示符的環境變量 下面是一個帶有顏色和豐富信息的 Linux PS1 配置示例,包含用戶名、主機名、路徑、時間、Git 分支和退出狀態提示: # 添加到 ~/.bashrc 文件末尾 PS1\[\e[1;32m\]\u\[\e[m\] # 綠色粗體用戶名 PS…

Python PyTorch庫【機器學習框架】全面深入講解與實踐

一、PyTorch 核心概念 1. 定義與發展背景 PyTorch 是由 Facebook AI Research (FAIR) 開發的開源機器學習框架,2016 年首次發布。其核心特性包括: 動態計算圖(Define-by-Run)GPU 加速張量計算自動微分系統豐富的神經網絡模塊 …

呼叫中心座席管理系統:智能升級,高效服務

在數字化轉型加速的今天,客戶服務體驗已成為企業競爭力的核心要素。傳統 呼叫中心系統 依賴硬件設備、人工操作的模式已無法滿足高效、智能、靈活的現代企業需求。暢信達呼叫中心 座席管理系統 V5.0應運而生,以WEBRTC軟電話接入、智能座席輔助、知識庫管…