前面的解决方案忽略的一件事是 ImplementClass 可以重新定义 MethodToBeCalled 而不是调用 MustBeCalled -
public abstract class AbstractClass
{
public abstract void AbstractMethod();
private void MustBeCalled()
{
//will be invoked by MethodToBeCalled();
Console.WriteLine("AbstractClass.MustBeCalled");
}
public void MethodToBeCalled()
{
MustBeCalled();
AbstractMethod();
}
}
public class ImplementClass : AbstractClass
{
public override void AbstractMethod()
{
Console.WriteLine("ImplementClass.InternalAbstractMethod");
}
public new void MethodToBeCalled() {
AbstractMethod();
}
}
如果只有 C# 允许密封未覆盖的方法 - 就像 Java 的 final 关键字!
我能想到的解决这个问题的唯一方法是使用委托而不是继承,因为类可以定义为密封的。而且我正在使用命名空间和“内部”访问修饰符来防止在实现类上提供新的实现。此外,要覆盖的方法必须定义为受保护的,否则用户可以直接调用它。
namespace Something
{
public sealed class OuterClass
{
private AbstractInnerClass inner;
public OuterClass(AbstractInnerClass inner)
{
this.inner = inner;
}
public void MethodToBeCalled()
{
MustBeCalled();
inner.CalledByOuter();
}
public void MustBeCalled()
{
//this must be called when AbstractMethod is invoked
System.Console.WriteLine("OuterClass.MustBeCalled");
}
}
public abstract class AbstractInnerClass
{
internal void CalledByOuter()
{
AbstractMethod();
}
protected abstract void AbstractMethod();
}
}
public class ImplementInnerClass : Something.AbstractInnerClass
{
protected override void AbstractMethod()
{
//when called, base.MustBeCalled() must be called.
//how can i enforce this?
System.Console.WriteLine("ImplementInnerClass.AbstractMethod");
}
public new void CalledByOuter()
{
System.Console.WriteLine("doesn't work");
}
}