Java---關於多態、抽象類、接口超詳細解析。

主要內容

  一、多態的引入

  二、抽象類

  三、接口

  四、多態的應用

一. 多態的引入

多態概述

  同一個引用類型,使用不同的實例而執行不同操作,即父類引用指向子類對象

多態的必要條件

  1.一定要有繼承關係

   2.一定要有重寫

   3.父類引用指向子類對象

多態訪問成員的特點

  成員變量
     編譯的時候看左邊類型,運行的時候看左邊類型

   成員方法
     編譯的時候看左邊類型,運行的時候看右邊類型

   靜態成員
     編譯的時候看左邊類型,運行的時候看左邊類型
   構造方法

     先執行父類的構造方法,可以幫我們初始化父類繼承過來成員,再執行子類

多態的好處

   1.提高了程序的維護性

   2.提高了程序的擴展性

多態的缺點

   1.使用父類引用不能訪問子類所特有的功能。

   解決辦法:
      使用多態中的轉型

   2.多態的轉型問題

      分爲向上轉型和向下轉型。

   向上轉型(自動轉換)
     格式:<父類型> <引用變量名> = new <子類型>();

特點:
  1.子類轉爲父類,父類的引用指向子類對象類,似於自動進行類型轉換。

  2.此時通過父類引用變量調用的方法是子類覆蓋或繼承父類的方法。

  3.此時通過父類引用變量無法調用子類特有的屬性和方法。

向下轉型(強制轉換)
    格式:<子類型> <引用變量名> = (<子類型> )<父類型的引用變量>;
特點:
  1.父類轉爲子類,父類引用轉爲子類對象,類似於強制類型轉換。

  2.在向下轉型的過程中,如果沒有轉換爲真實子類類型,會出現類型轉換異常。

instanceof關鍵字
測試它左邊的對象是否是它右邊的類的實例,返回boolean類型的數據

注意:instanceof通常和向下轉型(強制類型轉換)結合使用

二. 抽象類

抽象類的引入

  如果說有一個汽車類。汽車有一個run()方法,並且汽車類對應着 兩個子類,分別是寶馬車類和奔馳車類,這兩個子類也相應有自己的run()方法。

  我們思考一個問題,雖然我說過汽車類,但是你知道我說的是什麼汽車嗎?只有看到了具體的汽車,我們纔會明白,這是什麼汽車。 也就是說,汽車本身並不是一個具體的,而是一個抽象的事物。只有真正的寶馬車,纔是具體的汽車。
同理,我們也可以推想,不同的汽車run方法的實現應該是不一樣的,所以,我們沒必要在汽車類中的run方法給出具體實現,僅僅給出一個聲明即可。在Java中,如果一個沒有方法體,沒有實現的方法定義爲抽象方法,一個類中一旦出現抽象方法,該類一定是一個抽象類。

抽象類特點

  1.抽象類和抽象方法一定要使用abstract關鍵字來聲明

  2.抽象類中不一定有抽象方法

  3.沒有抽象方法的類有意義嗎? – 有意義 不讓外界創建對象

  4.抽象類不能實例化

  5.抽象類如果想要實例化怎麼辦? - 可以利用多態 父類引用指向子類對象,只不過這個父類是一個抽象類而已

  6.如果作爲一個抽象類的子類,那麼該子類應該具備什麼特點?

    a.如果子類不想實現父類的抽象方法,那麼子類也可以自動升級爲抽象類

    b.如果子類想要實現父類的抽象方法,那麼子類就必須實現父類所有的抽象方法

  7.抽象類中可以有抽象方法,成員變量,成員方法,常量,構造方法,靜態方法.

     成員變量:可以有,用來給子類繼承使用

     成員方法:同上

     常量:同上

     構造方法: 幫助所有子類初始化父類繼承過來的成員變量

  抽象類是一個爲所有子類服務的類

  8.static final private可以用來修飾抽象方法嗎?

     a.static和abstract不能共存: static爲了方便調用,abstract爲了給子類重寫,沒有方法體

     b.abstract和final二者構成衝突,final修飾的方法不能被子類重寫,abstract修飾的方法就是用來給子類重寫,所以衝突

     c.abstract和private二者構成衝突,private修飾的方法不能夠被繼承,既然不能被繼承,就沒有重寫,而abstract修飾的方法就是用來給子類重寫,所以衝突

   9.抽象方法可以使用public 和 protected修飾嗎? 可以

   10.綜上訴述: 抽象類的所有的抽象方法用來給子類重寫

      抽象類的所有非抽象方法用來給子類使用

      抽象類的構造方法用來給子類初始化父類繼承過來的成員

      抽象類的成員變量用來給子類使用

      抽象類就是一個徹頭徹尾的服務類

