重写嵌套的类函数还是使用委托?
本文关键字:嵌套 类函数 重写 | 更新日期: 2023-09-27 17:52:38
我有一个base class
,里面有一个嵌套类型。外层(基本)类型中有一个函数,稍后将被它的子类型覆盖。事实上,从OO
的角度来看,这个函数属于inner type
,但我仍然需要它,被base class
的subtypes
覆盖。
我应该使用这个函数作为inner type
的callback
,还是只是把它移动到inner type
里面,让我们的subtypes
从那里重写它?
EDIT:添加示例代码
class A
{
protected void func() { /* do something */ }
class B { /**/ }
}
// OR
class A
{
class B
{
protected void func() { /* do something */ }
}
}
// Then
class C : A
{
override func() { /**/ }
}
我的建议是为内部类型函数创建一个委托,该函数由基类的构造函数初始化:
internal class BaseClass
{
public BaseClass(Action myAction)
{
this.innerType = new InnerType(myAction);
}
public BaseClass()
{
// When no function delegate is supplied, InnerType should default to
// using its own implementation of the specific function
this.innerType = new InnerType();
}
}
如您所见,派生类型可以使用:base (overridenAction)
调用基构造函数,在那里它们可以提供自己对最内层类型的函数实现。当然,你没有义务使用Action
,但任何你想要的委托。
在我看来,你所描述的看起来像是战略设计模式。考虑使用这种模式。您的代码将更易于维护,因为它包含了易于识别的模式。你也可以看看状态设计模式,通常你必须在这两者之间做出选择,它们是紧密相连的。
在这个场景中:
class A
{
class B
{
protected void func() { // do something }
}
}
不能从A
类派生并在B
类中重写func()
。
从你的描述看来,a派生类应该能够在内部类B
中覆盖一些函数(或功能),这表明你可能应该重新考虑你的设计。要么提取B
,不让它成为一个内部类,要么让你想要的功能通过这样的接口覆盖显式依赖:
class A
{
private B _MyB;
public A(ISomeBehaviour behaviour)
{
_MyB = new B(behaviour);
}
}
无论如何,如果你想坚持你的设计,那么我不建议使用委托方法,而是选择重写,因为使用委托,如果在子类中只需要添加装饰,则更难添加。
这就是外部类如何作为内部服务类的策略。
注意,不建议使用TemplateMethod
和Strategy
这样的模式名作为真正的类名,使用在域中有意义的名称。同样适用于Outer
和Inner
。
public class Consumer
{
public void Foo()
{
IOuterFoo fooService = new Derived();
fooService.OuterFoo();
}
}
// ...
public interface IOuterFoo
{
void OuterFoo();
}
abstract class Base : Base.IStrategy, IOuterFoo
{
public void OuterFoo() { _service.Foo(); }
private readonly InnerService _service;
protected Base() { _service = new InnerService(this); }
private interface IStrategy { void Foo(); }
private class InnerService
{
private readonly IStrategy _strategy;
public InnerService(IStrategy strategy) { _strategy = strategy; }
public void Foo() { _strategy.Foo(); }
}
void IStrategy.Foo() { TemplateMethodFoo(); }
protected abstract void TemplateMethodFoo();
}
class Derived : Base
{
protected override void TemplateMethodFoo()
{
throw new NotImplementedException();
}
}