Java——多態的學習

今天繼續填坑,說一下Java多態。

上一篇博客中,我們已經學習了繼承,這裏我補充一個小的知識點。其實任何一個我們定義的類,假如沒有給這個類繼承一個父類,那麼這個類就默認繼承一個Object類

我們先來看一下多態的定義吧

在這裏插入圖片描述

簡單來說就是子類重寫了父類的重名方法,當我們調用這個方法是可以調用到不同類中的同名方法。我們先來看個例子吧

public class PolyDemo {
    public static void main(String[] args) {
        print(new Object());
        print(new Person());
        print(new Student());
        print(new GraduateStudent());
    }

    public static void print(Object o){
        System.out.println(o.toString());
    }
}

class Person{
    public String toString(){
        return "Person!";
    }
}

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

class GraduateStundet extend Student{
    public String toString(){
        return "GraduateStudent!";
    }
}

在這段代碼中,我定義了三個類,分別是Person,Student和GraduatStudent。三個類是繼承關係。可以看到三個類中都有一個重名的方法:toString。我們構建一個函數print來調用這個toString方法。

這裏我來解釋一下爲什麼要把print的形參設成Object類型。這裏就涉及到一個重要的知識點:動態綁定。什麼叫動態綁定呢?我們先來看一下這幾個類的繼承關係:

Object <- Person <- Student <- GraduateStudent

在這關係中,GrandeStudent是最特別的類,Object是最通用的類。在我們調用print方法時候,其實計算機會先從最特殊的類出發(GrandeStudent),如果我們傳入的參數是對應的GrandeStudent類,那麼就在這個類中調用toString方法。但假如我們的參數不是GrandeStudent呢?那Java虛擬機就會自動向上轉型,查找GrandeStudent的父類,看看形參與參數是否匹配,若匹配,則調用該類的toString方法。

那問題來了,假如找不到參數對應類中的方法呢?我把GraduateStudent的toString方法註釋了

class GraduateStundet extend Student{
    /*public String toString(){
        return "GraduateStundet!";
    }*/
}

大家可以猜一下運行的結果。我這裏就直接給大家放出運行結果吧:

在這裏插入圖片描述

可以看到,由於GraduateStudent中沒有toString的方法,那麼就會調用上一級,也就是它的父類中看看是否有重名的toString方法。如果有就直接調用,直到最終的父類Object。這裏我們簡單一點記憶就是從特殊到普遍,從兒子到老子。

爲了加深大家的理解,我這裏給出一道題目,設置一個printArea的方法,來打印所有幾何體的面積。幾何體和圓的類代碼我已經在上一篇博客中給出了,我現在再給出長方形類的代碼。

class Rectangle extends GeometicObject{
    double length,width;
    
    public Rectangle(){
        this.length = 2.0;
        this.width = 1.0;
    }
    
    public Rectangle(double length , double width,String color, boolean filled){
        super(color,filled);  //調用父類中的構造方法
        this.length = length;
        this.width = width;
    }
    
    public double getArea(){
        return width * length;
    }
    
    public String toString(){
        return super.toString() + "\nRectangle 's length :" + length
                + "\nRectangle 's width :" + width;
    }
}

接下來我們來構造一個printArea的方法:

public static void printArea(Geometry o){
        System.out.println("面積爲:" + o.getArea());
    }

值得注意,爲什麼這裏不用Object o作爲形參呢?這是因爲我們計算面積,面向的對象應該是所有的幾何體,因而以幾何體作爲最終父類更爲合適。

今天的多態內容到這裏就結束了,其實多態跟繼承一樣,並不難,關鍵在於靈活運用,分析好類之間的關係,合理進行繼承和方法重寫!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章