Lex Webb
Lex Webb

Reputation: 2852

Is there a way of allowing sub classes to override only -some- parents abstracts methods

I understand that the title may not make sense, but the below should explain my predicament.

So I'm making a user interface for my MonoGame game. I have an abstract class Clickable which contains some basic methods that are called when certain actions happen (And a few other things i have left out for clarity's sake):

abstract public class Clickable
{
    public abstract void OnClick(Vector2 pos, MouseButton button);

    public abstract void OnHover(Vector2 pos);

    public abstract void OnUnHover(Vector2 pos);

    public abstract void OnHold(Vector2 pos, MouseButton button);

    public abstract void OnRelease(Vector2 pos, MouseButton button);
}

Each of these methods can be called by my ControlManager, which cycles through a list of Clickable's to see if any of the above methods currently apply.

I then have a class which inherits from Clickable called Control (again stripped down):

abstract public class Control : Clickable
{
    public abstract void DrawBackground(SpriteBatch sb, GameTime gt);

    public abstract void DrawMiddleground(SpriteBatch sb, GameTime gt);

    public abstract void DrawForeground(SpriteBatch sb, GameTime gt);
}

So, my user controls inherit from this. My issue is, is that in order to have a compile-able class, i HAVE to to override all of these abstract methods.

Take the not-finished TextBox class:

class TextBox : Control
{
    Typeable typeable;

    public TextBox(Vector2 position, int width, int height, string text, SpriteFont font, Control alignedTo, Dictionary<String, Texture2D> images) :
        base(position, width, height, alignedTo, images)
    {
        typeable = new Typeable(text, font, position);
    }

    public override void OnClick(Vector2 position, MouseButton button)
    {
        //Cursor functions will go here
    }

    public override void OnHold(Vector2 pos, MouseButton button)
    {

    }

    public override void OnHover(Vector2 pos)
    {

    }

    public override void OnRelease(Vector2 pos, MouseButton button)
    {

    }

    public override void OnUnHover(Vector2 pos)
    {

    }

    public override void DrawBackground(SpriteBatch sb, GameTime gt)
    {

    }

    public override void DrawMiddleground(SpriteBatch sb, GameTime gt)
    {
        //draw textbox background
    }

    public override void DrawForeground(SpriteBatch sb, GameTime gt)
    {
        //draw textbox text
    }
}

As you can see, (where the comments are), i will only be using some of the methods that i am forced to declare.

Is there a way that i can have the base methods in my abstract classes and not have to override, (just have the option to)? Bare in mind a class like TextBox that will not implement the OnHold method, will still have it called by the ControlManager if a user holds the mouse button down on the control.

Upvotes: 2

Views: 89

Answers (3)

CodeCaster
CodeCaster

Reputation: 151584

Is there a way that i can have the base methods in my abstract classes and not have to override, (just have the option to)?

No.

Bear in mind a class like TextBox that will not implement the OnHold method, will still have it called by the ControlManager if a user holds the mouse button down on the control.

You want to have too much in your base class. Not all controls are clickable, so the click methods should not be in the base class. What you seem to be needing is multiple inheritance.

You can do this using interfaces:

public class Button: Control, IClickable[, IScrollable[, I...]]
{
    public void OnClick(Vector2 position, MouseButton button)
    {
        // implements IClickable 
    }    
}

You won't have to repeat much code between controls able to receive clicks, as you can also put the click handling methods in an IClickHandler and let that be implemented by a basic event handler.

Upvotes: 3

Yuval Itzchakov
Yuval Itzchakov

Reputation: 149538

If there are methods which aren't 100% necassery, you can have them marked as virtual and provide a basic implementation, which might even be just an empty method. That way, you cab still override where they are deseriable, and where they're not they can just use the "base" implementation. You absolutely cannot not implement an abstract method.

Upvotes: 1

BradleyDotNET
BradleyDotNET

Reputation: 61349

In the end, the answer to your question is no. For a class to be instantiated (instantiatable?), it has to override every abstract method (or inherit from a class that implements the methods it doesn not implement).

To make this "optional" just mark them as virtual instead of abstract, and provide the default (empty) implementation in the base class. Only use abstract when you actually want all derived classes to implement the method.

A method marked virtual must have an implementation, even if its empty:

public virtual void MyFunc()
{
}

Is valid. This will be called unless the derived object has:

public override void MyFunc()
{
   //Some implementation
}

Basically, You can't have method declarations without a method body somewhere in C#.

Upvotes: 4

Related Questions