淺談面向對象中的多態

面向對象有三大特徵:封裝、繼承和多態。今天我們來談談多態。

多態

多態概述
什麼是多態?
每每談及多態時,總有一種只可意會不可言傳的感覺。簡單來說多態就是某個事物,在不同時刻表現出來的不同狀態。
比如:貓可以是貓的類型,也可以是動物的類型(因爲貓也是動物)。
多態的前提

  • 類和類要有繼承關係。
  • 要有方法重寫。沒有也行,但沒有的話多態就沒有意義了。
  • 要有父類引用指向子類對象。(父類 對象名 = new 子類();)

多態中的成員的訪問特點

  • 成員變量的訪問特點:編譯看左邊,運行看左邊
  • 成員方法的訪問特點:編譯看左邊,運行看右邊
  • 構造方法:創建子類對象時,會先訪問父類的構造方法,對父類的數據進行初始化
  • 靜態方法的訪問特點:編譯看左邊,運行看左邊(靜態方法是屬於類的,算不上重寫,所以訪問還是左邊的)

多態的好處
可總結如下

  • 提高了代碼的維護性(繼承)
  • 提高了代碼的擴展性(多態)

多態雖然有好處,但是也有弊端。多態的弊端就是不能夠訪問子類特有的功能。(因爲是父類引用指向子類對象)
在這裏插入圖片描述
在多態的方式下,若要訪問子類特有的功能則需要向下轉型,即把父類的引用強制類型轉換爲子類的引用。
在這裏插入圖片描述
那麼有向下轉型,就有向上轉型,多態就是典型的向上轉型,父類引用指向子類對象。

抽象類

抽象類概述
在Java中,一個沒有方法體的方法應該定義爲抽象方法,而類中如果有抽象方法,該類必須定義爲抽象類。
抽象方法的格式:
修飾符 abstract 返回值類型 方法名();
在這裏插入圖片描述
抽象類的格式:
abstract class 類名{
}
在這裏插入圖片描述
那麼抽象類有哪些特點呢?

  • 抽象類和抽象方法必須用abstract關鍵字修飾。
    抽象類格式:abstract class 類名 {
    }
    抽象方法格式:public abstract void eat();
  • 抽象類不一定有抽象方法,但有抽象方法的類一定是抽象類
  • 抽象類中可以有構造方法,但抽象類不能進行實例化。抽象類中的構造方法是用於子類訪問父類數據時的初始化
  • 抽象類雖然不能直接初始化,但可以間接初始化。按照多態的方式,由具體的子類實例化。其實這也是多態的一種,抽象類多態。
  • 抽象類的子類:要麼也是抽象類;要麼重寫抽象類中的所有抽象方法

抽象類的成員特點

  • 成員變量:既可以是變量,也可以是常量。
  • 構造方法:有構造方法。用於子類訪問父類數據的初始化。
  • 成員方法:既可以是抽象的,也可以是非抽象的。

抽象類的成員方法特性

  • 抽象方法:強制要求子類做的事情。子類必須重寫父類的抽象方法。
    在這裏插入圖片描述
  • 非抽象方法:子類繼承的事情,提高代碼複用性。

一個類如果沒有抽象方法,可以定義爲抽象類,但是不能創建對象。

接口

何爲接口
爲了體現事物功能的擴展性,Java中提供了接口來定義一些額外功能(這些額外功能並不是類的對象所共有的,只是一部分對象擁有),並不給出具體實現,當有事物向具備這些額外功能時,就可以實現這個接口

接口的特點

  • 接口用關鍵字interface表示
    接口的格式爲:
    interface 接口名 {
    }
    在這裏插入圖片描述
  • 類實現接口用implements表示
    格式爲:
    class 類名 implements 接口名 {
    }
    這個類,可以叫做接口的子類, 這個接口 可以叫做這個類的父接口。
    在這裏插入圖片描述
  • 接口不能實例化
    若要實例化,則需要用多態的方式進行實例化
  • 接口的子類:可以是抽象類(但是意義不大);可以是具體類,要重寫接口中的所有抽象方法(推薦這樣寫)

作爲接口的子類,有什麼要求

  • 要求子類必須重寫接口中所有的抽象方法
  • 如果不想重寫,那麼這個類可以爲一個抽象類,將接口中的抽象方法繼承即可

接口成員特點

  • 成員變量:只能是常量,並且是靜態的。默認修飾符:public static final,但是建議我們在寫的時候手動給出。
  • 構造方法:接口沒有構造方法。
  • 成員方法:只能是抽象方法。默認修飾符:public abstract,但是建議我們在寫的時候手動給出。

類、接口之間的關係

  • 類與類:繼承關係,只能單繼承,可以多層繼承。
  • 類與接口:實現關係,可以單實現,也可以多實現。也可以在繼承一個類的同時實現多個接口。
  • 接口與接口:繼承關係,可以單繼承,也可以多繼承。

抽象類和接口的區別
成員的區別

  • 成員變量:
    抽象類中的成員變量既可以是常量,也可以是變量;
    接口中的成員變量只能是靜態的常量
  • 成員方法:
    抽象類中的成員方法既可以是抽象的,也可以是非抽象的;
    接口中的成員方法必須是抽象的
  • 構造方法:
    抽象類中有構造方法;
    接口中沒有構造方法

關係的區別:

  • 類與類:繼承關係,單繼承
  • 類與接口:實現關係,單實現和多實現均可
  • 接口與接口:繼承關係,單繼承和多繼承均可

設計理念的區別:

  • 抽象類:被繼承 體現的是:”is a”的關係。抽象類中定義的是該繼承體系的共性功能。
  • 接口:被實現 體現的是:”like a”的關係。接口中定義的是該繼承體系的擴展功能。

JDK1.8之後在接口中提供了用default修飾的方法,可以給出功能的具體實現,子類可以繼承下去用

abstract關鍵字

abstract關鍵字:抽象的,可以修飾類,也可以修飾方法。
特點

  • abstract 修飾類,此類就不能直接實例化
  • abstract 修飾方法,修飾的方法,要求子類必須重寫

abstract和以下關鍵字不共存:

  • private
    原因:private修飾的成員不能被子類繼承,而abstract要求繼承成員,並重寫方法。
  • final
    衝突的原因同上。
  • static
    不能共存 無意義
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章