覆盖是当您override
在子类中提供该方法的新实现时,该方法在基类中定义为virtual
.
隐藏是当您在子类中提供该方法的新实现时,该方法未在基类中定义为virtual
,或者当您的新实现未指定 时override
。
隐藏通常是不好的。如果可以完全避免,您通常应该尽量不这样做。隐藏可能会导致意想不到的事情发生,因为隐藏方法仅在您定义的实际类型的变量上调用时使用,而不是在使用基类引用时使用......另一方面,被覆盖的虚拟方法最终会被调用的正确方法版本,即使在使用子类上的基类引用调用时也是如此。
例如,考虑这些类:
public class BaseClass
{
public virtual void Method1() //Virtual method
{
Console.WriteLine("Running BaseClass Method1");
}
public void Method2() //Not a virtual method
{
Console.WriteLine("Running BaseClass Method2");
}
}
public class InheritedClass : BaseClass
{
public override void Method1() //Overriding the base virtual method.
{
Console.WriteLine("Running InheritedClass Method1");
}
public new void Method2() //Can't override the base method; must 'new' it.
{
Console.WriteLine("Running InheritedClass Method2");
}
}
让我们在匹配的引用中使用 InheritedClass 的实例这样称呼它:
InheritedClass inherited = new InheritedClass();
inherited.Method1();
inherited.Method2();
这将返回您应该期望的结果;这两种方法都表示它们正在运行 InheritedClass 版本。
运行 InheritedClass 方法 1
运行 InheritedClass 方法2
这段代码创建了同一个 InheritedClass 的实例,但将其存储在 BaseClass 引用中:
BaseClass baseRef = new InheritedClass();
baseRef.Method1();
baseRef.Method2();
通常,在 OOP 原则下,您应该期望与上述示例相同的输出。但是你没有得到相同的输出:
运行 InheritedClass 方法 1
运行 BaseClass 方法2
当您编写 InheritedClass 代码时,您可能希望所有调用都Method2()
运行您在其中编写的代码。通常,这就是它的工作方式 - 假设您正在使用virtual
已覆盖的方法。但是因为您使用的是new
/hidden 方法,所以它会调用您正在使用的引用上的版本。
如果那是您真正想要的行为,那么;你去吧。但我强烈建议,如果这是您想要的,代码可能存在更大的体系结构问题。