Java學習筆記(十一)面向對象---多態

来源:https://www.cnblogs.com/liyuxin2/archive/2020/02/15/12313781.html
-Advertisement-
Play Games

多態的體現 父類的引用指向了自己的子類對象。 父類的引用也可以接受自己的子類對象。 代碼體現 運行結果 多態的前提 必須是類與類之間有關係。要麼是繼承關係,要麼實現。 存在覆寫關係。 多態利弊 利處 多態的出現大大地提高了程式的拓展性。 弊端 提高了拓展性,但是只能使用父類的引用訪問父類中的成員,不 ...


多態的體現

父類的引用指向了自己的子類對象。
父類的引用也可以接受自己的子類對象。

代碼體現

abstract class Animal {
    public abstract void eat();
}
class Cat extends Animal {
    @Override
    public void eat() {
        System.out.println("eat fish");
    }
}
class Dog extends Animal {
    @Override
    public void eat() {
        System.out.println("eat bone");
    }
}
class Monkey extends Animal {
    @Override
    public void eat() {
        System.out.println("eat banana");
    }
}
public class Demo {
    public static void main(String[] args) {
        /*
        Animal c = new Cat();
        function(c);
         */
        function(new Cat());
        /*
        Animal d = new Dog();
        function(d);
        */
        function(new Dog());
        /*
        Animal m = new Monkey();
        function(m);
        */
        function(new Monkey());
    }
    public static void function(Animal a) {
        a.eat();
     }
}

運行結果

eat fish
eat bone
eat banana

多態的前提

必須是類與類之間有關係。要麼是繼承關係,要麼實現。
存在覆寫關係。

多態利弊

利處

多態的出現大大地提高了程式的拓展性。

弊端

提高了拓展性,但是只能使用父類的引用訪問父類中的成員,不能預先訪問子類的成員(因為子類這時還不存在)。

多態-示例

abstract class Student {
    public void eat() {
        System.out.println("eat rice");
    }
    public abstract void study();
}
class StudentToDo {
    public void Do(Student s) {
        s.eat();
        s.study();
    }
}
class StudentClass1 extends Student {
    @Override
    public void eat() {
        System.out.println("eat steak");
    }
    @Override
    public void study() {
        System.out.println("study English");
    }
}
class StudentClass2 extends Student {
    @Override
    public void study() {
        System.out.println("study Chinese");
    }
}
class StudentClass3 extends Student {
    @Override
    public void study() {
        System.out.println("study Japanese");
    }
}
public class Demo2 {
    public static void main(String[] args) {
        StudentToDo std =  new StudentToDo();
        std.Do(new StudentClass1());
        std.Do(new StudentClass2());
        std.Do(new StudentClass3());
    }
}

運行結果:

eat steak
study English
eat rice
study Chinese
eat rice
study Japanese

多態的出現 代碼中的特點(多態使用的註意事項)

多態中成員函數的特點

在編譯時期,參閱引用類型變數所屬的類中是否有調用的方法,如果有編譯通過,如果沒有編譯失敗。
在運行時期,參閱對象所屬的類中是否有調用的方法。
簡單總結:成員函數在多態調用時,編譯看左邊,運行看右邊。

class Fu {
    void method1() {
        System.out.println("Fu_Method_1");
    }
    void method2() {
        System.out.println("Fu_Method_2");
    }
}
class Zi extends Fu {
    @Override
    void method1() {
        System.out.println("Zi_Method_1");
    }
    void method3() {
        System.out.println("Zi_Method_3");
    }
}
public class Demo3 {
    public static void main(String[] args) {
        Fu f =new Zi();
        f.method1();
        f.method2();
        //f.method3(); 對於引用類型f所屬的類Fu中沒有method3()方法,所以編譯會不通過。
    }
}

運行結果:

Zi_Method_1
Fu_Method_2

多態中成員變數的特點

無論編譯還是運行,都參考左邊(引用型變數所屬的類)

class Fu {
    int num = 1;
}
class Zi extends Fu {
    int num = 2;
}
public class Demo4 {
    public static void main(String[] args) {
        Fu f = new Zi();
        System.out.println(f.num);   //參考左邊
        Zi z= new Zi();
        System.out.println(z.num);
    }
}

運行結果:

1
2

多態中靜態成員函數(變數)的特點

無論編譯還是運行,都參考左邊。
靜態類型,靜態綁定。
非靜態類型,動態綁定。

class Fu {
    static void method1() {
        System.out.println("Fu_Method_1");
    }
}
class Zi extends Fu {
    static void method1() {
        System.out.println("Zi_Method_1");
    }
}
public class Demo5 {
    public static void main(String[] args) {
        Fu f = new Zi();
        f.method1();
        Zi z = new Zi();
        z.method1();
    }
}

