C# - 繼承:初學者的全面指南

你好,有抱負的程序员們!今天,我們將踏上一段令人興奮的旅程,探索 C# 繼承的領域。別擔心如果你是編程新手——我將成為你的友好導遊,我們將一起逐步探索這個概念。在這個教程結束時,你將對繼承有堅實的掌握,並了解它如何使你的代碼更高效和有組織。

C# - Inheritance

繼承是什麼?

在我們深入細節之前,讓我們從一個簡單的比喻開始。想像你正在創建一個家族樹。家族樹中的每個人從他們的父母那裡繼承某些特質,對吧?在編程中,繼承的工作方式與此類似!

在 C# 中,繼承是一種機制,讓新的類可以基於已存在的類。新的類繼承已存在類的屬性和方法,就像你可能繼承了你父母的眼睛顏色或身高一樣。

基類和派生類

在繼承的世界中,我們有兩個主要角色:

  1. 基類(也稱為父類或超類):這是原始類,包含共同的屬性和方法。
  2. 派生類(也稱為子類或子類別):這是從基類繼承而來的新類。

讓我們看一個簡單的例子:

// 基類
public class Animal
{
public string Name { get; set; }
public int Age { get; set; }

public void Eat()
{
Console.WriteLine($"{Name} 正在吃東西。");
}
}

// 派生類
public class Dog : Animal
{
public void Bark()
{
Console.WriteLine($"{Name} 說「汪!」");
}
}

在這個例子中,Animal 是我們的基類,而 Dog 是我們的派生類。Dog 類聲明中的 : Animal 部分告訴 C# DogAnimal 繼承。

現在,讓我們看看我們如何使用這些類:

Dog myDog = new Dog();
myDog.Name = "Buddy";
myDog.Age = 3;

myDog.Eat();  // 從 Animal 繼承
myDog.Bark(); // 在 Dog 中定義

當我們運行這段代碼時,我們將看到:

Buddy 正在吃東西。
Buddy 說「汪!」

這不是很酷嗎?我們的 Dog 類可以訪問 Animal 類中的 NameAge 屬性,以及 Eat() 方法,而不需要我們重寫所有那個代碼!

初始化基類

現在,你可能會想,"當我創建派生類對象時,如果要為基類設置一些初始值怎麼辦?" 這個問題問得好!這就是構造函數發揮作用的地方。

讓我們修改我們的例子:

public class Animal
{
public string Name { get; set; }
public int Age { get; set; }

public Animal(string name, int age)
{
Name = name;
Age = age;
}

public void Eat()
{
Console.WriteLine($"{Name} 正在吃東西。");
}
}

public class Dog : Animal
{
public Dog(string name, int age) : base(name, age)
{
// 如果需要,對 Dog 進行額外初始化
}

public void Bark()
{
Console.WriteLine($"{Name} 說「汪!」");
}
}

在這個更新的版本中,我們為 Animal 類添加了一個構造函數。Dog 類的構造函數使用 : base(name, age) 語法來調用基類構造函數,並傳遞 nameage 參數。

現在,我們可以這樣創建一個 Dog 對象:

Dog myDog = new Dog("Buddy", 3);
myDog.Eat();
myDog.Bark();

這將產生與之前相同的輸出,但我們現在在創建 Dog 對象時初始化了 NameAge 屬性。

C# 中的多繼承

現在來個轉折:與某些其他編程語言不同,C# 不支持類的多繼承。這意味著一個類不能直接從多個基類繼承。

但別擔心!C# 有個巧妙的解決方案,使用接口。接口就像一個合同,指定了一個類應該做什麼,但不定義它應該如何做。

讓我們看一個例子:

public interface ISwimmable
{
void Swim();
}

public interface IFlyable
{
void Fly();
}

public class Bird : Animal, IFlyable
{
public Bird(string name, int age) : base(name, age) { }

public void Fly()
{
Console.WriteLine($"{Name} 正在飛行。");
}
}

public class Fish : Animal, ISwimmable
{
public Fish(string name, int age) : base(name, age) { }

public void Swim()
{
Console.WriteLine($"{Name} 正在游泳。");
}
}

public class Duck : Animal, ISwimmable, IFlyable
{
public Duck(string name, int age) : base(name, age) { }

public void Swim()
{
Console.WriteLine($"{Name} 正在游泳。");
}

public void Fly()
{
Console.WriteLine($"{Name} 正在飛行。");
}
}

在這個例子中,我們創建了兩個接口:ISwimmableIFlyable。我們的 Bird 類從 Animal 繼承並實現 IFlyableFish 類從 Animal 繼承並實現 ISwimmable。看看我們的 Duck 類——它從 Animal 繼承並實現了 ISwimmableIFlyable

讓我們使用這些類:

Bird myBird = new Bird("Tweety", 2);
myBird.Fly();

Fish myFish = new Fish("Nemo", 1);
myFish.Swim();

Duck myDuck = new Duck("Donald", 5);
myDuck.Swim();
myDuck.Fly();

這將輸出:

Tweety 正在飛行。
Nemo 正在游泳。
Donald 正在游泳。
Donald 正在飛行。

這不是很神奇嗎?我們的 Duck 既能游泳又能飛行,即使 C# 不支持類的多繼承!

方法表

這裡是一個總結我們在例子中使用過的方法的表:

類/接口 方法 描述
Animal Eat() 打印動物正在吃東西的消息
Dog Bark() 打印狗正在吠叫的消息
ISwimmable Swim() 定義游泳的方法
IFlyable Fly() 定義飛行的方法
Bird Fly() 實現飛行方法
Fish Swim() 實現游泳方法
Duck Swim(), Fly() 實現游泳和飛行方法

這就是 C# 中繼承的基本知識!從簡單的基類和派生類到使用接口的更複雜情況。記住,繼承是關於重用代碼和在類之間創建邏輯關係。它是使你的代碼更高效和容易維護的有力工具。

在你繼續你的編程旅程時,你會發現許多使用繼承來解決複雜問題的方法。繼續練習,並不要害怕嘗試這些概念。快樂編程!

Credits: Image by storyset