java面向對象基礎(四):抽象類和介面

来源:https://www.cnblogs.com/f-ck-need-u/archive/2017/12/27/8127993.html
-Advertisement-
Play Games

抽象類(abstract) 以下麵多態的示例來說明: 父類Animal中的sing()方法遲早要被子類Cat、Dog重寫,而且在多態實現下,Animal的sing()完全是多餘的。因此,可以將Animal的sing()方法的方法體刪掉。 更徹底一點,將sing()方法加上abstract關鍵字,這個 ...


抽象類(abstract)

  1. 使用abstract關鍵字來修飾的類是抽象類。使用abstract修飾方法時這個方法稱為抽象方法。
  2. 含有抽象方法的類必須被聲明為抽象類,抽象類必須被繼承,抽象方法必須被重寫。
  3. 抽象類不能被實例化,即不能new該類對象。因為抽象類是比較抽象的類,是殘缺不全的類。
  4. 抽象方法只需定義它的結構,不需寫方法體。因為抽象方法最終都要被子類重寫,即使定義抽象方法也是多餘的。
  5. 抽象類中並非一定要包含抽象方法,也並非不能包含普通方法。

以下麵多態的示例來說明:

class Animal {
  private String name;
  Animal(String name) {this.name = name;}

  public void sing(){System.out.println("animal sing...");} //這是多餘的方法
}

class Cat extends Animal {
  private String eyeColor;
  Cat(String n,String c) {super(n); eyeColor = c;}

  public void sing() {System.out.println("cat sing...");}
}

class Dog extends Animal {
    private String furColor;
    Dog(String n,String c) {super(n); furColor = c;}

    public void sing() {System.out.println("dog sing...");}
}

class Lady {
    private String name;
    private Animal pet;
    Lady(String name,Animal pet) {this.name = name; this.pet = pet;}
    public void myPetSing(){pet.sing();}
}

public class DuoTai {
    public static void main(String args[]){
        Cat c = new Cat("catname","blue");
        Dog d = new Dog("dogname","black");
        Lady l1 = new Lady("l1",c);
        Lady l2 = new Lady("l2",d);
        l1.myPetSing();
        l2.myPetSing();
    }
}

父類Animal中的sing()方法遲早要被子類Cat、Dog重寫,而且在多態實現下,Animal的sing()完全是多餘的。因此,可以將Animal的sing()方法的方法體刪掉。

class Animal {
  private String name;
  Animal(String name) {this.name = name;}

  public void sing() {}
}

更徹底一點,將sing()方法加上abstract關鍵字,這個方法變為抽象方法,抽象方法是不完整的方法,它必須被子類重寫。抽象方法所在的類也必須加上abstract關鍵字變成抽象類。成了抽象類後這個類也是不完整的類,所以無法實例化new Animal

abstract class Animal {
  private String name;
  Animal(String name) {this.name = name;}

  public abstract void sing();
}

雖然Animal中的sing()用不上了,但它卻必須要定義出來,因為它要被子類重寫。另外,如果子類不想重寫抽象方法,可以將這個子類也定義為抽象類,並讓子子類去重寫。

介面(interface)

介面定義的是一種具有某種能力的標準,通過介面實現的方式來體現如何具有該這些能力。說白了它就是能實現某些能力的標準。

例如定義一個USB介面的標準,各廠商如何去實現這個標準由各廠商自己去決定,但不管如何,各廠商實現的USB介面必須達到標準所要求具有的能力。

放在編程語言中來說,介面是一種特殊的抽象類,裡面的方法必須全部是抽象方法且都是public的,裡面的變數也必須都是"public static final"屬性的。即使不寫這些修飾關鍵字,預設也是這些屬性,但如果寫了,就絕對不能寫錯。

定義介面的方式是使用interface關鍵字替代class關鍵字。例如以下定義一個Singable介面,要求必須有喉嚨,且能唱歌,能臨時停止唱歌。

interface Singable {
    public static final boolean houlong = true;

    public void sing();
    public void tmpStop();
}

既然介面是一種抽象類,那麼就可以被繼承,且裡面的方法必須要重寫以體現各子類獨有的能力。通常介面都被命名為"XXXable",因為介面一般體現的是具有某種能力。

繼承介面這個特殊類的術語是"實現介面",使用implement關鍵字。某個類可以實現多個介面,也就是"多重繼承"不僅如此,實現介面的同時還可以實現extends繼承其他類。有以下幾種寫法:

class A implement intf1 {}
class A implement intf1,intf2 {}
class A extends ParentClass implement intf1,intf2 {}

以下是一個示例,定義了Singable和Paintable兩個介面,還定義了兩個實現這兩介面的類Student和Teacher,它們分別有各自的方法study()和teach()。