運行結果:

Fu_Method_1
Zi_Method_1

多態-轉型

abstract class Animal {
    public abstract void eat();
}
class Cat extends Animal {
    @Override
    public void eat() {
        System.out.println("eat fish");
    }
    public void CatchMouse() {
        System.out.println("CatchMouse");
    }
}
class Dog extends Animal {
    @Override
    public void eat() {
        System.out.println("eat bone");
    }
    public void GuardHouse() {
        System.out.println("GuardHouse");
    }
}
class Monkey extends Animal {
    @Override
    public void eat() {
        System.out.println("eat banana");
    }
    public void PlayBall() {
        System.out.println("Play Ball");
    }
}
public class Demo1 {
    public static void main(String[] args) {
        function(new Cat());
        function(new Dog());
        function(new Monkey());
    }
    public static void function(Animal a) {
        a.eat();
        if (a instanceof Cat) { //instanceof關鍵字用於判斷所屬類型
            Cat c = (Cat)a;     //向下轉型
            c.CatchMouse();
        } else if (a instanceof Dog) {
            Dog d = (Dog)a;     //向下轉型
            d.GuardHouse();
        } else {
            Monkey m = (Monkey)a;//向下轉型
            m.PlayBall();
        }
    }
}

運行結果:

eat fish
CatchMouse
eat bone
GuardHouse
eat banana
Play Ball

多態的應用

以電腦主板為例的示例
分析電腦主板要考慮到拓展性,使用了pci介面,板卡(音效卡,網卡等)和主板都遵循pci介面。

interface Pci {
    public void open();
    public void close();
}

class MainBoard {
    public void run() {
        System.out.println("Main Board run");
    }
    public void usePci(Pci p){ //介面類型指向自己的子類對象
        if(p != null){    //加入判斷防止空指針
        p.open();
        p.close();
        }
    }
}
class Netcard implements Pci {
    @Override
    public void open() {
        System.out.println("Netcard open");
    }

    @Override
    public void close() {
        System.out.println("Netcard close");
    }
}
class Soundcard implements Pci {
    @Override
    public void open() {
        System.out.println("Soundcard open");
    }

    @Override
    public void close() {
        System.out.println("Soundcard close");
    }
}
public class Demo6 {
    public static void main(String[] args) {
        MainBoard mb = new MainBoard();
        mb.run();
        mb.usePci(null);
        mb.usePci(new Netcard());
        mb.usePci(new Soundcard());
    }
}

運行結果

Main Board run
Netcard open
Netcard close
Soundcard open
Soundcard close

您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 楔子 假如我現在有一個列表l=['a','b','c','d','e'],我想取列表中的內容,有幾種方式? 首先,我可以通過索引取值l[0],其次我們是不是還可以用for迴圈來取值呀? 你有沒有仔細思考過,用索引取值和for迴圈取值是有著微妙區別的。 如果用索引取值,你可以取到任意位置的值,前提是你 ...
  • 楔子 作為一個會寫函數的python開發,我們從今天開始要去公司上班了。寫了一個函數,就交給其他開發用了。 def func1(): print('in func1') 季度末,公司的領導要給大家發績效獎金了,就提議對這段日子所有人開發的成果進行審核,審核的標準是什麼呢?就是統計每個函數的執行時間。 ...
  • 楔子 假如有一個函數,實現返回兩個數中的較大值: def my_max(x,y): m = x if x>y else y return mbigger = my_max(10,20)print(bigger) 之前是不是我告訴你們要把結果return回來你們就照做了?可是你們有沒有想過,我們為什麼 ...
  • 好久時間沒有做Django的項目了,今天創建項目竟然報Non-zero exit code(1)錯誤 查明原因是因為pip不是最新版本,需要執行以下命令:python -m pip install --upgrade pip 但還是沒有成功,提示超時,估計源有問題 使用豆瓣源進行安裝,問題解決了 命 ...
  • 前言最近由於疫情被困在家,於是準備每天看點專業知識,準備寫成博客,不定期發佈。博客大概會寫5~7篇,主要是“解剖”一些深度學習的底層技術。關於深度學習,電腦專業的人多少都會瞭解,知道Conv\Pool的過程,也看過論文,做過實驗或是解決方案。在寫的各種捲積網路 時候,有沒有問問自己:這些網路到底是... ...
  • 為什麼要用函數 現在python屆發生了一個大事件,len方法突然不能直接用了。。。 然後現在有一個需求,讓你計算'hello world'的長度,你怎麼計算? 這個需求對於現在的你其實不難,我們一起來寫一下。 s1 = "hello world" length = 0 for i in s1: l ...
  • 慕課網-悟空-玩轉Java併發工具,精通JUC,成為併發多面手-筆記 微雲:https://share.weiyun.com/81aa12bb98016e200add31fb8e191cdf百度網盤:鏈接:https://pan.baidu.com/s/1IiClTkQwFJgBL2NqlptKbA ...
  • 一、前言 從學單片機開始鼓搗C語言,到現在為了學CV鼓搗Python,期間在CSDN、簡書、博客園和github這些地方得到了很多幫助,所以也想把自己做的一些小東西分享給大家,希望能幫助到別人。記錄人生的第一篇博客,mark。 二、圖像檢測步驟 1. 讀取兩張圖片 第一張是需要檢測的小物體,第二章圖 ...
