我发现很难理解 C# 中的继承 [关闭]

Posted

技术标签:

【中文标题】我发现很难理解 C# 中的继承 [关闭]【英文标题】:I am finding it hard to understand inheritance in C# [closed] 【发布时间】:2016-08-01 15:47:20 【问题描述】:

我想知道这种情况:Employee继承自Person,Manager继承自Employee,哪种说法正确?

Person alice = new Employee();
Employee bob = new Person();
Manager cindy = new Employee();
Manager dan = (Manager)(new Employee());

【问题讨论】:

当您尝试时会发生什么?这段代码能编译吗?这些对象是否按照您期望的方式工作? 阅读教程。每个案例都有很多文章解释。 我投票结束这个问题作为题外话,因为这段代码可以简单地从 VS 运行。 这看起来像是一道测试题,不应该回答。好吧,直到考试时间结束。 【参考方案1】:

只有第一个是正确的。

【讨论】:

【参考方案2】:

让我们画一个草图:

  Person
    Employee  (Employee can be though as a subset of Person)
      Manager (Manager can be though as a subset of Employee)

所以 每个 ManagerEmployee每个 EmployeePerson。该序列是传递的,因此每个ManagerPerson。现在,让我们看看

  Person alice = new Employee();

您已经创建了一个 Employee 实例 (new Employee();),然后尝试将其分配给 Person (Person alice =) 实例;因为 每个 EmployeePerson 你可以做到。

相反:

  Manager cindy = new Employee();

您创建了一个Employee 实例,然后尝试将其分配给Manager 实例。你不能这样做,因为没有这样的规则 每个 EmployeeManager (正好相反:每个ManagerEmployee,但是不是反之亦然)。

【讨论】:

【参考方案3】:

继承的一个用途是将继承的类型转换为基类型(而不是相反)。

所以你可以这样做

Manager danTheManager = new Manager();
Employee danTheEmployee = (Employee)danTheManager;
Person danThePerson = (Person)danTheManager;
Person alsoDanThePerson = (Person)danTheEmployee;

关键是您应该始终能够将继承的类型转换为其基类型之一并将其用作该类型的实例。 (理想情况下尽量避免使用其他方式 - 检查对象以查看它是什么继承类型。)

它被称为Liskov Substitution Principle(SOLID 中的 L。)简单的解释是您应该始终能够将 Manager 转换为 EmployeePerson 并将其用作该实例类型,因为它继承自它们。您不必检查对象的类型,因为如果它是 Manager,它会以一种方式工作,但如果它是 Employee,它会以不同的方式工作。

【讨论】:

以上是关于我发现很难理解 C# 中的继承 [关闭]的主要内容,如果未能解决你的问题,请参考以下文章

C#对继承的理解

C#中的继承

理解开闭原则

在设计 C# 类库时,我应该何时选择继承而不是接口? [关闭]

尽管类继承,变量仍不可访问? [复制]

为啥 C# 中的基类允许实现接口契约而不继承它?