interface Singable {
    public void sing();
}

interface Paintable {
    public void paint();
}

class Student implements Singable {
    private String name;
    Student(String name) {this.name = name;}

    public void study() {System.out.println("Student studing...");}

    // overwrite methods 
    public void sing() {System.out.println("Student singing...");}
}

class Teacher implements Singable,Paintable {
    private String name;
    Teacher(String name) {this.name = name;}

    public void teach() {System.out.println("Teacher teaching...");}

    // overwrite methods 
    public void sing() {System.out.println("Teacher singing...");}
    public void paint() {System.out.println("Teacher painting...");}
}

public class Interface {
    public static void main(String[] args) {
        Singable s1 = new Student("Malongshuai");
        s1.sing();
        //s1.study();   //return error! because s1 upcasting from Student to Singable
        Student s = (Student)s1;
        s.study();  //return true

        Singable t1 = new Teacher("Gaoxiaofang");
        t1.sing();
        //t1.paint(); //return error! t1 upcasting from Teacher to Singable,not Paintable
        Paintable t = (Paintable)t1;
        t.paint();
    }
}

上面的示例中,Student類實現了Singable介面,所以它重寫了sing(),Teacher類實現了Singable介面和Paintable介面,所以它重寫了sing()和paint()。

需要註意的點在於介面和實現介面的類之間具有多態性。正如上面的Singable t1 = new Teacher("Gaoxiaofang");,此時t1雖然引用的是Teacher對象,但它能識別的數據只有Singable介面的成員sing(),而無法識別Teacher自身的方法teach()和Paintable介面的方法paint(),且因為子類Teacher重寫了Singable中的sing(),所以多態性使得t1.sing()調用的是Teacher重寫後的sing()。要訪問paint(),需要將t1轉型為Paintable類型或者Teacher類型,要訪問teach(),就必須轉型為Teacher類型。

註:若您覺得這篇文章還不錯請點擊右下角推薦,您的支持能激發作者更大的寫作熱情,非常感謝!


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • JEEPlatform 一款企業信息化開發基礎平臺,可以用於快速構建企業後臺管理系統,集成了OA(辦公自動化)、SCM(供應鏈系統)、ERP(企業資源管理系統)、CMS(內容管理系統)、CRM(客戶關係管理系統)等企業系統的通用業務功能。Github鏈接:https://github.com/u01 ...
  • 咖啡店需要做一個訂單系統,以合乎飲料供應要求。 1.最初是這樣設計的: 每一種飲料都需要繼承該抽象類,並覆寫cost()方法。 2.但是購買咖啡時需要考慮到調料的部分,每種咖啡會加不同種的調料,比如蒸奶、豆漿、摩卡或者覆蓋奶泡,那麼訂單系統需要考慮加入不同調料後的價格。因此需要實現不同的子類來定義添 ...
  • In Campaign mode, you can check your strategies on already defeated bases. You will not lose your troops.在戰役模式中,你能查看已被打敗的玩家的塔防策略,而且你不會損失任何戰鬥單位。Let's w ...
  • JAVA中的異常類都繼承自Throwable類,也就是說,這是異常類的根。Throwable類擴展了兩個類Error類和Exception類,Exception類又擴展了一個RuntimeException類。如下圖: Error:稱為錯誤,由Java虛擬機生成並拋出,這類錯誤一般是運行時系統內部的 ...
  • 題目大意:每個人有兩種值Di和Pi,從n個人中選m個人組成集合J,D(J)和P(J)為這m個人的Di與Pi和,使|D(J) - P(J)|最小。若有多個集合J最小,則使D(J) + P(J) 最大。 1<=n<=200, 1<=m<=20 ,Di和Pi最大為20. 註意到Di和Pi的和很小,我們可以 ...
  • 章節:enote筆記法的思考 why enote筆記法: key1)大腦喜歡顏色。 我們的大腦天生就喜歡顏色、對顏色很敏感,這是由我們人類過去的演化歷程決定的。 你可以理解為,文字有了顏色,讓這個冰冷的黑白世界突然有了色彩,變得絢麗多彩、色彩斑斕,充滿溫暖的暖意了起來,這使得讓你能更容易專註起來&保 ...
  • 首先來介紹下 Jetty,根據 wiki 的介紹: Jetty 是一個純粹的基於 Java 的網頁伺服器和 Java Servlet 容器。儘管網頁伺服器通常用來為人們呈現文檔, 但是 Jetty 通常在較大的軟體框架中用於電腦與電腦之間的通信。 Jetty 作為 Eclipse 基金會的一部分 ...
  • GCC4和GCC5使用的C++標準庫下,string的名字不一樣,導致鏈接錯誤。 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...