一周排行
    -Advertisement-
    Play Games
  • Timer是什麼 Timer 是一種用於創建定期粒度行為的機制。 與標準的 .NET System.Threading.Timer 類相似,Orleans 的 Timer 允許在一段時間後執行特定的操作,或者在特定的時間間隔內重覆執行操作。 它在分散式系統中具有重要作用,特別是在處理需要周期性執行的 ...
  • 前言 相信很多做WPF開發的小伙伴都遇到過表格類的需求,雖然現有的Grid控制項也能實現,但是使用起來的體驗感並不好,比如要實現一個Excel中的表格效果,估計你能想到的第一個方法就是套Border控制項,用這種方法你需要控制每個Border的邊框,並且在一堆Bordr中找到Grid.Row,Grid. ...
  • .NET C#程式啟動閃退,目錄導致的問題 這是第2次踩這個坑了,很小的編程細節,容易忽略,所以寫個博客,分享給大家。 1.第一次坑:是windows 系統把程式運行成服務,找不到配置文件,原因是以服務運行它的工作目錄是在C:\Windows\System32 2.本次坑:WPF桌面程式通過註冊表設 ...
  • 在分散式系統中,數據的持久化是至關重要的一環。 Orleans 7 引入了強大的持久化功能,使得在分散式環境下管理數據變得更加輕鬆和可靠。 本文將介紹什麼是 Orleans 7 的持久化,如何設置它以及相應的代碼示例。 什麼是 Orleans 7 的持久化? Orleans 7 的持久化是指將 Or ...
  • 前言 .NET Feature Management 是一個用於管理應用程式功能的庫,它可以幫助開發人員在應用程式中輕鬆地添加、移除和管理功能。使用 Feature Management,開發人員可以根據不同用戶、環境或其他條件來動態地控制應用程式中的功能。這使得開發人員可以更靈活地管理應用程式的功 ...
  • 在 WPF 應用程式中,拖放操作是實現用戶交互的重要組成部分。通過拖放操作,用戶可以輕鬆地將數據從一個位置移動到另一個位置,或者將控制項從一個容器移動到另一個容器。然而,WPF 中預設的拖放操作可能並不是那麼好用。為瞭解決這個問題,我們可以自定義一個 Panel 來實現更簡單的拖拽操作。 自定義 Pa ...
  • 在實際使用中,由於涉及到不同編程語言之間互相調用,導致C++ 中的OpenCV與C#中的OpenCvSharp 圖像數據在不同編程語言之間難以有效傳遞。在本文中我們將結合OpenCvSharp源碼實現原理,探究兩種數據之間的通信方式。 ...
  • 一、前言 這是一篇搭建許可權管理系統的系列文章。 隨著網路的發展,信息安全對應任何企業來說都越發的重要,而本系列文章將和大家一起一步一步搭建一個全新的許可權管理系統。 說明:由於搭建一個全新的項目過於繁瑣,所有作者將挑選核心代碼和核心思路進行分享。 二、技術選擇 三、開始設計 1、自主搭建vue前端和. ...
  • Csharper中的表達式樹 這節課來瞭解一下表示式樹是什麼? 在C#中,表達式樹是一種數據結構,它可以表示一些代碼塊,如Lambda表達式或查詢表達式。表達式樹使你能夠查看和操作數據,就像你可以查看和操作代碼一樣。它們通常用於創建動態查詢和解析表達式。 一、認識表達式樹 為什麼要這樣說?它和委托有 ...
  • 在使用Django等框架來操作MySQL時,實際上底層還是通過Python來操作的,首先需要安裝一個驅動程式,在Python3中,驅動程式有多種選擇,比如有pymysql以及mysqlclient等。使用pip命令安裝mysqlclient失敗應如何解決? 安裝的python版本說明 機器同時安裝了 ...