C#中抽象類、抽象方法和接口暨內聯臨時變量的精彩表達

目錄

一、抽象類

?1.示例

二、抽象方法

三、接口

1.示例

2.內聯表達治愈警告CA1859

(1)傳統程序書寫源碼

(2)內聯后的源碼

四、多重繼承

1.示例

五、顯式接口成員實現

1.示例

六、總結?


贈人玫瑰,手有余香,?留下心得,換點流量。

一、抽象類

????????一般將父類定義為抽象類,需要使用這個父類進行繼承與多態處理。C#中聲明抽象類時需要使用abstract關鍵字,聲明抽象類時,除abstract關鍵字、class關鍵字和類名外,其他的都是可選項。

????????抽象類除了被繼承之外沒有任何意義

?1.示例

//抽象類、抽象方法
namespace _01
{public abstract class MyClass{private string id = "";private string name = "";/// <summary>/// 編號屬性及實現/// </summary>public string ID{get{return id;}set{id = value;}}/// <summary>/// 姓名屬性及實現/// </summary>public string Name{get{return name;}set{name = value;}}/// <summary>/// 抽象方法,用來輸出信息/// </summary>public abstract void ShowInfo();}public class DriveClass : MyClass			     //繼承抽象類{/// <summary>/// 重寫抽象類中輸出信息的方法/// </summary>public override void ShowInfo(){Console.WriteLine(ID + " " + Name);}}class Program{/// <summary>/// 內聯/// </summary>static void Main(string[] args){DriveClass driveclass = new();     //實例化派生類,內聯前用派生類對象實例化抽象類                                                             ((DriveClass)driveclass).ID = "BH0001"; //使用抽象類對象訪問抽象類中的編號屬性((DriveClass)driveclass).Name = "TM";   //使用抽象類對象訪問抽象類中的姓名屬性((DriveClass)driveclass).ShowInfo();    //使用抽象類對象調用派生類中的方法Console.WriteLine("------------");driveclass.ID = "BH0001";              //派生類直接實例化driveclass.Name = "TM";driveclass.ShowInfo();Console.Read();}}
}//結果:
/*BH0001 TM
---------------
BH0001 TM*/

二、抽象方法

????????在抽象類中聲明方法時,如果加上abstract關鍵字,則為抽象方法。

????????使用abstract關鍵字定義的類稱為抽象類,而使用這個關鍵字定義的方法稱為抽象方法,抽象方法沒有方法體,這個方法本身沒有任何意義,除非它被重寫,而承載這個抽象方法的抽象類就必須被繼承。反之,如果聲明一個抽象的方法,就必須將承載這個抽象方法的類定義為抽象類,不可能在非抽象類中獲取抽象方法。只要類中有一個抽象方法,此類就被標記為抽象類。

????????抽象類被繼承后需要實現其中所有的抽象方法,也就是保證相同的方法名稱、參數列表和相同返回值類型創建出非抽象方法,當然也可以是抽象方法。繼承抽象類的所有子類需要將抽象類中的抽象方法進行覆蓋。

聲明抽象方法時需要注意以下兩點:
? 抽象方法必須聲明在抽象類中。
? 聲明抽象方法時,不能使用virtual、static和private修飾符。

????????抽象方法聲明引入了一個新方法,但不提供該方法的實現,由于抽象方法不提供任何實際實現,因此抽象方法的方法體只包含一個分號。

????????當從抽象類派生一個非抽象類時,需要在非抽象類中重寫抽象方法,以提供具體的實現,重寫抽象方法時使用override關鍵字。

三、接口

????????接口是抽象類的延伸,可以將它看作是純粹的抽象類,接口中的所有方法都沒有方法體。接口可由方法、屬性、事件和索引器或這4種成員類型的任何組合構成,但不能包含字段,也不能設置這些成員的具體值,即,只能定義,不能給它們賦值。?接口可以繼承其他接口。??

接口具有以下特征:
? 接口類似于抽象基類:繼承接口的任何非抽象類型都必須實現接口的所有成員。
? 不能直接實例化接口。
? 接口可以包含事件、索引器、方法和屬性。
? 接口不包含方法的實現。
? 類和結構可從多個接口繼承。
? 接口自身可從多個接口繼承。

1.示例

// 接口
namespace _02
{interface IMyInterface{/// <summary>/// 編號(可讀可寫)/// </summary>string ID{get;set;}/// <summary>/// 姓名(可讀可寫)/// </summary>string Name{get;set;}/// <summary>/// 顯示定義的編號和姓名/// </summary>void ShowInfo();}class Program : IMyInterface    //繼承自接口{string id = "";string name = "";/// <summary>/// 編號/// </summary>public string ID{get{return id;}set{id = value;}}/// <summary>/// 姓名/// </summary>public string Name{get{return name;}set{name = value;}}/// <summary>/// 顯示定義的編號和姓名/// </summary>public void ShowInfo(){Console.WriteLine("編號\t 姓名");Console.WriteLine(ID + "\t " + Name);}/// <summary>/// 注釋掉的部分,警告CA1859/// 內聯臨時變量后,警告消失/// </summary>static void Main(string[] args){Program program = new();                      //實例化Program類對象//IMyInterface Imyinterface = program;        //使用派生類對象實例化接口ImyInterface//Imyinterface.ID = "TM";                     //為派生類中的ID屬性賦值//Imyinterface.Name = "C#從入門到精通";        //為派生類中的Name屬性賦值//Imyinterface.ShowInfo();((IMyInterface)program).ID = "TM";            //為派生類中的ID屬性賦值((IMyInterface)program).Name = "C#從入門到精通";//為派生類中的Name屬性賦值((IMyInterface)program).ShowInfo();            //調用派生類中方法顯示定義的屬性值Console.WriteLine("----------------------");   //用子類派生類直接實例化program.ID = "TM";program.Name = "C#從入門到精通";program.ShowInfo();Console.Read();}}
}//運行結果:
/*
編號     姓名
TM       C#從入門到精通
----------------------
編號     姓名
TM       C#從入門到精通*/

2.內聯表達治愈警告CA1859

?????????上述示例中,傳統的Main()方法中,先實例化派生類Program,再用派生對象實例化接口,然后用接口的屬性為派生類屬性賦值。這是.NET Framework 4.8之前的做法,其缺點是程序表達晦澀,不易讀,繼承關系不明顯。

????????在.NET 7.0、.NET 8.0下不建議這樣表達,會提示警告CA1859。VS2022.NET 8.0快速重構建議給出的意見是用內聯臨時變量的方法,直接表達繼承關系,使得程序簡潔易讀,繼承關系清晰明了。

嚴重性

代碼

說明

項目

文件

禁止顯示狀態

消息

CA1859

將變量“_Imyinterface”的類型從“_02.IMyInterface”更改為“_02.Program”,以提高性能

02

E:\C#_TM\chapter17\02\Program.cs

72

活動

(1)傳統程序書寫源碼

static void Main(string[] args)
{Program program = new();				//實例化Program類對象IMyInterface Imyinterface = program;    //使用派生類對象實例化接口ImyInterfaceImyinterface.ID = "TM";                 //為派生類中的ID屬性賦值Imyinterface.Name = "C#從入門到精通";    //為派生類中的Name屬性賦值Imyinterface.ShowInfo();				//調用派生類中方法顯示定義的屬性值Console.WriteLine("------------------");//用子類派生類直接實例化program.ID = "TM";program.Name = "C#從入門到精通";program.ShowInfo();Console.Read();
}

(2)內聯后的源碼

static void Main(string[] args){Program program = new();                         //實例化Program類對象//使用派生類對象實例化接口     	                 ((IMyInterface)program).ID = "TM";               //為派生類中的ID屬性賦值((IMyInterface)program).Name = "C#從入門到精通";  //為派生類中的Name屬性賦值((IMyInterface)program).ShowInfo();              //調用派生類中方法顯示定義的屬性值Console.WriteLine("----------------------");	  //用子類派生類直接實例化program.ID = "TM";program.Name = "C#從入門到精通";program.ShowInfo();Console.Read();}

????????內聯的表達可以隱藏(舍去)? ?,結果是一樣的,只是繼承關系不再明顯可見了。? ? ?

????????后面的例子中都會出現CA1859警告,其處理方法同此例,不再重復講述。

四、多重繼承

????????可以只繼承一個接口,接口也可以多重繼承,使用多重繼承時,要繼承的接口之間用逗號“,”分隔。

1.示例

// 繼承多個接口
namespace _03
{interface IPeople{/// <summary>/// 姓名/// </summary>string Name{get;set;}/// <summary>/// 性別/// </summary>string Sex{get;set;}}interface ITeacher : IPeople            //繼承公共接口{/// <summary>/// 教學方法/// </summary>void Teach();}interface IStudent : IPeople            //繼承公共接口{/// <summary>/// 學習方法/// </summary>void Study();}class Program : IPeople, ITeacher, IStudent//多接口繼承{string name = "";string sex = "";/// <summary>/// 姓名/// </summary>public string Name{get{return name;}set{name = value;}}/// <summary>/// 性別/// </summary>public string Sex{get{return sex;}set{sex = value;}}/// <summary>/// 教學方法/// </summary>public void Teach(){Console.WriteLine(Name + " " + Sex + " 教師");}/// <summary>/// 學習方法,學習內聯的表達/// 內聯前,用派生類對象實例化接口ITeacher/// 內聯前,用派生類對象實例化接口IStudent/// 舍去內聯的表達后效果一樣,內聯的存在使得繼承關系清晰明了/// </summary>public void Study(){Console.WriteLine(Name + " " + Sex + " 學生");}static void Main(string[] args){Program program = new();   //實例化類對象,內聯表達((ITeacher)program).Name = "TM";((ITeacher)program).Sex = "男";((ITeacher)program).Teach();((IStudent)program).Name = "C#";((IStudent)program).Sex = "男";((IStudent)program).Study();Console.WriteLine("--舍去內聯--");program.Name = "TM";program.Sex = "男";program.Teach();program.Name = "C#";program.Sex = "男";program.Study();Console.Read();}}
}//運行結果:
/*
TM 男 教師
C# 男 學生
--舍去內聯--
TM 男 教師
C# 男 學生     */

五、顯式接口成員實現

????????如果類實現兩個接口,并且這兩個接口包含具有相同簽名的成員,那么在類中實現該成員將導致兩個接口都使用該成員作為它們的實現。然而,如果兩個接口成員實現不同的功能,則可能會導致其中一個接口的實現不正確或兩個接口的實現都不正確,這時可以顯式地實現接口成員,即創建一個僅通過該接口調用并且特定于該接口的類成員。顯式接口成員實現是使用接口名稱和一個句點命名該類成員來實現的。

????????顯式接口成員實現中不能包含訪問修飾符、abstract、virtual、override或static修飾符。

????????顯式接口成員屬于接口的成員,而不是類的成員,因此,不能使用類對象直接訪問,只能通過接口對象來訪問。

? ? ? ? ?使用場合:當繼承多個接口的類中欲實現來自各自接口的同名方法賦予不同的功能時。

1.示例

// 顯式接口成員實現
namespace _04
{interface IMyInterface1{/// <summary>/// 求和方法/// </summary>int Add();}interface IMyInterface2{/// <summary>/// 求和方法/// </summary>int Add();}/// <summary>/// 顯式接口成員實現/// </summary>class MyClass : IMyInterface1, IMyInterface2    //繼承接口{/// <summary>/// 求和方法1/// </summary>int IMyInterface1.Add()					    //顯式接口成員實現{int x = 3;int y = 5;return (x + y);}/// <summary>/// 求和方法2/// </summary>int IMyInterface2.Add()					    //顯式接口成員實現{int x = 3;int y = 5;int z = 7;return (x + y + z);}}class Program{static void Main(string[] args){MyClass myclass = new();			        //實例化接口繼承類的對象IMyInterface1 imyinterface1 = myclass;		//使用接口繼承類的對象實例化接口Console.WriteLine(imyinterface1.Add());		//使用接口對象調用接口中的方法IMyInterface2 imyinterface2 = myclass;		//使用接口繼承類的對象實例化接口Console.WriteLine(imyinterface2.Add());		//使用接口對象調用接口中的方法Console.WriteLine("----內聯表達----");       //使用內聯表達,是不是更清晰易讀?Console.WriteLine(((IMyInterface1)myclass).Add());  Console.WriteLine(((IMyInterface2)myclass).Add());Console.Read();}}
}//運行結果:
/*
8
15
----內聯表達----
8
15      */

????????內聯表達,用最少的語句,實現最清晰的繼承關系表達,是不是你的最愛?

六、總結?

????????抽象類和接口都包含可以由派生類繼承的成員,它們都不能直接實例化,但可以聲明它們的變量。如果這樣做,就可以使用多態性把繼承這兩種類型的對象指定給它們的變量。

????????抽象類和接口這兩種類型用于完全不同的目的。抽象類主要用作對象系列的基類,共享某些主要特性,例如共同的目的和結構。接口則主要用于類,這些類在基礎水平上有所不同,但仍可以完成某些相同的任務。

抽象類和接口的區別主要有以下幾點: 
? 它們的派生類只能繼承一個基類,即只能直接繼承一個抽象類,但可以繼承任意多個接口。 
? 抽象類中可以定義成員的實現,但接口中不可以。 
? 抽象類中可以包含字段、構造函數、析構函數、靜態成員或常量等,接口中不可以。 
? 抽象類中的成員可以是私有的(只要它們不是抽象的)、受保護的、內部的或受保護的內部成員(受保護的內部成員只能在應用程序的代碼或派生類中訪問),但接口中的成員必須是公共的。
? 派生類必須繼承抽象類的全部。派生類可以選擇是否繼承接口。
? 抽象類使得所有派生類大同小異,繼承多個接口則使得派生類各有不同。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/164775.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/164775.shtml
英文地址,請注明出處:http://en.pswp.cn/news/164775.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

梅見們要靠“年輕化”突圍,但代理商們面對新酒飲還需冷靜

文 | 螳螂觀察&#xff08;TanglangFin&#xff09; 作者 | kinki 沉寂了三年之后&#xff0c;今年酒行業再度熱鬧了起來&#xff0c;大大小小的展會接連落地&#xff0c;各大酒企都在忙著探索新模式、處理客情、選品招商……想要將過去三年的業績追回來。 對于酒行業的代理…

MySQL數據庫面試題總結(2022最新版)

&#x1f436; 程序猿周周 ?? 短視頻小廠BUG攻城獅 &#x1f93a; 如果文章對你有幫助&#xff0c;記得關注、點贊、收藏&#xff0c;一鍵三連哦&#xff0c;你的支持將成為我最大的動力 本文是《后端面試小冊子》系列的第 1?? 篇文章&#xff0c;該系列將整理和梳理筆者作…

EasyExcel 注解fillForegroundColor

EasyExcel 注解fillForegroundColor 對應的顏色值 /** * 樣式的數據類 * * author leiyiDong **/ Data // 頭背景設置成紅色 IndexedColors.RED.getIndex() HeadStyle(fillPatternType FillPatternType.SOLID_FOREGROUND, fillForegroundColor 10) // 頭字體設置成20 Hea…

大數據Doris(二十八):Routine Load查看和修改作業

文章目錄 Routine Load查看和修改作業 一、???????查看導入作業狀態

Audition 2024 24.0.0.46(音頻剪輯)

Audition 2024是一款非常棒的音頻編輯和混合軟件&#xff0c;提供了廣泛的工具和功能&#xff0c;用于創建、編輯、混合和設計音效。這款軟件旨在加速音頻和視頻制作工作流程&#xff0c;提供具有原始音效的高質量混音。其界面構成清晰&#xff0c;操作簡便&#xff0c;適合專業…

Linux下載工具XDM下載安裝與使用

Windows上IDM多線程下載非常強大&#xff0c;即能捕捉頁面上的視頻、圖片、音頻&#xff0c;又能作為瀏覽器下載器使用&#xff0c;但是IDM無法在Linux下使用&#xff0c;除非使用wine。不過我們可以在Linux中用XDM(Xtreme Download Manager)代替IDM。 1、XDM下載 Xtreme Dow…

Java的ArrayList中關于刪除的常用操作及方法

目錄 remove(int index)方法 remove(Object o)方法 removeAll?(Collection c)方法 removeIf?(Predicate filter)方法 removeRange?(int fromIndex, int toIndex)方法 remove(int index)方法 remove(int index)是ArrayList類中用于刪除指定位置元素的方法。它接收一個整…

小程序Canvas 2D問題解決,如安卓drawImage不執行、動態高度設置、高度1365(或4096)限制等

我的最新版小程序想在繪制時使用自定義字體&#xff0c;需要將舊版canvas升級到2d新版&#xff0c;發現了許多問題&#xff0c;下面記錄一下并提供解決思路&#xff0c;僅供參考&#xff0c;歡迎提供新思路。 一、開發工具和安卓上drawImage不執行&#xff0c;繪制出來是空白&…

聊聊tomcat的connection-timeout

序 本文主要研究一下tomcat的connection-timeout ServerProperties.Tomcat org/springframework/boot/autoconfigure/web/ServerProperties.java public static class Tomcat {/*** Access log configuration.*/private final Accesslog accesslog new Accesslog();/*** Th…

github批量倉庫克隆,git clone某個用戶的所有倉庫

利用github的api工具&#xff0c; 首先拿到用戶名為kevin的所有倉庫的url&#xff1a; curl "https://api.github.com/users/kevin/repos?per_page100&&page1" | grep -w clone_url >clone.txt過濾一下&#xff1a; grep -o https://[^"]* clone…

DM8單點_閃回查詢報錯flashback version has been out of date

問題描述 誤操作后&#xff0c;閃回查詢到某一時間點提示:“[-9801]:flashback version has been out of date.” SQL> SELECT * FROM PERSON_TYPE WHEN TIMESTAMP 2023-11-23 18:51:41; SELECT * FROM PERSON_TYPE WHEN TIMESTAMP 2023-11-23 18:51:41; [-9801]:flashbac…

redis運維(十九)redis 的擴展應用 lua(一)

一 redis 的擴展應用 lua redis如何保證原子操作 說明&#xff1a;引入lua腳本,核心解決原子性問題 ① redis為什么引入lua? lua腳本本身體積小,啟動速度快 ② redis引入lua的優勢 小結&#xff1a; 類似自定義redis命令 ③ redis中如何使用lua ④ EVAL 說明&#…

性能測試的指南:測試類型、性能測試步驟、最佳實踐等!

近期公司為了節省成本搞了一波機房遷移&#xff0c;整合了一些南美部署架構。有一些上google云和有些下阿里云等大的調整。 在做機房遷移項目當中就需要思考如何進行性能測試&#xff0c;這種大的機房遷移SRE&#xff08;運維&#xff09;會針對組件會做一些單組件的性能測試&a…

【深度學習】參數優化和訓練技巧

尋找合適的學習率(learning rate) 學習率是一個非常非常重要的超參數&#xff0c;這個參數呢&#xff0c;面對不同規模、不同batch-size、不同優化方式、不同數據集&#xff0c;其最合適的值都是不確定的&#xff0c;我們無法光憑經驗來準確地確定lr的值&#xff0c;我們唯一可…

6.2.SDP協議

那今天呢&#xff1f;我們來介紹一下sdp協議&#xff0c;那實際上呢&#xff1f;sdp協議非常的簡單。我們如果拿到一個stp的文檔去看的話&#xff0c;那你要分閱里邊的所有的內容會覺得很枯燥&#xff0c;但實際上呢&#xff0c;如果我們按照這張圖所展示的結構去看stp的話。你…

Javascript每天一道算法題(十四)——合并數組區間_中等

文章目錄 1、問題2、示例3、解決方法&#xff08;0&#xff09;方法0——雙指針&#xff08;錯誤思路&#xff09;&#xff08;1&#xff09;方法1——雙指針&#xff08;正確&#xff09; 總結 1、問題 以數組 intervals 表示若干個區間的集合&#xff0c;其中單個區間為 inte…

怎么讀一個網絡的代碼

1.網絡代碼怎么來的&#xff1f; 我想要實現一個功能&#xff0c;這個功能是輸入一張圖像&#xff0c;返回一個類別結果。 所以很明確就有三個部分&#xff0c;一個是接受圖像輸入&#xff0c;一個是處理圖像得到處理結果&#xff0c;一個是對處理結果判斷生成結果。 現在想要使…

rocketmq 發送時異常:system busy 和 broker busy 解決方案

之前寫的解決方案,都是基于測試環境測試的.到生產環境之后,正常使用沒有問題,生產環境壓測時,又出現了system busy異常(簡直崩潰).最后在rocketmq群里大佬指導下,終于解決(希望是徹底解決). 下面直接給出結果: 目前通過生產環境各種參數修改測試得出: broker busy異常: 可通…

Using PeopleCode in Application Engine Programs在應用引擎程序中使用PeopleCode

This section provides an overview of PeopleCode and Application Engine programs and discusses how to: 本節概述了PeopleCode和應用程序引擎程序&#xff0c;并討論了如何: Decide when to use PeopleCode.決定何時使用PeopleCode。Consider the program environment.考…

Java之《ATM自動取款機》(面向對象)

《JAVA編程基礎》項目說明 一、項目名稱&#xff1a; 基于JAVA控制臺版本銀行自動取款機 項目要求&#xff1a; 實現銀行自動取款機的以下基本操作功能&#xff1a;讀卡、取款、查詢。&#xff08;自動取款機中轉賬、修改密碼不作要求&#xff09; 具體要求&#xff1a; 讀卡…