检查类继承的原则

已完成

继承是面向对象的编程的主要特征之一。 它允许通过定义类之间的关系来创建类的层次结构。 在 C# 中,可以创建定义常见行为和特征的基类,然后创建继承和扩展该行为的派生类。

例如,名为 Person 的基类可以定义 NameAge 属性。 名为 Employee 的派生类可能会继承这些属性,并定义其他属性,例如 EmployeeNumberSalary

此示例可以使用以下 C# 代码表示:

public class Person
{
    public string? Name { get; set; }
    public int Age { get; set; }
}

public class Employee : Person
{
    public int EmployeeNumber { get; set; }
    public decimal Salary { get; set; }
}

此代码示例定义 Person 类,然后定义 Employee 类。 请注意 : 类声明中的冒号 (Employee) 字符。 :Employee 之间的冒号(Person)指示 Employee 类继承自 Person 类。 在这种情况下,Employee 类继承 NameAge 属性,并定义另外两个属性:EmployeeNumberSalary。 创建 Employee 对象时,可以访问 Name 类中定义的 AgePerson 属性,以及 EmployeeNumber 类中定义的 SalaryEmployee 属性。 创建 Person 对象时,它只能访问 NameAge 属性。

通过继承,可以创建共享常见行为和特征的类的层次结构。 它使你能够重复使用代码并定义类之间的关系。 通过使用继承,可以创建更易于维护且可扩展的代码。

继承的优点

继承提供了几个好处,包括:

  • 代码重用:继承允许重用派生类中基类中定义的代码。 这样可以减少重复并提升代码重用。
  • 扩展性:继承使你可以通过将新成员添加到派生类来扩展基类的行为。 可以在派生类中定义新的属性、方法和事件。
  • 封装:继承通过允许你将基类的实现细节隐藏给派生类,从而提升封装性。 通过继承和封装,可以定义与派生类的对象交互的清晰接口。
  • 一致性:继承允许在基类中定义常见行为,从而提升一致性。 从基类继承可确保派生类共享相同的基行为。
  • 多态性:继承可实现多态性,这使你可以将派生类的对象视为其基类的对象。 多态性使你能够编写用于不同类型对象的代码,而无需在编译时知道其特定类型。

将类继承与接口实现进行比较

C# 提供了两种机制用于定义类之间的关系:类继承和接口实现。 类继承允许类从基类继承成员,而接口实现允许类实现接口中定义的成员。 这两种机制都支持代码重用和提升多态性,但它们具有不同的特征:

类继承具有以下特征:

  • 类只能从一个基类继承。
  • 派生类可以重用、扩展和修改基类中定义的行为。
  • 继承在类之间创建“is-a”关系。

接口实现具有以下特征:

  • 类可以实现多个接口。
  • 类可以定义自己的行为并实现在接口中定义的成员。
  • 接口实现在类之间创建“can-do”关系。

设计面向对象的系统时,“is-a”和“can-do”关系之间的差异非常重要。 通常,当派生类是基类的专用版本时,应使用类继承。 当类可以执行一组特定的作时,应使用接口实现。

何时使用类继承的一个示例是,你有一个名为 Dog 的基类和名为 German ShepherdGolden Retriever的派生类。 German ShepherdGolden RetrieverDog的专用版本。 在这种情况下,可以使用类继承在 Dog 类中定义一组常见的属性和方法,然后在 German ShepherdGolden Retriever 类中扩展和修改该行为。

使用接口实现的一个示例是,你有一个名为 IDrawable 的接口,用于定义 Draw 方法。 可以在可绘制的类中实现 IDrawable 接口,例如 CircleRectangle。 在这种情况下,可以使用接口实现来定义由不同类共享的常见作集。

比较类继承与多态性

类继承和多态性是面向对象的编程中密切相关的概念。 继承允许定义共享常见行为的类的层次结构,而多态性允许将派生类的对象视为其基类的对象。

例如,请考虑一个名为 HousePet 的基类和名为 DogCat的派生类。 HousePet 类定义一个 Speak 方法,该方法返回表示宠物发出的声音的字符串。 Dog 类重写 Speak 方法以返回“Woof”,Cat 类重写 Speak 方法以返回“Meow”。 可以创建一个名为 HousePetmyPetDogCat 对象,并调用 Speak 方法以获取相应的响应。

在此示例中,HousePet 类定义 SpeakDog 类共享的常见 Cat 行为。 DogCat 类将重写 Speak 方法以自定义行为。 对引用其中一个派生类的 Speak 对象调用 HousePet 方法时,会根据对象的类型获取相应的响应。 下面是演示此概念的代码示例:

HousePet myPet1 = new Dog();    // Create a HousePet object named myPet1 that's of type Dog
HousePet myPet2 = new Cat();    // Create a HousePet object named myPet2 that's of type Cat

Console.WriteLine(myPet1.Speak());    // Call the Speak method on myPet1
Console.WriteLine(myPet2.Speak());    // Call the Speak method on myPet2

// Output: Woof
//         Meow

public class HousePet
{
    public virtual string Speak()
    {
        return "Hello";
    }
}

public class Dog : HousePet
{
    public override string Speak()
    {
        return "Woof";
    }
}

public class Cat : HousePet
{
    public override string Speak()
    {
        return "Meow";
    }
}

通过多态性,可以编写适用于不同类型对象的代码,而无需在编译时了解其特定类型。 在此示例中,通过创建类型为 HousePetDogCat 类的实例来实现多态性。 Speak 方法在 HousePet 对象上调用,并根据对象的类型(“Woof”或“Meow”)返回相应的响应。 在 C# 中,可以使用类继承或接口实现来实现多态性。

总结

继承是面向对象的编程中的基本概念,通过定义类之间的关系,可以创建类的层次结构。 在 C# 中,可以使用类继承来创建定义常见行为和特征的基类,然后创建继承和扩展该行为的派生类。 继承提供了多种优势,包括代码重用、扩展性、封装、一致性和多态性。 通过使用继承,可以创建更易于维护且可扩展的代码。