繁体   English   中英

在派生类中定义基类构造函数方法

[英]Define base class constructor methods in derived classes

我正在尝试创建一个全面的abstract BaseClass ,它定义了创建所有派生类的方式,但允许派生类专门化/聚集了创建过程中使用的字段和方法。 这是一个简化的示例:

public abstract class BaseClass
{
    public List<String> list;

    public BaseClass()
    {
        defineList();
        optionalDoSomething();
        doSomething();
    }

    protected void defineList()
    {
        list = new List<String>();
    }

    protected void doSomething()
    {
        // do something w/ list here
    }

    protected void optionalDoSomething() {}
}

public class DerivedClass : BaseClass
{
    protected void defineList()
    {
        base.defineList();
        list.Add("something");
    }

    public DerivedClass() : base() { }
}

public class SecondDerivedClass : DerivedClass
{
    protected void defineList()
    {
        base.defineList();
        list.Add("somethingElse");
    }

    protected void optionalDoSomething()
    {
        // do something special
    }

    public SecondDerivedClass() : base() { }
}

这将使所有派生类都不必重新创建相同的初始化逻辑,并且每个派生类将只需要“覆盖”创建过程中使用的必要字段和方法(可能还需要覆盖类中的其他位置)。

问题:

  1. 我不能标记BaseClass “方法为virtual ,因为你不能叫virtual的基类的构造方法(在任何情况下,我不会想用virtual方法,因为,例如,我不希望DerivedClass使用SecondDerivedClassdefineList方法)。

  2. 我可以将它们标记为abstract ,但是这样我将无法在BaseClass放置“默认实现”,并且每个派生类都必须复制/实现这些默认值。 同样, SecondDerived类仍将需要一种方法来“重写” DerivedClass的实现。

  3. 简单地使用new关键字“隐藏”较少派生类的方法是行不通的。

获得此模式的正确方法是什么?

TLDR:按我下面的评论:如果BaseClass是一个abstract与方法类A ,和DerivedClass是派生的类BaseClass (不一定是直接孩子BaseClass ),然后调用ABaseClass “构造函数应该调用A()在每一个继承层次结构中的class直到DerivedClass (包括DerivedClass (但不包括)。 我们可以假设在每个中间类上都定义了A (强制为)。

尝试使用此解决方案,该实现是使用受保护的虚拟方法实现的,因此从外部看不到它,并且在派生类中也不是必需的:

    public abstract class BaseClass
    {
        public List<String> List { get; protected set; }

        protected BaseClass()
        {
            defineList();
            optionalDoSomething();
            doSomething();
        }

        protected void defineList()
        {
            // default implementation here
            List = new List<String>();

            internalDefineList();
        }

        protected void doSomething()
        {
            // default implementation here
            internalDoSomething();
        }

        protected void optionalDoSomething()
        {
            // default implementation here
            internalOptionalSomething();
        }

        protected virtual void internalDefineList()
        {
        }

        protected virtual void internalDoSomething()
        {
        }

        protected virtual void internalOptionalSomething()
        {
        }
    }

    public class DerivedClass : BaseClass
    {
        protected override void internalDefineList()
        {
            var list = List;
        }

        protected override void internalDoSomething()
        {
        }

        // this method is not required
        /*          
        protected override void internalOptionalSomething()
        {
        }
        */
    }

我认为您应该参考template-method-design-pattern

在操作中定义算法的框架,将某些步骤推迟到子类。 模板方法允许子类重新定义算法的某些步骤,而无需更改算法的结构。

你可以尝试类似的东西

abstract class AbstractClass
  {
    public List<String> list;
    public abstract void PrimitiveOperation1();

    public void TemplateMethod()
    {
      //initialize code that each class should perform
      PrimitiveOperation1();
    }
  }

class DerivedClass: AbstractClass
  {
    public override void PrimitiveOperation1()
    {
      list.Add("something");
    }
  }

用法

AbstractClass abstractClass1 = new DerivedClass();
abstractClass1.TemplateMethod();

一种实现所需目标的方法是在基类中添加一个显式的Initialize方法,并在其中进行初始化逻辑,例如:

public abstract class BaseClass
{
    public List<String> list;

    public BaseClass()
    {

    }

    public void Initialize()
    {
        defineList();
        optionalDoSomething();
        doSomething();
    }
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM