Resolving SubClass instances from an array of their SuperClass

While trying to get my head wrapped around subclassing, I came across a solution that seems to work for handling an array of SuperClass. I was experimenting with passing parameters, but for simplicity sake, assume no parameters need be used. Is this a hazardous approach or just OOP 101? Is there a more “natural” way to approach this?

Looks similar to this question: custom superclass array?

There is an example attached.

I have SubClasses of one SuperClass.
SuperClass → Box
SubClass BoxA of Box
SubClass BoxB of Box and so on
Instances of the SubClasses are referenced in an array of type SuperClass.

The SubClasses all have a method with the same name, but different code.
The SuperClass needs a method of the same name to avoid an error, but any code in it gets ignored.

Rather than sprinkle this kind of code throughout the App…

Select Case True
Case mBox IsA BoxA
  var newBox As BoxA
  newBox=BoxA(mBox)
  newBox.AddToContent(1)

Case mBox IsA BoxB
  Var newBox As BoxB
  newBox=BoxB(mBox)
  newBox.AddToContent

’ …
End Select

…this more compact code can be used instead:

Var bBox As Box
bBox=Resolve_BoxType(mBox)
bBox.AddToContent(1)

The Resolve_BoxType code looks like this:

Var newBox As Box
Select Case True
  Case inBox IsA BoxA
    newBox=BoxA(inBox)
  Case inBox IsA BoxB
    newBox=BoxB(inBox)
End Select
Return newBox

Box.zip (7.8 KB)

(The concern I have is that the Resolve_BoxType method is set up to return a Box, but it actually returns a subclass of Box.)

You do not need to know or resolve the subclass, Xojo will do this for you.

In your example, you need only call the instance’s AddToContent method. If the subclass has implemented that, it will be called. If it hasn’t, its superclass’s version will be called. If the subclass needs to send it up the chain, it can call Super.AddToContent.

It doesn’t matter how many levels of subclass you are working with either. Let’s say your have

  • Box
  • BoxA of type Box that implements the function
  • BoxB of type BoxA that doesn’t
  • BoxC of the BoxB that does.

If you have an instance of BoxC and call AddToContent, its version will be called. If you have an instance of BoxB, BoxA’s version will be called.

The Resolve_BoxType method isn’t needed. You can call the AddToContent method on the superclass, and if the instance is actually a subclass then the subclass’s version is automatically used:

For Each mBox As Box In BoxArray
  mBox.AddToContent(1) ' will call subclass versions as appropriate
Next

The alternative to this is to implement an event in Box like DoAddContent. Calling MyBox.AddToContent will call RaiseEvent DoAddContent, and a subclass can choose to implement this or not. If the subclass needs to send it down the chain, you would have to do the same in that subclass.

I like this approach better because Xojo shows me the events I can implement as opposed to having to remember which methods I need to override.

But whatever suits you better.

1 Like

Thanks all!
I took a long path to arrive at this solution because I did not add the method to the SuperClass in the earlier attempts, and stayed sidetracked until I finally did add it.

I’ve replaced the function that I created and will take a look at the RaiseEvent approach, too.