C# - 繼承:初學者的全面指南
你好,有抱負的程序员們!今天,我們將踏上一段令人興奮的旅程,探索 C# 繼承的領域。別擔心如果你是編程新手——我將成為你的友好導遊,我們將一起逐步探索這個概念。在這個教程結束時,你將對繼承有堅實的掌握,並了解它如何使你的代碼更高效和有組織。
繼承是什麼?
在我們深入細節之前,讓我們從一個簡單的比喻開始。想像你正在創建一個家族樹。家族樹中的每個人從他們的父母那裡繼承某些特質,對吧?在編程中,繼承的工作方式與此類似!
在 C# 中,繼承是一種機制,讓新的類可以基於已存在的類。新的類繼承已存在類的屬性和方法,就像你可能繼承了你父母的眼睛顏色或身高一樣。
基類和派生類
在繼承的世界中,我們有兩個主要角色:
- 基類(也稱為父類或超類):這是原始類,包含共同的屬性和方法。
- 派生類(也稱為子類或子類別):這是從基類繼承而來的新類。
讓我們看一個簡單的例子:
// 基類
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# Dog
從 Animal
繼承。
現在,讓我們看看我們如何使用這些類:
Dog myDog = new Dog();
myDog.Name = "Buddy";
myDog.Age = 3;
myDog.Eat(); // 從 Animal 繼承
myDog.Bark(); // 在 Dog 中定義
當我們運行這段代碼時,我們將看到:
Buddy 正在吃東西。
Buddy 說「汪!」
這不是很酷嗎?我們的 Dog
類可以訪問 Animal
類中的 Name
和 Age
屬性,以及 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)
語法來調用基類構造函數,並傳遞 name
和 age
參數。
現在,我們可以這樣創建一個 Dog
對象:
Dog myDog = new Dog("Buddy", 3);
myDog.Eat();
myDog.Bark();
這將產生與之前相同的輸出,但我們現在在創建 Dog
對象時初始化了 Name
和 Age
屬性。
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} 正在飛行。");
}
}
在這個例子中,我們創建了兩個接口:ISwimmable
和 IFlyable
。我們的 Bird
類從 Animal
繼承並實現 IFlyable
。Fish
類從 Animal
繼承並實現 ISwimmable
。看看我們的 Duck
類——它從 Animal
繼承並實現了 ISwimmable
和 IFlyable
!
讓我們使用這些類:
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