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

时间:2015-01-04 18:12:23

标签: c# inheritance abstract-class

我正在尝试创建一个全面的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方法(在任何情况下,我都不想使用{{1}因为,例如,我不希望virtual使用DerivedClass'SecondDerivedClass方法。

  2. 我可以将它们标记为defineList,但之后我无法在abstract中放置“默认实现”,并且每个派生类都必须复制/实现这些默认值。此外,BaseClass类仍需要一种方法来“覆盖”SecondDerived的实现。

  3. 仅使用DerivedClass关键字“隐藏”较少派生类的方法不起作用。

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

    TLDR:根据我的评论如下: 如果newBaseClass类,方法为abstractA是来自DerivedClass的类(不一定是BaseClass的直接子级),然后在BaseClass'构造函数中调用A应该在继承层次结构中的每个类中调用BaseClass,直到并包括A()(但不能再进一步)。我们可以假设每个中间类都定义了DerivedClass(强制)。

3 个答案:

答案 0 :(得分:1)

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

    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()
        {
        }
        */
    }

答案 1 :(得分:1)

我认为你应该参考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();

答案 2 :(得分:0)

实现所需目标的一种方法是向基类添加显式Initialize方法并在那里执行初始化逻辑,例如:

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

    public BaseClass()
    {

    }

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