Brendan Hill
Brendan Hill

Reputation: 3752

Override abstract method, but keep method abstract?

I want to override an abstract method, but keep it abstract so derived classes are required to implement it themselves.

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" ...
    }
}    

In this code, ClientInvoicesComponentController is not required to implement CreateCustomColumns() because this is not allowed:

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"

So, how can I override CreateCustomColumns() in ClientComponentController, but still force it to be overridden again in derived classes like ClientInvoicesComponentController?

Of course it still CAN be overridden anyway, but there is nothing to indicate to the developer that it MUST be overridden... which is my aim.

-Brendan

Upvotes: 2

Views: 2124

Answers (2)

Ricky
Ricky

Reputation: 10771

In this case, I think it would be better to divide your logic into 2 methods, one method you play with and the other method your users play with. Assuming the "CreateCustomColumns" method is the name you want your users to override, you create another method, say "CreateCustomColumnsCore", for yourself. The classes may look like this:

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.
    }
}

Users can still override your CreateCustomColumnsCore method, this could be a feature or a bug based on if you can permit users to do this.

Upvotes: 2

Jan Dörrenhaus
Jan Dörrenhaus

Reputation: 6717

In a word: Not.

A method being abstract means that it is declared but not defined. Being defined but abstract does not really make sense in this context, so it is not possible.

I would also very much like to know your use case. If there is some behaviour you want subclasses to inherit, but also add their own functionality, you could so something like this:

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.
    }
}

Upvotes: 4

Related Questions