Java多態之向上轉型

Java多態之向上轉型

多態性是面向對象的第三大特徵。ide

多態的優勢

  • 改善代碼的組織結構和可讀性。
  • 可以建立可擴展的程序。(隨時能夠加入新功能
  • 消除類型之間的耦合關係。

說實話,做爲小白的我,並不太可以理解上面三個優勢。隨着深刻學習,理解應該會愈來愈深吧,共勉。學習

向上轉型

概念

Java容許把子類對象賦值給父類的引用變量,不用作任何強制轉換,系統自動完成。向上轉型來自於自下而上的繼承關係,子類繼承父類,子類是一種特殊的父類,因此向上轉型的操做實際上是情理之中的。測試

下面依照簡單的代碼,來試着理解向上轉型的概念與好處。code

package com.my.pac14;

/**
 * @auther Summerday
 */
public class DynamicBinding {
    //Object是全部類的超類,根據向上轉型,該方法能夠接受任何類型的對象
    public static void test(Object x) {
        System.out.println(x.toString());
    }

    public static void main(String[] args) {
        test(new PrimaryStudent());//Student
        test(new Student());//Student
        test(new Person());//Person
        test(new Object());//java.lang.Object@1b6d3586
    }
}

class Person extends Object {
    @Override
    public String toString() {
        return "Person";
    }
}

class Student extends Person {
    @Override
    public String toString() {
        return "Student";
    }
}

class PrimaryStudent extends Student {
}
  • 咱們能夠看到,下面的方法接收一個Object類型的對象,並調用該對象的toString()方法。
public static void test(Object x) {
        System.out.println(x.toString());
    }
  • 下面是調用語句,除了第四句,其餘的傳入對象都看起來與形參類型不符,但固然是能夠運行的,這裏面就蘊含着咱們說的向上轉型
public static void main(String[] args) {
    test(new PrimaryStudent());//Student
    test(new Student());//Student
    test(new Person());//Person
    test(new Object());//java.lang.Object@1b6d3586
}
  • 就拿傳入Student類型的對象來講吧,拆解一下,是如下的表達式:
Object x = new Student();
  • Object類是全部類的超類,上式中將建立的子類類型對象直接賦給父類類型的引用變量,這在Java中是容許的,這就是所謂的向上轉型。可以實現的緣由,也是由於子類在向上轉型的過程當中,也許會縮小接口,但至少不會比父類中有的接口還要窄

舉個簡單的例子,假設人類能夠分爲不少不少種,咱們能夠說學生是人類的一種,卻不能說人類是學生的一種。向上轉型必定程度上容許子類擴展超類的部分丟失,經過父類引用變量只能調用父類中的方法來實現,咱們去操做人類的時候,只能在人類具備的行爲屬性中作選擇,而不能直接以學生類的標準去操做它,由於咱們並不知道他是哪一類,萬一不是學生呢,對吧,用人類總沒錯,由於我人類有的東西,你學生類必定有。這就是我所理解的向上轉型。對象

向上轉型好在哪

若是沒有向上轉型機制,咱們想要達到原來的效果,就須要增長許多重載的test方法,這樣就顯得過於繁瑣。若是要增長相似test()的方法或者添加從Object導出的新類,還會作更多複雜的操做,不利於擴展,不可取不可取。繼承

// 原來的狀況:須要建立不少不少的測試方法。
    public static void test(Object x) {
        System.out.println(x.toString());
    }
    public static void test(Person x) {
        System.out.println(x.toString());
    }
    public static void test(Student x) {
        System.out.println(x.toString());
    }
    public static void test(PrimaryStudent x) {
        System.out.println(x.toString());
    }

多態的存在正好解決了這個棘手的問題,爲了利於擴展,只須要寫一個僅接收基類做爲參數的簡單方法,無論導出類如何,在運行時自動選擇調用對應導出類的方法,真的就很舒服。接口

那麼,編譯器又是如何肯定應該調用哪一個方法呢?這就涉及到所謂的「綁定」啦,這個呢,咱們在下片總結。編譯器

參考書籍:《Thinking in Java》it

相關文章
相關標籤/搜索