我希望能够按照派生的顺序调用重写的方法。
例如,在以下代码中,我创建了一个名为CallMeThird的新类,当调用其CallMe
方法时,我希望它按继承顺序执行基类CallMe
方法:
- 调用MeFirst
- CallMeSecond
- CallMeThird
不过有几件事我想避免:
- 在派生类中调用
base.CallMe
- 使用
OnCallMeFirst
和OnCallMeSecond
作为CallMe
仍然暴露在派生类中,并且代码可能会变得混乱
有没有一个漂亮、干净的模式可以用于这种情况?
using System;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
Base b = new CallMeThird();
b.CallMe();
while (Console.ReadKey().Key != ConsoleKey.Escape)
{
}
}
}
public abstract class Base
{
public abstract void CallMe();
}
public class CallMeFirst : Base
{
public override void CallMe()
{
Console.WriteLine("I would like to be called first");
}
}
public class CallMeSecond : CallMeFirst
{
public override void CallMe()
{
Console.WriteLine("I would like to be called second");
}
}
public class CallMeThird : CallMeSecond
{
public override void CallMe()
{
Console.WriteLine("I would like to be called third");
}
}
}
将base.CallMe();
添加到每个重写中,这样它将链接您的继承层次结构。
你可以随心所欲地避免它,但这是解决方案。重写意味着替换,如果你想使用父类实现,你最好称之为
然而,我认为这里没有继承的必要。如果CallMeThird只使用CallMeSecond(等等),而不需要与之互换,我更喜欢composition。这意味着CallMeThird将包含CallMeSecond并返回对其CallMe方法的调用。然而,这个例子是为了了解您的问题是组合问题还是继承问题。
正如Nathan所指出的,通过base
进行调用的能力是专门为实现这一点而存在的,这可能是实现您想要的目标的最简单、最干净、最高效、最稳定的方法。因此,我建议不要回避专门为解决您的问题而存在的功能,除非您有要求这样做。
然而,如果你绝对确定出于任何原因都想避免这种情况,这里有一个可能的替代方案:
- 避免多态性(使这些方法成为非虚拟方法)
- 定义自定义属性
- 用该属性装饰每个类中所需的方法
- 在基类中的方法中,使用反射来构建继承链(从基类到对象的实际类)
- 对于链中的每种类型,选择用属性装饰的方法
- 对于生成的方法序列,按所需顺序调用每个方法
考虑Template方法以避免使用多重继承。