程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> .NET網頁編程 >> C# >> C#入門知識 >> C#中的繼承與多態還有接口

C#中的繼承與多態還有接口

編輯:C#入門知識

C#中的繼承與多態還有接口


簡單繼承

最簡單的三個類

 

public class Animal {
    public Animal()
    {
        Debug.Log("Construct Animal!");
    }
}

public class Mammal : Animal {
    public Mammal()
    {
        Debug.Log("Construct Mamal!");
    }
}

public class Sheep : Mammal
{
    public Sheep()
    {
        Debug.Log("Construct Sheep!");
    }
}

在main裡面

 

 

Sheep sheep = new Sheep();

\

 

 

子類的構造函數會依次執行基類的構造函數,沒有異議。

 

需要注意的是,沒有特別聲明,子類都會自動去找父類中沒有參數的構造函數,如果基類中沒有,則需要在子類的構造函數中調用,比如:

 

public class Animal{

    int age;
    public Animal(int _age)
    {
        age = _age;
        Debug.Log("Construct Animal!");
    }
}

則子類的構造函數就要這樣寫

 

 

    public Mammal():base(0)
    {
        Debug.Log("Construct Mamal!");
    }


 

 

在基類Animal中添加函數

 

    public void Eat()
    {
        Debug.Log("Animal Eat!");
    }


 

下面談一下方法的覆蓋

在子類Sheep中覆蓋定義Eat方法

 

    public new void Eat()
    {
        Debug.Log("Sheep Eat!");
    }

這裡的new關鍵字表示隱藏基類中的方法,官方解釋如下:

 

new 關鍵字可以顯式隱藏從基類繼承的成員。隱藏繼承的成員時,該成員的派生版本將替換基類版本。雖然可以不使用 new 修飾符來隱藏成員,但將收到編譯器警告。如果使用 new 來顯式隱藏成員,將禁止此警告。

測試代碼:

 

        Sheep sheep = new Sheep();
        Animal animal = new Sheep();

        sheep.Eat();
        animal.Eat();

結果是這樣的

 

\

 

沒有發生多態行為,聲明的基類對象,執行的就是基類方法,聲明的子類對象,執行的就是子類方法。

在子類的函數中,都有一個base變量,可以認為是一個對基類的引用,通過base就可以調用基類的方法。

 

多態

多態就是多態就是父類引用指向子類對象,調用方法時會調用子類的實現,而不是父類的實現,這叫多態。

基類Animal中定義函數

 

    public virtual void Birth()
    {
        Debug.Log("Animal Birth!");
    }


 

Sheep中overrride一下

 

    public override void Birth()
    {
        Debug.Log("Sheep Birth!");
    }

測試代碼

 

 

        Sheep sheep = new Sheep();
        Animal animal = new Sheep();
        animal.Birth();

執行結果

 

\

 

有下面兩個需要注意的點

1.子類調用父類的方法

當然是直接用base了。

2.繼承鏈中的虛方法

無論在虛擬成員和最初聲明虛擬成員的類之間已聲明了多少個類,虛擬成員永遠都是虛擬的。如果類 A 聲明了一個虛擬成員,類 B 從 A 派生,類 C 從類 B 派生,則類 C 繼承該虛擬成員,並且可以選擇重寫它,而不管類 B 是否為該成員聲明了重寫。

 

Sealed關鍵字的用法

Sealed關鍵字用來阻止派生類重寫虛擬成員。還是舉例說明。

基類Animal中定義方法

 

public virtual void Move()
{
    Debug.Log("Animal Move!");
}

Mammal中sealed override這個函數

 

 

    public sealed override void Move()
    {
        Debug.Log("Mammal Move!");
    }

這時候在Sheep中已經無法overide這個函數了,因為在Sheep看來,基類的Move是被當作一個普通函數來處理的,如果要定義自己的Move函數,就要加new,像這樣

 

 

    public new void Move()
    {
        Debug.Log("Sheep Move!");
    }


 

寫點代碼來測試多態性

 

        Animal animal = new Animal(1);
        Animal animal1 = new Mammal(1);
        Animal animal2 = new Sheep();
        Sheep sheep = new Sheep();

        animal.Move();
        animal1.Move();
        animal2.Move();
        sheep.Move();


運行結果

 

\

 

第一個無話可說,直接執行了Animal的move函數

第二個,正常的多態

第三個有點意思,多態到Mammal就打住了

第四個就是普通的執行Sheep類的成員函數。

 

abstract關鍵字的使用

官方解釋:abstract 修飾符指示所修飾的內容缺少實現或未完全實現。abstract 修飾符可用於類、方法、屬性、索引器和事件。在類聲明中使用 abstract 修飾符以指示某個類只能是其他類的基類。標記為抽象或包含在抽象類中的成員必須通過從抽象類派生的類來實現。

接地氣的解釋:abstract類用於搭建子類的框架,子類必須實現其中的abstract方法,使用的也是override關鍵字。

abstract方法和vitual方法的區別

abstract方法沒有函數體,子類一定要有對應方法的實現。

vitual方法子類可以選擇實現也可以選擇不實現。

兩個都可以用於實現多態。

 

抽象類不能實例化。抽象類的用途是提供一個可供多個派生類共享的通用基類定義。例如,類庫可以定義一個抽象類,將其用作多個類庫函數的參數,並要求使用該庫的程序員通過創建派生類來提供自己的類實現。

 

接口

接口包含類或結構可以實現的一組相關功能的定義。
例如,使用接口可以在類中包括來自多個源的行為。 由於C#語言不支持多重繼承,所以該功能很重要。 此外,如果要模擬結構的繼承,也必須使用接口,因為它們無法實際從另一個結構或類繼承。

 

定義一個簡單的接口,只有接口函數的定義,沒有實現。

 

public interface ISay {

    void SayHello();
    void SayFuck();
}

 

 

Sheep繼承ISay接口
public class Sheep : Mammal, ISay

則Sheep類中必須要有ISay中定義的接口的定義

 

    public void SayHello()
    {
        Debug.Log("ISay Hello");
    }

    public void SayFuck()
    {
        Debug.Log("ISay SayFuck");
    }

測試代碼

 

 

        Sheep sheep = new Sheep();
        sheep.SayHello();
        sheep.SayFuck();

執行結果

 

\

 

接口有下面幾個屬性

接口類似於抽象基類。實現接口的任何類或結構都必須實現其所有成員。
接口無法直接進行實例化。其成員由實現接口的任何類或結構來實現。
接口可以包含事件、索引器、方法和屬性。
接口不包含方法的實現。
一個類或結構可以實現多個接口。一個類可以繼承一個基類,還可實現一個或多個接口。

 

參考

MSDN

 

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved