【问题标题】:Need for method hiding and method overriding需要方法隐藏和方法覆盖
【发布时间】:2018-01-24 11:15:54
【问题描述】:

为什么在 C# 中开发了方法隐藏和方法覆盖?我不是在问他们的实施。我特别问的是发明者希望用语言创造这两种东西的场景。为什么方法隐藏在不同的场景中有用(代码示例)以及为什么没有。为什么方法覆盖在某些情况下效果很好,为什么在其他情况下效果不好。实际示例将不胜感激。请注意,我不是要求实施。

【问题讨论】:

  • 您提供的线程中的大多数答案都与实现有关。我是从开发人员的角度问这个问题。在 C# 中创建这两个东西有什么需要
  • stackoverflow.com/questions/3838553/overriding-vs-method-hiding 检查那个。接受的答案很详细
  • 好吧,给定线程中接受的答案非常详细,但您能稍微解释一下,这个“穷人的协方差”在那个详细的答案中究竟说明了什么?我的目的是了解发明者对 C# 的意图。这能解释什么吗?
  • 这只是语言的一个怪癖。可能是一时兴起,而不是真正的功能性,因为隐藏有用的用例并不多
  • 除非你问他,否则你不会知道。无论如何,如果您想大海捞针,请在本书中搜索microsoft.com/en-us/download/details.aspx?id=7029

标签: c# overriding method-hiding


【解决方案1】:

你问为什么? “为什么”很简单:允许类/对象的多态性。

假设您要创建一个代表汽车的类,另一个代表卡车的类。你可能会注意到,两者都有很多共同的属性(比如它们有轮子、引擎、重量、长度等)和方法(比如说“打开”和“关闭”引擎,增加/减少加速度等)。

你是做什么的?你会用完全相同的代码编写 2 个类,然后只为卡车添加 Weagon 吗?

不,您编写了一个“汽车”类,其中包含汽车的所有方法和属性,以及您制作的一些属性然后“可覆盖”(取决于如何做到这一点的语言 - 我是 C#程序员因此将是“抽象的”或“虚拟的”,视情况而定)。

然后“卡车”将覆盖最大速度,或站点,或者说它在前部和车上有多少个轮子,如果它之间有一个轴等等。

另一方面,隐藏方法是当基方法不能被覆盖时(因为,取决于语言,如果不是“制成”可覆盖的,它就不能被覆盖)等等,声明一个方法在子类上,它“隐藏”了原来的类。

它是怎么发生的?假设 Car 类是这样的:

public class Car
{
    private double mLength;
    private int mMaxSpeed;
    public virtual double Length { get { return this.mLength; } set { if (value > 0) { this.mLength = value; } } }
    public int MaxSpeed { get { return this.mMaxSpeed; } set { if (value > 0 && value < 350) { this.mMaxSpeed = value; } } }
}

现在,在 C# 中,“virtual”关键字表示方法(或本例中的属性)可以被覆盖,因此缺少它意味着它不能。该类允许覆盖“Length”属性,但不能覆盖“MaxSpeed”。

所以,当我编写 Truck 类时,会是这样的:

public class Truck : Car
{
    public override double Length { get { return base.Length; } set { if (value > 20.00) { base.Length = value; } } }
    public new int MaxSpeed { get { return base.MaxSpeed; } set { if (value < 100 && value > 0) { base.MaxSpeed = value; } } }
}

通过这样做,Truck 类会覆盖“Length”,但会隐藏“MaxSpeed”。 由于 Truck 继承了(多态性)Car,因此可以将其作为值传递给 Car 的任何变量,所以:

Car m1 = new Car();
Car m2 = new Truck();

这行得通,因为卡车(在我们的定义中)是一辆汽车。 那么,后果是什么?如果我创建了一个具有 Car 类型参数的方法,并且我传递了一个 Truck 实例,则被覆盖的方法将(始终)调用它的最高实现,但隐藏的方法将调用特定类型的方法.

所以这个:

public static void Initialize(Car vehicle)
{
    vehicle.Length = 5.00; //if vehicle is a Car (not derivated) will be 5 if it's a truck will not set
    vehicle.MaxSpeed = 350; //will set to 350 for both, even if Truck does not allow over 100, the method called is on the car Class, not Truck
}

Initialize(new Car());
Initialize(new Truck()); //Length won't pass (as intended on Truck class to only allow higher than 20) but MaxSpeed will pass as 350, even if Truck does not allow it

对于隐藏方法 (MaxSpeed) 会是一个问题,但对于覆盖方法 (Length) 不会。由于 Length 将为其最高实现(它是在卡车上重写的虚拟方法)提供,因此它将始终按照实际类的意图工作,但 MaxSpeed 将使用 Car 类中的方法编写,即使它是卡车。只有当函数/方法使用 Truck 作为参数时,它才会在 Truck 类上按预期实现。

【讨论】:

  • 所以这就是您的答案所解释的: 1- 这两个概念是为在 C# 中实现多态性和继承而开发的。 2- 方法覆盖适用于那些可以使用基类中存在的相同功能但可以在派生类级别自定义的方法。 3-方法隐藏适用于那些希望将其基本功能作为默认值的方法,但如果有人想在派生类中自定义它,可以在派生类中使用 new 关键字并在实现派生时强制转换或使用派生类的对象来完成班级。是吗?
  • 是的,对于这个概念,但我的回答与 C# 无关——许多语言都使用这个概念。同样的行为适用于 VB/VB.net、Delphi 和 Pascal、Python 甚至(不是 EXACLTY 相同的方式,例如,“New”和“Virtual”关键字在 C# 上,但在 VB 上是“Hides”和“Overridable” " - 所以我的回答是我解释了这个概念并使用 C# 作为示例来源。
  • 谢谢。赞赏。
猜你喜欢
  • 2013-01-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-04-19
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多