动态

详情 返回 返回

C# 繼承、多態性、抽象和接口詳解:從入門到精通 - 动态 详情

C# 繼承

C# 中,可以將字段和方法從一個類繼承到另一個類。我們將“繼承概念”分為兩類:

  • 派生類(子類) - 從另一個類繼承的類
  • 基類(父類) - 被繼承的類

要從一個類繼承,使用 : 符號。

在以下示例中,Car 類(子類)繼承了 Vehicle 類(父類)的字段和方法:

示例

class Vehicle  // 基類(父類)
{
  public string brand = "Ford";  // 車輛字段
  public void honk()             // 車輛方法
  {
    Console.WriteLine("Tuut, tuut!");
  }
}

class Car : Vehicle  // 派生類(子類)
{
  public string modelName = "Mustang";  // 汽車字段
}

class Program
{
  static void Main(string[] args)
  {
    // 創建一個 myCar 對象
    Car myCar = new Car();

    // 在 myCar 對象上調用 honk() 方法(來自 Vehicle 類)
    myCar.honk();

    // 顯示 brand 字段(來自 Vehicle 類)的值和 modelName 字段(來自 Car 類)的值
    Console.WriteLine(myCar.brand + " " + myCar.modelName);
  }
}

輸出

Tuut, tuut!
Ford Mustang

為什麼以及何時使用“繼承”?

  • 它對於代碼重用非常有用:在創建新類時重用現有類的字段和方法

sealed 關鍵字

如果您不希望其他類從一個類繼承,請使用 sealed 關鍵字:

sealed class Vehicle 
{
  ...
}

class Car : Vehicle 
{
  ...
}

如果您嘗試訪問一個 sealed 類,C# 會生成一個錯誤:

'Car': cannot derive from sealed type 'Vehicle'

多態性和方法覆蓋

多態性意味着 "多種形態",它發生在我們有許多通過繼承相互關聯的類時。繼承允許我們從另一個類繼承字段和方法。多態性使用這些方法來執行不同的任務。這允許我們以不同的方式執行單個動作。

例如,考慮一個名為 Animal 的基類,它有一個名為 animalSound() 的方法。Animal 的派生類可以是 PigsCatsDogsBirds,它們也有自己的 animalSound() 方法實現(豬會叫,貓會喵喵叫等)。

示例:

class Animal  // 基類(父類)
{
  public virtual void animalSound() 
  {
    Console.WriteLine("動物發出聲音");
  }
}

class Pig : Animal  // 派生類(子類)
{
  public override void animalSound() 
  {
    Console.WriteLine("豬説:wee wee");
  }
}

class Dog : Animal  // 派生類(子類)
{
  public override void animalSound() 
  {
    Console.WriteLine("狗説:bow wow");
  }
}

現在我們可以創建 PigDog 對象,並在它們兩個上調用 animalSound() 方法:

示例:

class Program 
{
  static void Main(string[] args) 
  {
    Animal myAnimal = new Animal();  // 創建一個 Animal 對象
    Animal myPig = new Pig();  // 創建一個 Pig 對象
    Animal myDog = new Dog();  // 創建一個 Dog 對象

    myAnimal.animalSound();
    myPig.animalSound();
    myDog.animalSound();
  }
}

輸出將為:

動物發出聲音
豬説:wee wee
狗説

C# 抽象

抽象類和方法

數據抽象是隱藏某些細節並僅向用户顯示基本信息的過程。

抽象可以通過抽象類或接口來實現。

abstract 關鍵字用於類和方法:

  • 抽象類:是一個受限制的類,不能用於創建對象(要訪問它,必須從另一個類繼承)。
  • 抽象方法:只能在抽象類中使用,並且沒有方法體。方法體由派生類(繼承自)提供。

抽象類可以同時包含抽象方法和常規方法:

abstract class Animal {
  public abstract void animalSound();
  public void sleep() {
    Console.WriteLine("Zzz");
  }
}

從上面的例子可以看出,無法創建 Animal 類的對象:

Animal myObj = new Animal(); // 將生成錯誤(無法創建抽象類或接口“Animal”的實例)

要訪問抽象類,必須從另一個類繼承它

例子

// 抽象類
abstract class Animal {
  // 抽象方法(沒有方法體)
  public abstract void animalSound();
  // 常規方法
  public void sleep() {
    Console.WriteLine("Zzz");
  }
}

// 派生類(繼承自 Animal)
class Pig : Animal {
  public override void animalSound() {
    // animalSound() 的方法體在這裏提供
    Console.WriteLine("The pig says: wee wee");
  }
}

class Program {
  static void Main(string[] args) {
    Pig myPig = new Pig(); // 創建一個 Pig 對象
    myPig.animalSound(); // 調用抽象方法
    myPig.sleep(); // 調用常規方法
  }
}

為什麼以及何時使用抽象類和方法?

  • 為了實現安全性——隱藏某些細節,只顯示對象的重要細節。
  • 注意:抽象也可以通過接口實現

C# Interface

接口是在 C# 中實現抽象的另一種方式。

接口是一個完全“抽象類”,它只能包含抽象方法和屬性(沒有實際的方法體):

