C# 基礎知識系列- 4 面向對象

来源:https://www.cnblogs.com/c7jie/archive/2020/03/29/12593422.html
-Advertisement-
Play Games

面向對象 面向對象是一個抽象的概念,其本質就是對事物以抽象的方式建立對應的模型。 簡單來講,比如我有一隻鋼筆,那麼我就可以通過分析,可以得到 這隻鋼筆的材第是塑料,品牌是個雜牌 ,裡面裝的墨是黑色的,可以用。這時候就能建立一個鋼筆的模型,它在這裡應該有這些屬性: 圖是一個不正確的UML類圖,但是可以 ...


面向對象

面向對象是一個抽象的概念,其本質就是對事物以抽象的方式建立對應的模型。
簡單來講,比如我有一隻鋼筆,那麼我就可以通過分析,可以得到 這隻鋼筆的材第是塑料,品牌是個雜牌 ,裡面裝的墨是黑色的,可以用。這時候就能建立一個鋼筆的模型,它在這裡應該有這些屬性:

file

圖是一個不正確的UML類圖,但是可以簡單的概述一下我們抽象的結果。這個圖就描述了一個我們抽象出來的鋼筆類應該有哪些特性,而我手裡的那隻鋼筆就可以看做是鋼筆類的一個實例。
簡單來講,面向對象編程就是針對一個事件或者說一個過程,找到這個過程中參與的所有人、事務或者相對獨立的個體,按照他們在這個過程中表現,提取出他們的特性,描述他們的行為,然後按照類別不同再抽象出類來。
所以,類是事物的概念抽象,事物是類的特殊實例。

創建一個類

上面簡單的介紹了面向對象的概念,現在先創建一個C#類,然後介紹一下這個類需要註意的地方:

public class Person
{
	private static int count;

	public static int Count
	{
		get { return count; }
		set { count = value; }
	}

	private string name;

	public string Name
	{
		get { return name; }
		set { name = value; }
	}
	public Person()
	{
		Name = "";
		Count = Count + 1;
	}

	public Person(string name)
	{
		this.Name = name;
	}

	public void SayHello()
	{
	}
}

其中:
private string name;private static int count;這兩個在C#中稱為Field,也就是欄位的意思;
public static int Countpublic string Name 這兩個在C#中稱為Property,也就是屬性的意思。
當然,不是說一個是private就叫欄位,另一個是public就稱之為屬性,而是因為屬性有getset來控制訪問和賦值的行為。

public Person()public Person(string name)是構造方法,所謂的構造方法就是初始化一個實例的方法,調用形式如下:
Person p = new Person() 通過new關鍵字+類名+對應的參數列表即可。構造方法沒有返回類型,方法名必須是類名,可以有任意個參數。

面向對象的三大特性

面向對象的三大特性是封裝、繼承、多態。我把它們稱為面向對象面試三巨頭,因為一旦面試,如果有面向對象的問題絕對會問到這三個特性。這裡先簡單介紹一下三大特性,

  • 封裝:對象的方法實現對外是隱藏的,就像我們在不拆開鋼筆之前很難知道鋼筆的墨水是怎麼流動然後寫出字的;
  • 繼承:子類天然擁有父類的屬性和方法,假如我們還有一隻特種鋼筆,那麼我們可以把這隻特種鋼筆抽象出的類認為是鋼筆的子類,這隻特種鋼筆跟鋼筆一樣,可以用來做鋼筆能做的事,雖然有時候不好用;
  • 多態:簡單來講就是多種狀態,對於面向對象來說,就是方法重寫和方法重載。比如說,我們去找領導簽字,領導在忙讓我們把文件放那邊,過一會領導派人送過來簽好字的文件。如果領導有多只鋼筆,那麼領導用哪只筆、在什麼時候、用什麼姿勢對於我們來說就是不確定的狀態,這就是多態的一種。

訪問控制符

在將三大特性之前,先介紹一下 C#的訪問控制。C#常用的訪問控制分為四種:

  • private: 限定只有同屬於一個類的成員才可以訪問,如果限定一個類是私有類,那麼這個類必須是內部類
  • protected: 限定當前類的成員、子類可以訪問,不能用來限定外部類,同private一樣,如果限定類是受保護類,這個類必須是內部類
  • internal(default):預設訪問許可權,對於類和方法來說,限定同一個DLL可以訪問,其他DLL不能訪問。區別是類的 internal 關鍵字可以省略,方法如果省略訪問許可權符,則預設是protected
  • public:公開,所有能引用類的地方都能訪問類里的public對象,這是最開放的許可權。

C#還有更多的訪問控制,不過常用的只有這四種,更多的可以參照【官方文檔】。

