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
  • 1. 說明 /* Performs operations on System.String instances that contain file or directory path information. These operations are performed in a cross-pla ...
  • 視頻地址:【WebApi+Vue3從0到1搭建《許可權管理系統》系列視頻:搭建JWT系統鑒權-嗶哩嗶哩】 https://b23.tv/R6cOcDO qq群:801913255 一、在appsettings.json中設置鑒權屬性 /*jwt鑒權*/ "JwtSetting": { "Issuer" ...
  • 引言 集成測試可在包含應用支持基礎結構(如資料庫、文件系統和網路)的級別上確保應用組件功能正常。 ASP.NET Core 通過將單元測試框架與測試 Web 主機和記憶體中測試伺服器結合使用來支持集成測試。 簡介 集成測試與單元測試相比,能夠在更廣泛的級別上評估應用的組件,確認多個組件一起工作以生成預 ...
  • 在.NET Emit編程中,我們探討了運算操作指令的重要性和應用。這些指令包括各種數學運算、位操作和比較操作,能夠在動態生成的代碼中實現對數據的處理和操作。通過這些指令,開發人員可以靈活地進行算術運算、邏輯運算和比較操作,從而實現各種複雜的演算法和邏輯......本篇之後,將進入第七部分:實戰項目 ...
  • 前言 多表頭表格是一個常見的業務需求,然而WPF中卻沒有預設實現這個功能,得益於WPF強大的控制項模板設計,我們可以通過修改控制項模板的方式自己實現它。 一、需求分析 下圖為一個典型的統計表格,統計1-12月的數據。 此時我們有一個需求,需要將月份按季度劃分,以便能夠直觀地看到季度統計數據,以下為該需求 ...
  • 如何將 ASP.NET Core MVC 項目的視圖分離到另一個項目 在當下這個年代 SPA 已是主流,人們早已忘記了 MVC 以及 Razor 的故事。但是在某些場景下 SSR 還是有意想不到效果。比如某些靜態頁面,比如追求首屏載入速度的時候。最近在項目中回歸傳統效果還是不錯。 有的時候我們希望將 ...
  • System.AggregateException: 發生一個或多個錯誤。 > Microsoft.WebTools.Shared.Exceptions.WebToolsException: 生成失敗。檢查輸出視窗瞭解更多詳細信息。 內部異常堆棧跟蹤的結尾 > (內部異常 #0) Microsoft ...
  • 引言 在上一章節我們實戰了在Asp.Net Core中的項目實戰,這一章節講解一下如何測試Asp.Net Core的中間件。 TestServer 還記得我們在集成測試中提供的TestServer嗎? TestServer 是由 Microsoft.AspNetCore.TestHost 包提供的。 ...
  • 在發現結果為真的WHEN子句時,CASE表達式的真假值判斷會終止,剩餘的WHEN子句會被忽略: CASE WHEN col_1 IN ('a', 'b') THEN '第一' WHEN col_1 IN ('a') THEN '第二' ELSE '其他' END 註意: 統一各分支返回的數據類型. ...
  • 在C#編程世界中,語法的精妙之處往往體現在那些看似微小卻極具影響力的符號與結構之中。其中,“_ =” 這一組合突然出現還真不知道什麼意思。本文將深入剖析“_ =” 的含義、工作原理及其在實際編程中的廣泛應用,揭示其作為C#語法奇兵的重要角色。 一、下劃線 _:神秘的棄元符號 下劃線 _ 在C#中並非 ...