C#面向對象核心-多態

来源:https://www.cnblogs.com/tanyuyang/archive/2023/03/28/17266518.html
-Advertisement-
Play Games

多態 1 認識多態 1.1 基本概念 多態是同一個行為具有多個不同表現形式或形態的能力,意味著有多重形式。在面向對象編程範式中,多態性往往表現為"一個介面,多個功能"。 在 C# 中,每個類型都是多態的,因為包括用戶定義類型在內的所有類型都繼承自 Object。 多態性分為靜態的和動態多態。在靜態多 ...


多態

1 認識多態

1.1 基本概念

多態是同一個行為具有多個不同表現形式或形態的能力,意味著有多重形式。在面向對象編程範式中,多態性往往表現為"一個介面,多個功能"。

在 C# 中,每個類型都是多態的,因為包括用戶定義類型在內的所有類型都繼承自 Object。

多態性分為靜態的和動態多態。在靜態多態性中,函數的響應是在編譯時發生的。在動態多態性中,函數的響應是在運行時發生的。

  • 靜態多態:函數重載、運算符重載
  • 動態多態:vob(virtual 虛函數,override 重寫,base 父類)、抽象函數、介面

1.2 使用

class GameObject
{
    public string name;
    public GameObject(string name)
    {
        this.name = name;
    }
    //虛函數 可以被子類重寫
    public virtual void Atk()
    {
        Console.WriteLine("游戲對象進行攻擊");
    }
}
class Player : GameObject
{
    public Player(string name) : base(name)//調用父類的構造函數
    {

    }
    //重寫虛函數
    public override void Atk()
    {
        Console.WriteLine("玩家對象進行攻擊");
    }
}
class Monster : GameObject
{
    public Monster(string name) : base(name)
    {

    }
    public override void Atk()
    {
        base.Atk();//base代表父類,可以通過它來保留父類的行為,會調用一次父類的方法
        Console.WriteLine("怪物對象進行攻擊");
    }
}

class Father
{
    public void SpeakName()
    {
        Console.WriteLine("Father的方法");
    }
}
class Son : Father
{
    public new void SpeakName()
    {
        Console.WriteLine("Son的方法");
    }
}

//Main
//用父類取裝載子類的對象時,有兩個同名的方法,會優先調用父類的 多態就用來解決這類問題
Father f = new Son();
f.SpeakName();
(f as Son).SpeakName();

GameObject p = new Player("abc");//虛函數和重寫解決了問題
p.Atk();

GameObject m = new Monster("def");
m.Atk();
/*
輸出:
Father的方法
Son的方法

玩家對象進行攻擊

游戲對象進行攻擊
怪物對象進行攻擊
*/

2 abstract 抽象類和抽象方法

2.1 抽象類

abstract 關鍵字修飾的類。

特點:

  • 不能被實例化
  • 可以包含抽象方法
  • 繼承抽象類必須重寫其抽象方法
abstract class Thing//抽象一類物品
{
    public string name;
    
    //可以在抽象類中寫抽象函數
}
class Water : Thing
{

}

2.2 抽象方法

abstract 修飾的方法,又叫 純虛方法

特點:

  • 只能在抽象類中聲明
  • 沒有方法體
  • 不能是私有的
  • 繼承後必須實現,用override重寫
abstract class Fruits
{
    public string name;

    public virtual void Test()
    {
        //虛方法可以寫邏輯
    }
    public abstract void Bad();//抽象方法
}
class Apple : Fruits
{
    //虛方法在子類中可以選擇是否重寫
    //抽象方法一定要重寫
    public override void Bad()
    {

    }
}

3 介面

3.1 基本概念

關鍵字:interface,介面是行為的抽象規範,是抽象行為的“基類”,各種類通過繼承它來實現對應的行為。

介面聲明規範:

  1. 不包含成員變數
  2. 只包含方法、屬性、索引器、事件
  3. 成員不能被實現
  4. 成員可以不寫訪問修飾符,而且不能是私有的
  5. 介面不能繼承類,但是介面可以繼承另一個介面

介面使用規範:

  1. 類可以繼承多個介面
  2. 類繼承介面後,必須實現介面中所有成員

特點:

  1. 它和類的聲明類似
  2. 介面是用來繼承的
  3. 介面不能被實例化,但可以作為容器來存儲對象

3.2 聲明

/*
interface 介面名
{

}
介面名:I+帕斯卡命名法
*/
interface IFly
{
    void Fly();//方法

    string Name//屬性
    {
        get;
        set;
    }

    int this[int index]//索引
    {
        get;
        set;
    }

    event Action doSomething;//事件
}

3.3 使用

介面用來繼承:

  1. 類可以繼承1個類,n個介面
  2. 繼承了介面後,必須實現其中的內容,而且必須為 public
  3. 實現的介面函數,可以加 visual 再在子類中 override
  4. 介面遵循里氏替換原則
