📅  最后修改于: 2023-12-03 15:14:27.303000             🧑  作者: Mango
继承是C#中面向对象编程中的一个核心概念,它允许我们提取共同的特征并将其放置在父类中,子类继承父类并获得这些特征,同时还可以添加自己的特征。这使得代码重复性减少,可读性更好,可维护性更强。
在C#中,我们使用:
运算符来实现继承。下面是一个简单的例子:
class Animal {
public void Eat(string food) {
Console.WriteLine($"I'm eating {food}!");
}
}
class Cat : Animal {
public void Meow() {
Console.WriteLine("Meow!");
}
}
Cat mimi = new Cat();
mimi.Eat("fish"); // 输出 "I'm eating fish!"
mimi.Meow(); // 输出 "Meow!"
在这个例子中,我们定义了一个Animal
类,它有一个Eat
方法。我们定义了一个Cat
类,它继承自Animal
类,并且除了继承自Animal
类的Eat
方法之外,还有自己的Meow
方法。在我们创建了Cat
的实例之后,我们可以调用其从Animal
继承下来的Eat
方法,也可以调用其自己的Meow
方法。
值得注意的是,子类可以访问其父类的公有成员,但不能访问私有成员。
有时,子类可能需要覆盖其父类中的某个方法,以改变其行为。我们可以使用override
关键字来完成这个任务。下面是一个带有重写的例子:
class Animal {
public virtual void MakeSound() {
Console.WriteLine("I don't know how to make a sound.");
}
}
class Cat : Animal {
public override void MakeSound() {
Console.WriteLine("Meow!");
}
}
class Dog : Animal {
public override void MakeSound() {
Console.WriteLine("Woof!");
}
}
Animal animal1 = new Animal();
Animal animal2 = new Cat();
Animal animal3 = new Dog();
animal1.MakeSound(); // 输出 "I don't know how to make a sound."
animal2.MakeSound(); // 输出 "Meow!"
animal3.MakeSound(); // 输出 "Woof!"
在这个例子中,我们定义了一个Animal
类,它有一个虚拟方法MakeSound
。同时,我们定义了两个子类Cat
和Dog
,它们都重写了Animal
类中的MakeSound
方法。在我们创建了三个不同的实例之后,我们调用它们各自的MakeSound
方法,得到了不同的结果。
值得注意的是,当使用virtual
关键字修饰方法时,表示这个方法可以被子类重写。而当子类使用override
关键字重写父类的虚拟方法时,也必须使用virtual
关键字来修饰父类虚拟方法。
除了普通的类外,C#中还存在抽象类和接口两种特殊的类类型,它们都可以用于继承或者实现,在面向对象编程中发挥着重要的作用。
抽象类是不能直接实例化的类,它只能用于被继承。与普通类不同的是,抽象类可以包含抽象方法,抽象方法必须被子类重写才能被运行。下面是一个抽象类的例子:
abstract class Animal {
public abstract void MakeSound();
}
class Cat : Animal {
public override void MakeSound() {
Console.WriteLine("Meow!");
}
}
class Dog : Animal {
public override void MakeSound() {
Console.WriteLine("Woof!");
}
}
Animal animal1 = new Cat();
Animal animal2 = new Dog();
animal1.MakeSound(); // 输出 "Meow!"
animal2.MakeSound(); // 输出 "Woof!"
在这个例子中,我们定义了一个抽象类Animal
和两个子类Cat
和Dog
。由于Animal
包含一个抽象方法MakeSound
,所以Animal
类本身不能被实例化。我们使用子类来实例化Animal
,并且通过调用MakeSound
方法来演示抽象方法的使用。
与抽象类相似,接口也不能直接实例化。接口是一种特殊的类类型,它声明了一组公共方法、属性、索引器和事件,并没有实现。它的作用是定义了一组协议,使得其他类可以按照这个协议进行实现。下面是一个接口的例子:
interface IAnimal {
void MakeSound();
}
class Cat : IAnimal {
public void MakeSound() {
Console.WriteLine("Meow!");
}
}
class Dog : IAnimal {
public void MakeSound() {
Console.WriteLine("Woof!");
}
}
IAnimal animal1 = new Cat();
IAnimal animal2 = new Dog();
animal1.MakeSound(); // 输出 "Meow!"
animal2.MakeSound(); // 输出 "Woof!"
在这个例子中,我们定义了一个接口IAnimal
和两个子类Cat
和Dog
。由于Cat
和Dog
都实现了IAnimal
接口中的MakeSound
方法,所以它们可以被当做IAnimal
类型来实例化。我们使用接口来实现多态,即使子类的实现方式不同,但它们都遵循了IAnimal
接口的协议,具有了相同的行为。
继承是C#中面向对象编程的核心概念之一,它允许我们重用代码、减少重复、提高可读性和可维护性。在使用继承时,我们通常需要了解基本的语法和相关的概念,如重写、抽象类和接口等,以充分发挥继承的优势。