【发布时间】:2014-01-10 03:28:14
【问题描述】:
我对方法覆盖和 OOP 原则的有效性有点困惑。 我知道关于密封、阴影、覆盖、虚拟等的一切,但我遇到了一个场景,这让我很困惑。假设我有:
class classA
{
public virtual void sayhello()
{
Console.WriteLine("hello I'm A");
}
};
class classB :classA
{
public override void sayhello()
{
Console.WriteLine("hello I'm B");
}
};
class Program
{
static void Main(string[] args)
{
classB a = new classB();
a.sayhello();
}
}
根据我目前研究的所有内容,可以使用 override 关键字覆盖声明为 virtual 或 abstract(在抽象类中)的方法在儿童班。据此,上面的代码完美无缺。 当我删除 virtual 关键字,然后尝试使用 override 关键字覆盖该方法时,编译器会给出错误:
无法覆盖继承的成员“inheritence.classA.sayhello()”,因为它没有标记为虚拟、抽象或覆盖
然后我从子类中删除了 override 关键字,并将实现提供为:
class classB :classA
{
public void sayhello()
{
Console.WriteLine("hello I'm B");
}
};
在这种情况下,可以覆盖该方法。我能够覆盖该方法,它不是虚拟的或抽象的。所以,我的问题是:
1. 不违反OOP原则吗?因为我能够覆盖该方法,该方法在父级中未标记为 virtual。
2. 为什么允许我以这种方式覆盖该方法?哪个甚至没有标记为virtual?
3.从classA方法中去掉virtual关键字,它给了我密封方法在classA,当我试图在 classB 中覆盖该方法时。 (正如我之前提到的编译器错误)。如果我删除了 virtual,这样子类就不会覆盖它,那么为什么子类可以巧妙地覆盖它,删除它的 override 关键字?是否只有这种情况,密封关键字是为设计的?
【问题讨论】:
-
你执行了一个叫做方法隐藏的概念msdn.microsoft.com/en-us/library/aa691135%28v=vs.71%29.aspx
-
是的,但这不是违反 oop 原则吗?比方说,classA 不想让它的方法被隐藏?或者当我们可以简单地隐藏它时,为什么我们然后使用 new 关键字进行阴影?
-
@O.R.Mapper 是的。因为 OP 的实例类型为
classB -
在最后一种情况下,您应该看到一条警告,指出您在
classB中引入的方法隐藏了classA中的方法。这不是压倒一切的。它只是两个不相关的同名方法。避免这种情况;这会导致混乱。 -
@JeppeStigNielsen 是的,我注意到警告:) 无论如何,我可以确定,子类不会这样做?
标签: c# oop virtual-functions overriding sealed