Java 多態(tài)

Java 多態(tài)

多態(tài)是同一個行為具有多個不同表現(xiàn)形式或形態(tài)的能力

多態(tài)就是同一個接口,使用不同的實例而執(zhí)行不同操作

image

多態(tài)性是對象多種表現(xiàn)形式的體現(xiàn)

同一個事件發(fā)生在不同的對象上會產生不同的結果

多態(tài)的優(yōu)點

  1. 消除類型之間的耦合關系
  2. 可替換性
  3. 可擴充性
  4. 接口性
  5. 靈活性
  6. 簡化性

多態(tài)存在的三個必要條件

  1. 繼承
  2. 重寫
  3. 父類引用指向子類對象

比如

Parent p = new Child();

當使用多態(tài)方式調用方法時,首先檢查父類中是否有該方法误褪,如果沒有匙铡,則編譯錯誤艇肴;如果有华糖,再去調用子類的同名方法

多態(tài)的好處:可以使程序有良好的擴展,并可以對所有類的對象進行通用處理

下面的代碼演示了多態(tài)的實現(xiàn)和應用

public class Test {
    public static void main(String[] args) {
      show(new Cat());  // 以 Cat 對象調用 show 方法
      show(new Dog());  // 以 Dog 對象調用 show 方法

      Animal a = new Cat();  // 向上轉型 
      a.eat();               // 調用的是 Cat 的 eat
      Cat c = (Cat)a;        // 向下轉型 
      c.work();        // 調用的是 Cat 的 work
  }  

    public static void show(Animal a)  {
      a.eat();  
        // 類型判斷
        if (a instanceof Cat)  {  // 貓做的事情 
            Cat c = (Cat)a;  
            c.work();  
        } else if (a instanceof Dog) { // 狗做的事情 
            Dog c = (Dog)a;  
            c.work();  
        }  
    }  
}

abstract class Animal {  
    abstract void eat();  
}  

class Cat extends Animal {  
    public void eat() {  
        System.out.println("吃魚");  
    }  
    public void work() {  
        System.out.println("抓老鼠");  
    }  
}  

class Dog extends Animal {  
    public void eat() {  
        System.out.println("吃骨頭");  
    }  
    public void work() {  
        System.out.println("看家");  
    }  
}

編譯運行以上 Java 代碼子檀,輸出結果如下

吃魚
抓老鼠
吃骨頭
看家
吃魚
抓老鼠

虛方法

重寫可以讓子類能夠重寫父類的方法

當子類對象調用重寫的方法時,調用的是子類的方法乃戈,而不是父類中被重寫的方法

要想調用父類中被重寫的方法褂痰,則必須使用關鍵字 super

首先,我們先定義一個 Employee 類

public class Employee {
   private String name;
   private String address;
   private int number;
   public Employee(String name, String address, int number) {
      System.out.println("Employee 構造函數(shù)");
      this.name = name;
      this.address = address;
      this.number = number;
   }
   public void mailCheck() {
      System.out.println("郵寄支票給: " + this.name
       + " " + this.address);
   }
   public String toString() {
      return name + " " + address + " " + number;
   }
   public String getName() {
      return name;
   }
   public String getAddress() {
      return address;
   }
   public void setAddress(String newAddress) {
      address = newAddress;
   }
   public int getNumber() {
     return number;
   }
}

然后寫一個 Salary 類繼承 Employee 類

public class Salary extends Employee
{
   private double salary; // 全年工資
   public Salary(String name, String address, int number, double salary) {
       super(name, address, number);
       setSalary(salary);
   }
   public void mailCheck() {
       System.out.println("Salary 類的 mailCheck 方法 ");
       System.out.println("郵寄支票給:" + getName()
       + " 症虑,工資為:" + salary);
   }
   public double getSalary() {
       return salary;
   }
   public void setSalary(double newSalary) {
       if(newSalary >= 0.0) {
          salary = newSalary;
       }
   }
   public double computePay() {
      System.out.println("計算工資缩歪,付給:" + getName());
      return salary/52;
   }
}

然后寫一個測試類生成 Salary 類對象并調用一些方法

public class VirtualDemo {
   public static void main(String [] args) {
      Salary s = new Salary("員工 A", "北京", 3, 3600.00);
      Employee e = new Salary("員工 B", "上海", 2, 2400.00);
      System.out.println("使用 Salary 的引用調用 mailCheck -- ");
      s.mailCheck();
      System.out.println("\n使用 Employee 的引用調用 mailCheck--");
      e.mailCheck();
    }
}

編譯運行以上 Java 代碼,輸出結果如下

Employee 構造函數(shù)
Employee 構造函數(shù)
使用 Salary 的引用調用 mailCheck --
Salary 類的 mailCheck 方法
郵寄支票給:員工 A 谍憔,工資為:3600.0
使用 Employee 的引用調用 mailCheck--
Salary 類的 mailCheck 方法
郵寄支票給:員工 B 匪蝙,工資為:2400.0

