Reputation: 2852
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
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
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
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