// 接口
interface Animal 
{
  void animalSound(); // 接口方法(沒有方法體)
  void run(); // 接口方法(沒有方法體)
}

通常,以字母 "I" 開頭是一種良好的實踐,因為這樣可以更容易地記住它是一個接口而不是一個類。

默認情況下,接口的成員是抽象和公共的。

注意:接口可以包含屬性和方法,但不能包含字段。

要訪問接口方法,接口必須由另一個類“實現”(有點像繼承)。要實現接口,請使用冒號符號(與繼承一樣)。接口方法的實際方法體由“實現”類提供。請注意,在實現接口時,不必使用 override 關鍵字:

// 接口
interface IAnimal 
{
  void animalSound(); // 接口方法(沒有方法體)
}

// Pig “實現”了 IAnimal 接口
class Pig : IAnimal 
{
  public void animalSound() 
  {
    // animalSound() 的方法體在這裏提供
    Console.WriteLine("豬説:嗚嗚");
  }
}

class Program 
{
  static void Main(string[] args) 
  {
    Pig myPig = new Pig();  // 創建一個 Pig 對象
    myPig.animalSound();
  }
} 

接口的注意事項:

  • 與抽象類一樣,接口不能用於創建對象(在上面的示例中,在 Program 類中不能創建“IAnimal”對象)。
  • 接口方法沒有方法體 - 方法體由“實現”類提供。
  • 在實現接口時,必須覆蓋其所有方法。
  • 接口可以包含屬性和方法,但不能包含字段/變量。
  • 接口成員默認是抽象和公共的。
  • 接口不能包含構造函數(因為它不能用於創建對象)。

為什麼以及何時使用接口?
1) 為了實現安全性 - 隱藏對象的某些細節,僅顯示重要的細節(接口)。
2) C# 不支持“多繼承”(一個類只能繼承一個基類)。但是,可以通過接口實現多繼承,因為類可以實現多個接口。注意:要實現多個接口,請使用逗號分隔它們(見下面的示例)。

為什麼以及何時使用抽象類和方法?

  • 為了實現安全性——隱藏某些細節,只顯示對象的重要細節。
  • 注意:抽象也可以通過接口實現

C# 接口

接口是在 C# 中實現抽象的另一種方式。

接口是一個完全“抽象類”,它只能包含抽象方法和屬性(沒有實際的方法體):

// 接口
interface Animal 
{
  void animalSound(); // 接口方法(沒有方法體)
  void run(); // 接口方法(沒有方法體)
}

通常,以字母 "I" 開頭是一種良好的實踐,因為這樣可以更容易地記住它是一個接口而不是一個類。

默認情況下,接口的成員是抽象和公共的。

注意:接口可以包含屬性和方法,但不能包含字段。

要訪問接口方法,接口必須由另一個類“實現”(有點像繼承)。要實現接口,請使用冒號符號(與繼承一樣)。接口方法的實際方法體由“實現”類提供。請注意,在實現接口時,不必使用 override 關鍵字:

// 接口
interface IAnimal 
{
  void animalSound(); // 接口方法(沒有方法體)
}

// Pig “實現”了 IAnimal 接口
class Pig : IAnimal 
{
  public void animalSound() 
  {
    // animalSound() 的方法體在這裏提供
    Console.WriteLine("豬説:嗚嗚");
  }
}

class Program 
{
  static void Main(string[] args) 
  {
    Pig myPig = new Pig();  // 創建一個 Pig 對象
    myPig.animalSound();
  }
} 

接口的注意事項:

  • 與抽象類一樣,接口不能用於創建對象(在上面的示例中,在 Program 類中不能創建IAnimal對象)。
  • 接口方法沒有方法體 - 方法體由“實現”類提供。
  • 在實現接口時,必須覆蓋其所有方法。
  • 接口可以包含屬性和方法。

C# 多接口

要實現多個接口,請使用逗號分隔它們:

interface IFirstInterface 
{
  void myMethod(); // 接口方法
}

interface ISecondInterface 
{
  void myOtherMethod(); // 接口方法
}

// 實現多個接口
class DemoClass : IFirstInterface, ISecondInterface 
{
  public void myMethod() 
  {
    Console.WriteLine("一些文本..");
  }
  public void myOtherMethod() 
  {
    Console.WriteLine("一些其他文本...");
  }
}

class Program 
{
  static void Main(string[] args) 
  {
    DemoClass myObj = new DemoClass();
    myObj.myMethod();
    myObj.myOtherMethod();
  }
}

最後

為了方便其他設備和平台的小夥伴觀看往期文章:

微信公眾號搜索:Let us Coding,關注後即可獲取最新文章推送

看完如果覺得有幫助,歡迎 點贊、收藏、關注

user avatar pulsgarney 头像 user_2dx56kla 头像 wanshoujidezhuantou 头像 ligaai 头像 daqianduan 头像 xiaodiandideyangrouchuan 头像 binghe001 头像 aitibao_shichangyingxiao 头像 yunxiao0816 头像 kubesphere 头像 tangqingfeng 头像 kuaidi100api 头像
点赞 51 用户, 点赞了这篇动态!
点赞

Add a new 评论

Some HTML is okay.