在上面 3 個文件中

  1. 實例化了兩個 Salary 對象:一個使用 Salary 引用 s,另一個使用 Employee 引用 e
  2. 當調用 s.mailCheck() 時韵卤,編譯器在編譯時會在 Salary 類中找到 mailCheck()骗污,執(zhí)行過程 JVM 就調用 Salary 類的 mailCheck()
  3. 因為 e 是 Employee 的引用,所以調用 e 的 mailCheck() 方法時沈条,編譯器會去 Employee 類查找 mailCheck() 方法
  4. 在編譯的時候需忿,編譯器使用 Employee 類中的 mailCheck() 方法驗證該語句, 但是在運行的時候,Java虛擬機(JVM)調用的是 Salary 類中的 mailCheck() 方法

這個過程被稱為虛擬方法調用屋厘,該方法被稱為虛擬方法

Java 中所有的方法都能以這種方式表現(xiàn)涕烧,因此,重寫的方法能在運行時調用汗洒,不管編譯的時候源代碼中引用變量是什么數(shù)據類型

?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末议纯,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子溢谤,更是在濱河造成了極大的恐慌瞻凤,老刑警劉巖,帶你破解...
    沈念sama閱讀 221,430評論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件世杀,死亡現(xiàn)場離奇詭異阀参,居然都是意外死亡,警方通過查閱死者的電腦和手機瞻坝,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,406評論 3 398
  • 文/潘曉璐 我一進店門蛛壳,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人所刀,你說我怎么就攤上這事衙荐。” “怎么了浮创?”我有些...
    開封第一講書人閱讀 167,834評論 0 360
  • 文/不壞的土叔 我叫張陵忧吟,是天一觀的道長。 經常有香客問我蒸矛,道長瀑罗,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 59,543評論 1 296
  • 正文 為了忘掉前任雏掠,我火速辦了婚禮斩祭,結果婚禮上,老公的妹妹穿的比我還像新娘乡话。我一直安慰自己摧玫,他們只是感情好,可當我...
    茶點故事閱讀 68,547評論 6 397
  • 文/花漫 我一把揭開白布绑青。 她就那樣靜靜地躺著诬像,像睡著了一般。 火紅的嫁衣襯著肌膚如雪闸婴。 梳的紋絲不亂的頭發(fā)上坏挠,一...
    開封第一講書人閱讀 52,196評論 1 308
  • 那天,我揣著相機與錄音邪乍,去河邊找鬼降狠。 笑死对竣,一個胖子當著我的面吹牛,可吹牛的內容都是我干的榜配。 我是一名探鬼主播否纬,決...
    沈念sama閱讀 40,776評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼蛋褥!你這毒婦竟也來了临燃?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 39,671評論 0 276
  • 序言:老撾萬榮一對情侶失蹤烙心,失蹤者是張志新(化名)和其女友劉穎膜廊,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體弃理,經...
    沈念sama閱讀 46,221評論 1 320
  • 正文 獨居荒郊野嶺守林人離奇死亡溃论,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 38,303評論 3 340
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了痘昌。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 40,444評論 1 352
  • 序言:一個原本活蹦亂跳的男人離奇死亡炬转,死狀恐怖辆苔,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情扼劈,我是刑警寧澤驻啤,帶...
    沈念sama閱讀 36,134評論 5 350
  • 正文 年R本政府宣布,位于F島的核電站荐吵,受9級特大地震影響骑冗,放射性物質發(fā)生泄漏。R本人自食惡果不足惜先煎,卻給世界環(huán)境...
    茶點故事閱讀 41,810評論 3 333
  • 文/蒙蒙 一贼涩、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧薯蝎,春花似錦遥倦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,285評論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至消略,卻和暖如春堡称,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背艺演。 一陣腳步聲響...
    開封第一講書人閱讀 33,399評論 1 272
  • 我被黑心中介騙來泰國打工却紧, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留婿失,地道東北人。 一個月前我還...
    沈念sama閱讀 48,837評論 3 376
  • 正文 我出身青樓啄寡,卻偏偏與公主長得像豪硅,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子挺物,可洞房花燭夜當晚...
    茶點故事閱讀 45,455評論 2 359

推薦閱讀更多精彩內容

  • 多態(tài)是同一個行為具有多個不同表現(xiàn)形式或形態(tài)的能力懒浮。 多態(tài)就是同一個接口,使用不同的實例而執(zhí)行不同操作识藤,如圖所示: ...
    Java架構學習者閱讀 274評論 0 1
  • 多態(tài)是同一個行為具有多個不同表現(xiàn)形式或形態(tài)的能力砚著。 多態(tài)就是同一個接口,使用不同的實例而執(zhí)行不同操作痴昧,如圖所示: ...
    Java機械師閱讀 2,282評論 1 0
  • 多態(tài)是同一個行為具有多個不同表現(xiàn)形式或形態(tài)的能力稽穆。 多態(tài)就是同一個接口,使用不同的實例而執(zhí)行不同操作赶撰,如圖所示: ...
    java伯爵閱讀 1,993評論 0 0
  • **多態(tài)是同一個行為具有多個不同表現(xiàn)形式或形態(tài)的能力舌镶。 **多態(tài)性是對象多種表現(xiàn)形式的體現(xiàn)。 多態(tài)存在的三個必要條...
    清風沐沐閱讀 266評論 0 0
  • Java多態(tài) 1豪娜、多態(tài)的總結 面向對象編程有三大特性:封裝餐胀、繼承、多態(tài)瘤载。 封裝隱藏了類的內部實現(xiàn)機制否灾,可以在不影響...
    wymhuster閱讀 702評論 0 3