簡體   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