三.接口

接口的概述

接口就是抽象方法和常量的集合,接口是一個比抽象類還要抽象的類。

接口的格式

  關鍵字 接口名 {
      常量;
      抽象方法;
      JDK1.8之後可以有默認方法和靜態方法;
   }

接口的特點

  1.接口使用interface關鍵字來修飾

  2.接口由常量和抽象方法組成

     a.常量: 默認接口中所有的成員變量都是省略 public static final,一般接口的成員變量都是大寫

     b.抽象方法:默認接口中所有的成員方法都是省略了 public abstract
      我們建議都寫上

  3.接口不能實例化,因爲接口是完全抽象的
      如果需要"創建"接口,那麼必須使用多態

  4.接口的實現類
      使用implement關鍵字來完成接口的實現
      接口的實現類特點
     a.如果一個類實現了接口,那麼該類就必須實現類接口定義所有的抽象方法
     b.如果一個接口不想實現接口的方法,那麼子類必須定義爲一個接口

  5.接口是可以擴展功能的 通過多實現

  6.接口是可以多繼承的

  7.接口是一種規範

  8.接口是靈活的

  9.類與接口之間的關係

      類和類     單繼承   不可以實現
      類和接口    單繼承   多實現
      接口和接口  多繼承   不可以多實現

   10. 什麼時候使用繼承,什麼時候使用接口?

      當我設計一個非常複雜而又無法實現的類的時候可以使用繼承

      當我重新開始編寫一些簡單的功能或者制定一些標準的時候使用接口

      開發中一般採用面向接口編程,普通類是模板,抽象類是部門模板,部分規範,接口是規範。

   接口和抽象類的區別
在這裏插入圖片描述

四、多態的應用

多態的三種實現方式

  1.直接使用多態

  2.使用父類作爲方法形參實現多態

  3.使用父類作爲方法返回值實現多態

多態作爲形參

  形式參數
     基本類型

   引用類型

    普通類
   當一個形參希望我們傳入的是一個普通類時,我們實際上傳入的是該類的對象/匿名對象

     抽象類
  當一個形參希望我們傳入的是一個抽象類時,我們實際上傳入的是該類的子類對象/子類匿名對象

   接口

   當一個形參希望我們傳入的是一個接口時,我們實際上傳入的是該類的實現類對象/實現類匿名對象

多態作爲返回值

     基本類型

     引用類型

     普通類
   當一個方法的返回值是一個普通的類時,實際上返回的是該類的對象,我們可以使用該類的對象接收

    抽象類
   當一個方法的返回值是一個抽象類時,實際上返回的是該抽象類的子類對象,我們可以使用該抽象類接收

     接口
   當一個方法的返回值是一個接口時,實際上返回的是該接口的實現類對象,我們可以使用接口接收
   注意:

  1.當方法的返回值類型是引用類型的時候,可以使用鏈式調用。

  2.當方法的參數是引用類型的時候,最好加上非空判斷。

發佈了28 篇原創文章 · 獲贊 47 · 訪問量 4077
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章