封裝

封裝簡單來講就是調用方不知道被調用方的具體實現以及內部機制,就像我們看別人只能看到外表缺看不到器官的運作(當然除非你是醫生)。
那麼封裝有什麼好處呢:

  • 對外隱藏實現,防止外部篡改引發安全問題
  • 減少不必要的關聯,被調用方需要調用方提供參數,但除此之外調用方只需要靜待被調用方返回結果就行
  • 打包一系列的操作,防止中間發生變故

比如說一個鐘錶,給我們一堆零件,在沒有拼接、安裝好之前也就是封裝好,這個鐘錶是不能正常使用的。只有我們按照一定邏輯,將零件安裝好之後(封裝),再裝上電池或上發條(調用) 鐘錶才會轉起來。
簡單的用代碼介紹一下:

class Program
{
	static void Main(string[] args)
	{
		Person p = new Person();
		p.SayHello();
	}
}


public class Person
{
	private static int count;

	public static int Count
	{
		get { return count; }
		set { count = value; }
	}

	private string name;

	public string Name
	{
		get { return name; }
		set { name = value; }
	}

	public Person()
	{
		Name = "小明";
		Count = Count + 1;
	}

	public Person(string name)
	{
	}

	public void SayHello()
	{
		Console.WriteLine("你好,我叫"+Name);
	}
}

簡單看一下,對於Program類來講,Person的SayHello是怎麼實現的完全不知情。這就是封裝的意義。

繼承

C#的繼承是單繼承,也就是說一個類只有一個父類,如果不指明父類,那麼它的父類就是object。換句話說,object是C#繼承體系裡的根,也就是所有類的祖先類。
C#的繼承用 表示,即 class B: A表示B繼承A。

public class A
{
	public virtual void Say()
	{
	}
	public void Look()
	{
	}
}
public class B : A
{
	public override void Say()
	{
	}
}

上述代碼建立了一個簡單的繼承體系。那麼問題來了,繼承有什麼用呢?簡單來講,對於A和B在Say方法有不同的實現,對於調用方來講,它們的表現應當是一致的。換句話說,就是所有用到A的地方,都能用B來代替,這不會出現任何問題。
繼承可以簡化很多行為(方法)一致的寫法。如示例所述,B類在Look上與其父類A類有著一致的行為和表現,那麼B就可以省略了Look的定義和描述,沿用父類的方法。通過繼承可以很快地建立一套豐富的方法體系。子類每一次對父類的方法補充都會在子類里體現出來。所以繼承可以說是面向對象的核心體系。

有個關鍵字需要額外的講解一下saled,如果看到一個類有這個標記,那麼需要註意了,這個類是不可被繼承的類。

多態

多態的實現就是通過類的繼承和方法的重載實現的。類的繼承主要通過重寫父類方法或者覆蓋父類方法來實現的,主要關鍵字就是 virtualoverridenew
具體的介紹是:

  • virtual 關鍵字聲明函數為虛函數,意思就是子類可能會重寫該方法
  • override 用在子類,用來聲明該方法是重寫父類的方法
  • new 跟實例化對象的new不同,這個放在方法前的意思是該方法會隱藏父類方法的實現。
public class A
{
	public virtual void Say()
	{
		//省略實現
	}

	public void SetName()
	{
		//省略實現
	}
}

public sealed class B:A
{
	public override void Say() //重寫父類方法
	{
		//省略實現
	}
	public new void SetName() // 覆蓋父類方法
	{
		//省略實現
	}
}

重寫和覆蓋的區別在哪呢:

A a = new B();
a.Say();// 調用的是 B中 Say方法
a.SetName();//調用的是A的SetName 方法
B b = (B)a;
b.SetName();//調用的是B的SetName 方法
b.Say();// 調用的是 B中 Say方法

類和介面

C#中類和介面的聲明方式不同,類用的關鍵字是class,介面用的是interface。而且類是繼承,介面是實現,一個類只能有一個父類,介面可以有多個。
介面需要註意的地方就死,介面所有的方法都是public的,因為介面就是用來定義規範的,所以一旦它的方法訪問控制不是public的話,就沒什麼意義。

public class Demo1
{
}
public interface IDemo
{
	string Method();
}
public class Demo3 : Demo1, IDemo
{
	public string Method()
	{
		return "test";
	}
	string IDemo.Method()
	{
		return "test2";
	}
}

介面的實現和類的繼承都是 : ,先繼承後實現。

觀察示例代碼,發現Demo3有兩個方法public string Method()string IDemo.Method() 。這兩個都是實現介面的方法,不同的地方是它們的使用:

IDemo idemo = new Demo3();
idemo.Method();//返回 test2
Demo3 demo = new Demo3();
demo.Method();// 返回 test