class Animal
{

}
class Tiger : Animal, IFly//繼承類和介面
{
    //實現介面內容
    public void Fly()
    {

    }
    public string Name
    {
        get;
        set;
    }
    public int this[int index]
    {
        get
        {
            return 0;
        }
        set
        {

        }
    }
    public event Action doSomething;
}

3.4 介面繼承介面

  • 介面繼承介面時,不需要實現
  • 類繼承介面後,去實現介面的所有內容
interface IWalk
{
    void Walk();
}

interface IMove : IFly, IWalk
{

}

class Test : IMove//實現所有內容
{
    public int this[int index] 
    { 
        get => throw new NotImplementedException(); set => throw new NotImplementedException(); 
    }

    public string Name 
    { 
        get => throw new NotImplementedException(); set => throw new NotImplementedException(); 
    }

    public event Action doSomething;

    public void Fly()
    {
        throw new NotImplementedException();
    }

    public void Walk()
    {
        throw new NotImplementedException();
    }
}

3.5 顯示實現介面

  • 當一個類繼承兩個介面,但是介面中存在著同名方法時使用
  • 註意:顯示實現介面時,不能寫訪問修飾符
interface IAtk
{
    void Atk();
}
interface ISuperAtk
{
    void Atk();
}

class Player : IAtk, ISuperAtk
{
    //顯示實現介面:介面名.行為名
    void IAtk.Atk()
    {

    }
    void ISuperAtk.Atk()
    {

    }
}

4 sealed 密封方法

4.1 基本概念

  • 密封方法:用 sealed 修飾的重寫函數,讓虛方法或抽象方法不能再被重寫,和 override 一起出現
  • 密封類:用 sealed 修飾的類,讓類不能被繼承

4.2 使用

abstract class Animal
{
    public string name;

    public abstract void Eat();

    public virtual void Speak()
    {
        Console.WriteLine("giao");
    }
}

class Person : Animal
{
    public override void Eat()
    {

    }

    public override void Speak()
    {

    }
}

class WhitePerson : Person
{
    public sealed override void Eat()//不能重寫了
    {
        base.Eat();
    }

    public override void Speak()
    {
        base.Speak();
    }
}

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

-Advertisement-
Play Games
更多相關文章
  • 藍橋杯【答疑】 題目描述 分析 這是一個貪心演算法,要所得的時刻之和最小,而且下一個同學需要等上一個同學結束以後才能進行,因此需要對所耗總時間進行有小到大的排序,總時間相同的同學則對前兩步時間之和有小到大進行排序,最後算出時間之和即可。 代碼 import java.util.Arrays; impo ...
  • 附件用的fastdf上傳和下載的, 本地開發時就沒考慮過多文件上傳就會有併發的問題,比如多個只上傳成功了一個或者上傳了但是文檔內容缺失了,變成0位元組。 呵。。都是一次難忘的經歷。 經過本地模擬大批量的上傳下載, 發現fastdf是在啟動時就初始化了tracker和stroge, 每次調用過他的介面後 ...
  • 一、Jx9 虛擬機的生命周期 載入 Jx9 腳本 jx9_compile() 或 jx9_compile_file(),載入編譯成功後,Jx9 引擎將自動創建一個實例 (jx9_vm) 並且返回指向此虛擬機的指針用於後續調用。 如載入編譯 Jx9 腳本時出現問題,也就是編譯時出錯,可調用jx9_co ...
  • 生產環境,一個簡單的事務方法,提交失敗,報 Global lock wait timeout 偽代碼如下: @GlobalTransactional(rollbackFor = Exception.class,timeoutMills = 30000,lockRetryInternal=3000,l ...
  • PowerPlume是PowerBuilder深度創新的擴展開發框架(免費商用)。 它的三個主要特色是一、原創功能;二、零改動相容(非侵入性);三、極簡介面設計。 ...
  • 記錄人生第一次重裝系統之後的數據恢復過程,包括桌面恢復、常用軟體下載和屬性修改、vscode插件、zotero數據恢復、onenote筆記數據恢復,讓重裝系統的你不用慌。 ...
  • 發文原因 很多初學者都使用 cargo new [project_name] 來創建項目,並直接在 main.rs 文件中實現所有功能。 這樣是不合理的,並不符合我們 cargo 的開發規範。 下麵將簡單的介紹一下 rust project 中的文件結構。 cargo new [project_na ...
  • 其他 1 命名空間 命名空間用來組織和重用代碼的,命名空間就像一個工具包,類就像工具。 1.1 使用 namespace MyGame { class GameObject { } } namespace MyGame//命名空間可以分開寫 { class Player : GameObject { ...
一周排行
    -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版本說明 機器同時安裝了 ...