.NET Core CSharp初級篇 1-5 介面、列舉、抽象

WarrenRyan發表於2019-07-21

.NET Core CSharp初級篇 1-5

全文目錄

(部落格園).NET Core Guide

(Github).NET Core Guide

本節內容類的介面、列舉、抽象

簡介

問題

  • 如果你需要表示星期或者是某些狀態,使用字串或者數字是否不直觀?
  • 你是否發現,無論何種電腦,它的USB口的設計都是遵循一定規範的?

列舉

列舉(enum)是一個非常好用的一個特殊值型別,他可以讓你指定一系列字元常量(通常從0開始)。它的定義和使用如下:

public enum Week
{
    Monday,
    ...//此處省略
    Sunday = 6//可賦值
}
bool flag = (6 == (int)Week.Sunday)

不過你也可以指定其他的型別作為列舉的值,例如:

public enum Week:byte
{
    Monday,
    ...
    Sunday= 6
}

列舉與其他型別的轉換使用強制型別轉換即可,例如:(int)Week.Sunday,不過特別的,0不需要強制轉換就可以和列舉進行比較。

Flag Enum

這是一個有趣的列舉,它支援你對列舉按位進行運算,使用flag enum需要在列舉名上面指定一個Attribute,也就是[Flags],通常來說,我們會使用2的冪作為列舉值,因為按位運算本質是2進位制的運算。

具體例項如下

[Flags]
public enum Status
{
    Success = 1,
    NotFound = 2,
    Fail = 4
}
//支援按位運算,運算步驟我們在之前已經有過詳細的講解
Status.Success | Status.NotFound

預設的,如果你輸入了一個不合理的列舉值(也就是沒定義),編譯器會預設直接輸出該數字,不過如果你使用了按位運算的列舉,那麼他會將你輸入的數字轉換成二進位制與每一個列舉值進行&運算,得出的結果會與列舉值進行比較,如果找到了就會輸出。

例如以上例的Status:

Console.WriteLine((Status)7);
//輸出是三個都輸出
//7 = 0111,
//1 = 0001,
//2 = 0010
//4 = 0011

介面

介面這個東西,新手非常容易被誤導,例如在WebApi開發中,你的前端朋友讓你把介面給他,這個時候,他需要的東西在後端的口中叫做API,
當你的後端朋友說,你寫一個介面,我們使用依賴注入進行統一管理實現了介面的類,這個時候,他需要的是一個約定,也是我們這裡講的介面(interface)。

介面是C#物件導向中實現多型的重要語法。介面的定義可以理解為是一種約定的規範。例如電腦的USB-A介面,全世界的廠商都是統一規範生產,如果大家不按著約定生產,後果會是什麼?

在C#中,介面也一樣起到了這個作用,但是還有一些更為廣泛的應用。

介面的定義使用interface關鍵字,預設的,所有介面的成員的訪問許可權都是public,因為規範是需要公佈給所有人看,如果定義了訪問許可權就沒有實際的意義了
,並且介面中所有的函式都不存在函式體。總的來說就是,介面是一個提供類的規格的東西,卻不提供實現。

介面的例子

//定義一個介面
public inteface IHuman
{
    void Eat();
    bool Alive();
}
//介面的實現,必須實現每一個介面中的函式並保持返回型別、函式簽名,函式引數一致
public class Human:IHuman
{
    void Eat()
    {

    }
    bool Alive()
    {
        return default<bool>();
    }
}

介面的實現會和我們後面講到的繼承非常相似,在這裡,你只需要記住介面支援一個類實現多個介面,但只能繼承一個類即可。

介面衝突

因為支援一個類實現多個介面,那麼很有可能會造成A介面中擁有和B介面中完全一致的函式,這個時候我們就需要使用顯式實現介面進行處理。

當你需要呼叫不同介面的同簽名方法時,使用介面進行強制轉換即可。

例如:

interface IApple
{
    void Wash();
}
interface IFruit
{
    void Wash();
}
class test : IApple,IFruit
{
    void IApple.Wash()=>{};
    void IFruit.Wash()=>{};
}
test t= new test();
((IApple)t).Wash();
((IFruit)t).Wash();

這樣就可以避免介面在命名上的衝突。

並且介面如果你隱式的實現,所有介面函式預設都是sealed的。
如果存在一個多繼承的問題,這個可能目前講起來為之過早,我就順口提一下,例如,人類繼承與動物類,動物繼承於生物介面,
那麼對於人類,是隱式的繼承了生物介面,但是對於人類和動物,進食的方式有很大區別,那麼我們就應該重寫進食這個方法。
我們就要把基類(父類)中的介面函式標記為virtual或者abstract,然後在子類中使用override進行重寫。

這就已經說的太遠了,後面我們會進行深入的刨析。

抽象

抽象可以有抽象欄位、抽象類、抽象委託、抽象函式等等。我們就以其中常用的抽象函式和抽象類做一個解析。

抽象和介面非常相似,抽象類不能被例項化,抽象方法沒有方法體,都是依賴子類(被繼承類)進行操作。

抽象函式

這個就和介面幾乎一模一樣,也沒有太多講的必要,如果你宣告瞭一個函式是抽象函式,那麼它不存在方法體,你需要透過子類去重寫(override)實現。

在實際應用中,子類僅能重寫父類中的虛方法或者抽象方法,當不需要使用父類中方法的內容時,將其定義成抽象方法,否則將方法定義成虛方法。

抽象類

"一個包含一個或多個純虛擬函式的類叫抽象類,抽象類不能被例項化,進一步
一個抽象類只能透過介面和作為其它類的基類使用."

一個抽象類可以包含抽象和非抽象方法,當一個類繼承於抽象類,那麼這個派生類必須實現所有的
的基類抽象方法。

但是透過宣告派生類也為抽象,我們可以避免所有或特定的虛方法的實現,
這就是抽象類的部分實現。

看起來很高深?事實上抽象類就是一個提供了有部分沒有方法體的函式和有具體實現的函式的集合。它相比於介面毫無實現而言,抽象類可以提供非抽象的方法,也就是說,抽象類中可以含有有實現方法的函式。

看這個例子

public abstract class A
{
    public void GetSomeThing()
    {
        //todo
    }
    public abstract void SetSomeThing();
}
public class B:A
{
    //實現抽象方法
    public override void SetSomeThing()
    {
        //呼叫非抽象方法
        base.GetSomeThing();
    }

}

這裡面涉及到了base關鍵字以及":"繼承符號,在後面的繼承、多型的課程有會有更加深入的介紹。






作  者:WarrenRyan
出  處:https://www.cnblogs.com/WarrenRyan/
關於作者:熱愛數學、熱愛機器學習,喜歡彈鋼琴的不知名小菜雞。
版權宣告:本文版權歸作者所有,歡迎轉載,但未經作者同意必須保留此段宣告,且在文章頁面明顯位置給出原文連結。若需商用,則必須聯絡作者獲得授權。
特此宣告:所有評論和私信都會在第一時間回覆。也歡迎園子的大大們指正錯誤,共同進步。或者直接私信
聲援博主:如果您覺得文章對您有幫助,可以點選文章右下角推薦一下。您的鼓勵是作者堅持原創和持續寫作的最大動力!


博主一些其他平臺:
微信公眾號:寤言不寐
BiBili——小陳的學習記錄
Github——StevenEco
BiBili——記錄學習的小陳(計算機考研紀實)
掘金——小陳的學習記錄
知乎——小陳的學習記錄

聯絡方式:

電子郵件:cxtionch@live.com

社交媒體聯絡二維碼:

.NET Core CSharp初級篇 1-5 介面、列舉、抽象

相關文章