C# 继承的方法无法访问派生类中的新实现

C# 继承的方法无法访问派生类中的新实现,c#,inheritance,methods,method-hiding,C#,Inheritance,Methods,Method Hiding,如本文件所述: 派生类的type对象无法访问从基类继承的新重新定义的方法,并且在继承的方法DescribeCar中对ShowDetails方法中派生类的对象的调用是对基类的ShowDetails方法进行的 如果DescribeCar方法也可用于ConvertibleCar类,为什么它看不到所谓的新ShowDetails方法 new隐藏了旧方法,这意味着如果直接在ConvertibleCar实例上调用它,将获得派生类行为,但不会以多态方式调用它 当基类调用它时,它正在调用虚方法,因为它没有被重写,

如本文件所述:

派生类的type对象无法访问从基类继承的新重新定义的方法,并且在继承的方法DescribeCar中对ShowDetails方法中派生类的对象的调用是对基类的ShowDetails方法进行的

如果DescribeCar方法也可用于ConvertibleCar类,为什么它看不到所谓的新ShowDetails方法


new隐藏了旧方法,这意味着如果直接在ConvertibleCar实例上调用它,将获得派生类行为,但不会以多态方式调用它

当基类调用它时,它正在调用虚方法,因为它没有被重写,所以虚方法调用基类方法。与其使用几乎从未使用过的方法隐藏,不如覆盖它:

class ConvertibleCar : Car
{
    public override void ShowDetails()
    {
        System.Console.WriteLine("A roof that opens up.");
    }
}

new隐藏了旧方法,这意味着如果直接在ConvertibleCar实例上调用它,将获得派生类行为,但不会以多态方式调用它

当基类调用它时,它正在调用虚方法,因为它没有被重写,所以虚方法调用基类方法。与其使用几乎从未使用过的方法隐藏,不如覆盖它:

class ConvertibleCar : Car
{
    public override void ShowDetails()
    {
        System.Console.WriteLine("A roof that opens up.");
    }
}

好吧,当你想到它时——想想没有继承——这就像问为什么Car.descripebecar不能访问ConvertibleCar.ShowDetails

ConvertibleCar.ShowDetails本质上是一个方法,如果您愿意,它不是Car的成员,因为有了新的关键字。然而,Car有一个显示细节的方法

Car.descripebecar作为Car的成员方法,具有Car.ShowDetails的可见性,不可转换Car.ShowDetails,因此调用Car.ShowDetails

也许这会更清楚。使用新关键字,这是另一种思考方式:

class Car
{
  ...
  public virtual void ShowDetails(){..}
}

class ConvertibleCar : Car
{
  public void new_ShowDetails(){}
}

Car不知道ConvertibleCar.new\u ShowDetails,因此无法调用该方法。

好吧,当您考虑它时-考虑没有继承-这就像问Car.DescribeCar为什么没有访问ConvertibleCar.ShowDetails的权限

ConvertibleCar.ShowDetails本质上是一个方法,如果您愿意,它不是Car的成员,因为有了新的关键字。然而,Car有一个显示细节的方法

Car.descripebecar作为Car的成员方法,具有Car.ShowDetails的可见性,不可转换Car.ShowDetails,因此调用Car.ShowDetails

也许这会更清楚。使用新关键字,这是另一种思考方式:

class Car
{
  ...
  public virtual void ShowDetails(){..}
}

class ConvertibleCar : Car
{
  public void new_ShowDetails(){}
}

Car不了解ConvertibleCar.new\u ShowDetails,因此无法调用该方法。

其他答案是正确的,但我想展示一个示例,说明DescribeCar方法内部发生的情况

t是ConvertibleCar,因为它是对象的实际类型,但this变量实际上是编译器隐藏的每个非静态方法的参数,它的类型是Car

关于虚拟方法的具体情况是,当您的代码调用它们时,编译器会对对象的实际类型进行额外的查找,即调用GetType并检查层次结构中是否有任何类型重写了该方法。然后调用方法的最新实现。
但是如果使用new而不是override,则此查找不会产生任何结果,将使用基本实现。如果使用new,调用新实现的唯一方法是将变量强制转换为定义新实现的类型。

