覆盖抽象方法,但保持方法抽象?

时间:2013-09-09 01:14:01

标签: c# oop override abstract

我想覆盖一个抽象方法,但要保持抽象,因此需要派生类来实现它。

public abstract class ComponentController
{
    public abstract void CreateCustomColumns();
}

public abstract class ClientComponentController : ComponentController
{
    public override void CreateCustomColumns()
    {
        // All grids to do with clients should show these columns.
        Grid.AddColumn("Client" ...
        Grid.AddColumn("ClientLocation" ...
        Grid.AddColumn("ClientPhoto" ...
    }
}

public class ClientInvoicesComponentController : ClientComponentController
{
    public override void CreateCustomColumns()
    {
        base.CreateCustomColumns();
        // On top of the generic columns, I also want to show these.
        Grid.AddColumn("InvoiceNumber" ...
        Grid.AddColumn("InvoiceDate" ...
    }
}

public class ClientCommunicationsComponentController : ClientComponentController
{
    public override void CreateCustomColumns()
    {
        base.CreateCustomColumns();
        // On top of the generic columns, I also want to show these.
        Grid.AddColumn("CommunicationDate" ...
        Grid.AddColumn("CommunicationType" ...
    }
}    

在此代码中,ClientInvoicesComponentController不需要实现CreateCustomColumns(),因为这是不允许的:

public abstract class ClientComponentController : ComponentController
{
    public abstract override void CreateCustomColumns()
    {
        Grid.AddColumn("Client" ...
        Grid.AddColumn("ClientLocation" ...
        Grid.AddColumn("ClientPhoto" ...
    }
}

--> "Abstract method cannot declare a body"

那么,如何在ClientComponentController中覆盖CreateCustomColumns(),但是仍然强制它在ClientInvoicesComponentController等派生类中再次被覆盖?

当然它仍然可以被覆盖,但没有任何迹象表明开发者必须覆盖它......这是我的目标。

-Brendan

2 个答案:

答案 0 :(得分:3)

总之:不是。

抽象方法意味着它已声明但未定义。在这种情况下,被定义但是抽象并没有真正意义,所以这是不可能的。

我也非常想知道你的用例。如果您希望子类继承某些行为,但也添加了自己的功能,那么您可以这样:

public abstract class BaseClass
{
    public void DoSomething()
    {
        // Base class behaviour goes here.
        DoSomethingInternal();
    }

    protected abstract void DoSomethingInternal();
}

public class SubClass : BaseClass
{
    protected override void DoSomethingInternal()
    {
        // Sub class behaviour goes here.
    }
}

答案 1 :(得分:1)

在这种情况下,我认为最好将您的逻辑分为两种方法,一种是您使用的方法,另一种是您的用户使用的方法。假设“CreateCustomColumns”方法是您希望用户覆盖的名称,则为自己创建另一个方法,例如“CreateCustomColumnsCore”。这些课程可能如下所示:

public abstract class ComponentController
{
    protected abstract void CreateCustomColumnsCore();
}

public abstract class ClientComponentController : ComponentController
{
    protected override void CreateCustomColumnsCore()
    {
        // your code here

        CreateCustomColumns();  // call users' implementation
    }

    public abstract void CreateCustomColumns();
}

public class ClientInvoicesComponentController: ClientComponentController
{
    public override void CreateCustomColumns()
    {
        // user must implement this method.
    }
}

用户仍然可以覆盖您的CreateCustomColumnsCore方法,如果您允许用户执行此操作,这可能是一项功能或错误。