objective-ciosinheritancesubclassivars

Changing the class of an ivar (to a derived class), in a subclass


Assume I have two base classes, Container and Gizmo. Class Container has an instance variable of class Gizmo.

Now I subclass Container (call that SubContainer) and I also subclass Gizmo (SubGizmo). In some of the methods of SubContainer I need to send a message to some properties that Gizmo doesn't have but SubGizmo does. Is there any way to override the ivar to be of class SubGizmo in SubContainer, so I can send those messages?

Right now I can make it work by casting my inherited ivar to SubGizmo every time I need to use such a property or method.

Here is why I want such a behavior: I already have a game that works, but the more modes I add, the harder it gets to maintain. If I want to change/add a method that will run on each mode; I would need to go to three different game - controller objects and make the change.

By subclassing, I wanted to keep the main game mechanics in the base classes and create a subclass for each mode. this way a change I make in a base class would reflect on each mode. However each controller and game object have new methods for different modes, and they send messages to each other. This is where my problem is arising from.


Solution

  • just introduce type safety and conversion logic using an approach like this:

    @interface SubContainer ()
    
    - (SubGizmo *)subGizmo;
    // setter is often unnecessary
    - (void)setSubGizmo:(SubGizmo *)pSubGizmo;
    
    @end
    
    @implementation SubContainer
    
    ...
    
    - (SubGizmo *)subGizmo
    {
        Gizmo * ret = self.gizmo;
        // sanity check the type to ensure this is properly initialized,
        // or return nil if holding a Gizmo is valid in this context:
        assert([ret isKindOfClass:[SubGizmo class]]);
        return (SubGizmo *)ret;
    }
    
    - (void)setSubGizmo:(SubGizmo *)pSubGizmo
    {
        self.gizmo = pSubGizmo;
    }
    
    - (void)addWater
    {
      [self.subGizmo addWater];
    }
    
    @end
    

    however, the creeping complexity suggests more variations in types is worth consideration.