其他答案都是正确的,但我想展示一个示例,说明DescribeCar方法内部发生的情况

t是ConvertibleCar,因为它是对象的实际类型,但this变量实际上是编译器隐藏的每个非静态方法的参数,它的类型是Car

关于虚拟方法的具体情况是,当您的代码调用它们时,编译器会对对象的实际类型进行额外的查找,即调用GetType并检查层次结构中是否有任何类型重写了该方法。然后调用方法的最新实现。
但是如果使用new而不是override,则此查找不会产生任何结果,将使用基本实现。如果使用new,调用新实现的唯一方法是将变量强制转换为定义新实现的类型。

不清楚您在问什么。Car.DescribeCar只知道汽车。显示详细信息。。。这可以在ConvertibleCar中被重写,但代码并不是这样做的。相反,它声明了一个新方法…因为您说它是新的,即它不重写但隐藏了另一个实现。new和override之间的区别在于,当对象被视为超类时,将不会调用定义为new的方法,我要问的是关于ConvertibleCar.DescribeCarDescribeCar是在Car中定义的,看不到您的新方法。坦白地说,你几乎从来都不想使用新的关键字

关于方法。你问的问题真的不清楚。Car.DescribeCar只知道汽车。显示详细信息。。。这可以在ConvertibleCar中被重写,但代码并不是这样做的。相反,它声明了一个新方法…因为您说它是新的,即它不重写但隐藏了另一个实现。new和override之间的区别在于,当对象被视为超类时,将不会调用定义为new的方法,我要问的是关于ConvertibleCar.DescribeCarDescribeCar是在Car中定义的,看不到您的新方法。坦白地说,你几乎不想在方法上使用new关键字,这意味着如果你直接在一个ConvertibleCar实例上调用它,你会得到派生类的行为——你能详细说明一下吗?看起来他/她是通过car2.descripebecar直接在ConvertibleCar实例上调用它@罗亚,我一定会试试的。诀窍在于,他不是直接在ConvertibleCar实例上调用它,而是调用一个继承的基类方法,该方法调用一个虚拟方法,因此不知道派生类中的隐藏方法。啊,我刚刚看到我的困惑是从哪里来的。我把描述和展示的细节搞混了。出于某种原因,我认为他在调用car2.ShowDetails,这显然会调用派生类方法。@BradleyDotNET当基类调用它时,它正在调用虚方法,为什么会这样?我是从DescribeCar调用它的,它对ConvertibleCar类可用,但它看不到新方法?@user3723486,因为ConvertibleCar没有定义自己的DescribeCar方法。这意味着如果直接在ConvertibleCar实例上调用它,您将获得派生类的行为-您能详细说明一下吗?看起来他/她是通过car2.descripebecar直接在ConvertibleCar实例上调用它@罗亚,我一定会试试的。诀窍在于,他不是直接在ConvertibleCar实例上调用它,而是调用一个继承的基类方法,该方法调用一个虚拟方法,因此不知道派生类中的隐藏方法。啊,我刚刚看到我的困惑是从哪里来的。我把描述和展示的细节搞混了。出于某种原因,我认为他在调用car2.ShowDetails,这显然会调用派生类方法。@BradleyDotNET当基类调用它时,它正在调用虚方法,为什么会这样?我从DescribeCar调用它,它可用于ConvertibleCar类,但是它看不到新方法?@user3723486,因为ConvertibleCar没有定义自己的DescribeCar方法。您甚至还可以派生,并且您的示例将是准确的:您甚至还可以派生,并且您的示例将是准确的:如何确认此关键字的类型?@user3723486 GetType方法返回关键字的实际类型对象,而不是引用的类型。此引用的类型将和在其中定义方法的类相同。如何确认此关键字的类型?@user3723486 GetType方法返回对象的实际类型,而不是引用的类型。此引用的类型将和在其中定义方法的类相同。