使用介面名.方法名實現方法的時候,這個方法對於實現類構造的對象來說是不可訪問的。當然兩種方法可以共存,但是不會兩個方法都被認為是介面的實現方法。介面優先使用介面名.方法名 作為實現方法,如果沒找到則認為同名同參的方法為實現方法。

Object 類 常用方法

object 作為基類定義了四個基本方法,這四個方法是所有子類都有的方法,也是一個核心方法:

  • Equals(object obj) 這是一個很重要的方法,它是 C#中判斷兩個對象是否相等的依據,也就是 == 運算符的結果,如果不重寫這個方法的話,返回的結果是兩個對象是否指向同一個引用地址。
  • GetType() 返回這個對象的類型,這是反射機制中重要的一塊
  • ToString() 返回字元串,獲得一個對象的文字描述,預設返回的是對象的地址描述信息,這個方法建議重寫
  • GetHashCode() 返回 Hash值,某些集合和程式機制會以HashCode作為元素的相等性判斷依據,所以在重寫 Equals 之後也要重寫 這個方法,並保證兩個方法對於相同的對象做相等性結果判定是應該表現一致。

擴展方法

C# 有一個很重要的機制就是擴展方法,擴展方法表現出的跟類自有的方法調用結果一致。
具體寫法如下:

public static class Methods
{
	public static string Test(this Person person)
	{
			return "test";
	}
}

需要註意的是,擴展方法所在類必須是靜態類,擴展方法必須是靜態方法,擴展方法第一個參數就是擴展的元素對象,用this標記。

不過很多人對擴展方法褒貶不一,有人認為擴展方法極易破壞繼承鏈,導致一些不必要的麻煩;有人認為擴展方法就跟工具方法一樣,而且可以優化調用方式,統一使用風格。

不過我看來,擴展方法利大於弊。因為擴展方法可以在不修改原有類的基礎上增加功能,同時它也是一個工具類,跟普通的方法是一致的。

更多內容煩請關註我的博客

file


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

-Advertisement-
Play Games
更多相關文章
  • Druid簡介 Druid是阿裡開源的資料庫連接池,作為後起之秀,性能比dbcp、c3p0更高,使用也越來越廣泛。 druid的優點 高性能。性能比dbcp、c3p0高很多。 只要是jdbc支持的資料庫,druid都支持,對資料庫的支持性好。並且Druid針對oracle、mysql做了特別優化。 ...
  • public static <T> T map2Object(Map<String, Object> map, Class<T> clazz) { SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); if (map ...
  • A - Coffee 題意:給你一個字元串,要你判斷是否滿足一下條件,全部滿足則輸出“Yes”,否則輸出“No”。 (1)字元串的第3個字母等於字元串的第4個字母 (2)字元串的第5個字母等於字元串的第6個字母 (3)字元串的長度為6,且全部為小寫字母 題解:簽到題,易解 代碼: #include< ...
  • 一、背景 一方面,有時必須從幾個類中派生出一個子類,繼承它們所有的屬性和方法。但是,Java不支持多重繼承。有了介面,就可以得到多重繼承的效果。 另一方面,有時必須從幾個類中抽取出一些共同的行為特征,而它們之間又沒有is-a的關係,僅僅是具有相同的行為特征而已。 二、圖示 三、介面的使用 1.介面: ...
  • 隨著繼承層次中一個個新子類的定義,類變得越來越具體,而父類則更一般,更通用。類的設計應該保證父類和子類能夠共用特征。有時將一個父類設計得非常抽象,以至於它沒有具體的實例,這樣的類叫做抽象類。 舉例: public class test { public static void main(String ...
  • 發現按照教程操作破解Eplan,破解一直不成功。主要原因是MultiKey64在win10上運行不成功。可以通過設備管理看到是否有下圖的驅動 需要關閉win10的簽名認證,這個鏈接就是關閉的方法https://jingyan.baidu.com/article/624e74594dbc8d34e8b ...
  • 你需要瞭解的 HTTP Status Code Intro 現在前後端分離的開發模式越來越流行,後端負責開發對應的 API,前端只需要 關註前端頁面的數據展示和前端邏輯即可。 對於前後端分離這種開發模式,我個人還是比較喜歡的,因為這樣可以讓更專業的人做更專業的事情,後端專註於做 API 的開發設計, ...
  • 在ASP.NET MVC中有四種過濾器類型 Action 1、在ASP.NET MVC項目中,新建文件夾Filter,然後新建類MyCustormFilter,繼承自ActionFilterAttribute類,我們來看下ActionFilterAttribute類有如下四個方法,從命名我應該就可以 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...