Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Derived classes of abstract class in an Array

Good day everyone.

I have a question about making and using derived classes of some base abstract class.

I can't quite understand how it works.

My goal: Make a basic class that will define what functions there should be, and then create different derived classes. Then to make an array of base class and instantiate in it different derived classes.

For example:

abstract class UIElement
{
    //constructor
    abstract public UIElement();
    //draw element
    abstract public void Draw(int mouseX, int mouseY);
    //checks if the element is pointed at by mouse
    abstract public Boolean IsPointed(int mouseX, int mouseY);
    //defines what happens when clicked
    abstract public void Click(int mouseX, int mouseY);
    //destructor
    abstract public ~UIElement();
}

Then create several derived classes and do like that:

UIElement[] qwe = new UIElement[3];
qwe[0] = new UIElementButton();
qwe[1] = new UIElementLabel();
qwe[2] = new UIElementSomethingElse();

1) What is the proper way to do it, because I can't find a definitive answer or an article that would explain it...

2) About class variables, where they should be declared: base class or derived?

3) What if different derived classes have different variables, how that should be addressed?

4) Can derived classes have different constructor including different arguments?

like image 309
NewProger Avatar asked Dec 30 '25 16:12

NewProger


1 Answers

In comments below, questionner is looking for advice on best practices for writing inheritence hierachies with abstract classes

From a general best-practices and correctness point of view, you ought to declare your UIElement base class without abstract on the constructor and without a finalizer. e.g.

public abstract class UIElement
{
    //constructor
    protected UIElement();
    //draw element
    public abstract void Draw(int mouseX, int mouseY);
    //checks if the element is pointed at by mouse
    public abstract bool IsPointed(int mouseX, int mouseY);
    //defines what happens when clicked
    public abstract void Click(int mouseX, int mouseY);
}

You could then implement derived classes as follows

public class UIElementButton : UIElement
{
    // Optional - create parameterless constructor and
    // explicitly call base constructor
    public UIElementButton() : base()
    {
    } 

    // Mandatory - must override abstract methods
    public override Draw(int mouseX, int mouseY)
    {
    }

    // Mandatory - must override abstract methods
    public override Boolean IsPointed(int mouseX, int mouseY)
    {
    }

    // Mandatory - must override abstract methods
    public override void Click(int mouseX, int mouseY)
    {
    }
}

You are correct that if you define derived classes as per the above, you could instantiate elements and store in an array of the base type as follows:

UIElement[] qwe = new UIElement[3]; 
qwe[0] = new UIElementButton(); 
qwe[1] = new UIElementLabel(); 
qwe[2] = new UIElementSomethingElse(); 

qwe[0].Click(1, 2); // Invokes UIElementButton.Click
qwe[1].Draw(3, 4);  // Invokes UIElementLabel.Draw

You should also be aware there is a UIElement class defined in WPF. This won't be a problem if you define a namespace for your type, but perhaps consider a more explicit type name such as BaseElement to distinguish your custom type.


Regarding your queries in comments:

For further advice on usage of abstract classes, please see All about abstract classes - Codeproject. - Where should class variables be declared: base class or derived? - What if different derived classes have different variables, how that should be addressed? - Can derived classes have different constructor including different arguments?

These are really the topic for different questions or own research on google, however as a starter I can say:

  1. Class variables should be declared in the scope where they are needed. Meaning if you have a variable Guid _uiElementId and want it to be accessed by derived types, it should be declared in the base class and marked as protected. If you have a variable in UIElementButton called Point _mousePoint and only UIElement button needs it, leave it in there and mark as private

  2. That's fine - any type can see its own private variables and protected variables from base classes. Just make sure names don't clash

  3. Yes they can, for instance.


 public class UIElementButton : UIElement    
 {    
    private string _buttonText; 

    // Overloaded ctor
    public UIElementButton(string buttonText) : base()
    {
        buttonText = buttonText;
    } 

    // Default constructor. Mark as private or protected 
    // to hide from external API
    public UIElementButton() : base()
    {
    } 
}

Best regards,

like image 101
Dr. Andrew Burnett-Thompson Avatar answered Jan 02 '26 06:01

Dr. Andrew Burnett-Thompson



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!