我搜索过但无法找到解决问题的方法。我的场景非常简单:
public class A
{
public virtual void MethodOne()
{
Console.log( "A" );
}
}
public class B : A
{
public override void MethodOne()
{
base.MethodOne();
Console.log( "B" );
}
}
public class C : B
{
public override void MethodOne()
{
base.MethodOne();
Console.log( "C" );
}
}
我想要做的是有一个C类实例(我们将它命名为'instanceC')调用其父级的重写方法及其祖父项。所以我期待这个:
instanceC.MethodOne();
// Output:
// "A"
// "B"
// "C"
但是我得到了这个:
instanceC.MethodOne();
// Output
// "A"
// "C"
跳过B类的方法。这不可能吗?我认为这是继承/多态的全部要点。提前谢谢!
答案 0 :(得分:11)
您的示例对我有效。我看到了A B C.我认为你最可能的问题是C不会扩展B.然而,在我们讨论这个问题时,让我建议一个可以说是更安全的模式。您似乎希望MethodOne的所有覆盖都从其基类执行代码。伟大的遗产是一个很好的模式。但是,使用此模式,您无法强制继承者执行基本逻辑,因为您无法强制它们调用base.MethodOne()
。即使他们确实调用了base.MethodOne()
,也无法确保逻辑的顺序。他们会在方法的开头,方法的中间或方法的结尾处调用base.MethodOne()
吗?通常,在这些类型的模式中,您希望子类在函数的开头执行所有基本逻辑。以下模式强制继承者在基类所期望的顺序中执行基本逻辑。它在技术上不那么灵活但更安全,因为继承者必须以基类指定的方式扩展基类。
public class A
{
//Don't make this method virtual because you don't actually want inheritors
//to be able to override this functionality. Instead, you want inheritors
//to be able to append to this functionality.
public void MethodOne()
{
Console.WriteLine( "A" );
MethodToBeOverriddenOne();
}
//Expose a place where inheritors can add extra functionality
protected virtual void MethodToBeOverriddenOne() { }
}
public class B : A
{
//Seal the method because you don't actually want inheritors
//to be able to override this functionality. Instead, you want inheritors
//to be able to append to this functionality.
protected sealed override void MethodToBeOverriddenOne()
{
Console.WriteLine("B");
MethodToBeOverriddenTwo();
}
//Expose a place where inheritors can add extra functionality
protected virtual void MethodToBeOverriddenTwo() { }
}
public class C : B
{
protected sealed override void MethodToBeOverriddenTwo()
{
Console.WriteLine("C");
}
}
答案 1 :(得分:1)
您发布的示例完美无缺,无论您在实际代码中执行的操作与您发布的内容有何不同。
Here is your code running on ideone完全像你想要的那样工作。
using System;
public class Test
{
public static void Main()
{
var c = new C();
c.MethodOne();
}
}
public class A
{
public virtual void MethodOne()
{
Console.WriteLine( "A" );
}
}
public class B : A
{
public override void MethodOne()
{
base.MethodOne();
Console.WriteLine( "B" );
}
}
public class C : B
{
public override void MethodOne()
{
base.MethodOne();
Console.WriteLine( "C" );
}
}