为什么要将派生类的实例分配给变量,该变量 Type 不是实例之一,而是其基类

本文关键字:实例 变量 基类 Type 派生 分配 为什么 | 更新日期: 2023-09-27 18:35:06

我有5年的经验。但老实说,虽然我知道并使用这个结构......

Baseclass bc = new DerivedClass(); 

我不知道它实际上做了什么,不是真的,不是真的。它是派生类还是基类?我知道如果我打电话给bc。方法() 我将获得派生类方法。但前提是我使用 new 关键字或覆盖或其他东西。老实说,我在这里开始变得有点模糊,我认为我需要回到基础,有人可以指出我正确的方向吗?

为什么要将派生类的实例分配给变量,该变量 Type 不是实例之一,而是其基类

您正在创建 DerivedClass 的实例,并将其分配给 BaseClass 类型的变量。如果您有类似基类 Animal 的东西,其中包含两个派生类 Fish 和 Dog,但您不知道哪一个将被实例化,这在您的上下文中并不重要,因为您将调用基类中定义的方法。例如,你可以有这样的东西:

Animal a;
if (whatever you want)
    a = new Dog();
else
    a = new Fish();
a.Feed();

小心使用修饰符,因为如果您使用虚拟定义动物饲料并在具有覆盖的鱼中重新定义它,则将执行 Fish 版本(它在执行时链接)。如果您没有将基本版本标记为虚拟版本并将 Fish 版本标记为新版本,则会执行 Animal 版本(它在编译时链接)。

它创建DerivedClass的实例并将其隐式转换为类型 Baseclass

正如我假设这编译的那样,这意味着DerivedClassBaseclass继承,例如:

class DerivedClass : Baseclass
{
}

或者有一个隐式强制转换运算符用于在这些类型之间进行转换,例如

class DerivedClass
{
    public static implicit operator Baseclass(DerivedClass d)
    {
        // return a Baseclass here
    }
}

使用以下方法

public class Person
{
    public string FirstName { get; set; }
    public string LastName { get; set; }
}
public class Employee : Person
{
    public string RoleName { get; set; }
}

如果我们创建一个新的Employee实例,但是我们的变量声明实际上是Person的,那么将要发生的只是对Person的隐式强制转换,这意味着我们将无法访问Employee中的任何方法或属性。我想如果Employee的构造函数影响Person的构造函数,这可能会很有用,但我们不关心Employee中的任何内容,但我不推荐它。相反,我建议构建一种利用更清晰的多态性的方法。例如,当派生对象用作参数时,实际上参数类型是其基之一的类型。

public void DoSomething(Employee employee)
{
    // here we do something with an employee
    // ...
    string fullName = GetTheirFullName(employee);
}
public string GetTheirFullName(Person person)
{
    return (person.FirstName + " " + person.LastName).Trim();
}

它只是创建一个DerivedClass实例并将其分配给 bc,其类型为 BaseClass