Kacy
Kacy

Reputation: 3430

How to implement inheritance without multiple instance variables referencing the same object?

I feel like I should only have to have one instance variable reference an object. But in the code below, I have 2 instance variables "_character" and "_witch" referencing the same object. If I add a more specialized witch class, I'd have to add a 3rd instance variable.
Is this typically what people do in this situation? Or is there a way to achieve this using only one reference? Also, I really don't want to have to cast anything (unless that really is the best practice in this scenario).

On top of the WitchAnimationController extending AnimationController, the WitchState extends CharacterState.

The base class:

public class AnimationController 
{
    protected CharacterState _character;

    public AnimationController( CharacterState character )
    {
        _character = character;
    }

    public void UpdateAnimations() 
    {
        /* call on some CharacterState functions... */
    }
}

The child class:

public class WitchAnimationController : AnimationController
{
    protected WitchState _witch; //inherits from CharacterState

    public AnimationController( WitchState witch ) : base( witch ) 
    {
        _witch = witch;
    }

    public void UpdateAnimations() 
    {
        base.UpdateAnimations();

        /* call on some WitchState functions... */
    }
}

Upvotes: 0

Views: 96

Answers (3)

Ondrej Tucny
Ondrej Tucny

Reputation: 27974

Use generics:

public class AnimationController<T> where T : CharacterState
{
    protected T _character;

    public AnimationController(CharacterState character)
    {
        _character = character;
    }
}

Then in each ancestor _character will be of the respective inherited type, like this:

public class WitchAnimationController : AnimationController<WitchState>
{        
    public AnimationController(WitchState witch) : base(witch) 
    {
    }
}

Upvotes: 2

Jon Skeet
Jon Skeet

Reputation: 1502406

If you don't need witch-specific calls, you can just ditch the _witch field and use the _character field - although I'd personally make it a private field with a protected property.

If you need character-specific members, you should consider making the animation controller generic:

public class AnimationController<T> where T : CharacterState
{
    protected T _character;

    public AnimationController(T character)
    {
        _character = character;
    }

    public void UpdateAnimations() 
    {
        /* call on some CharacterState functions... */
    }
}

Then:

public class WitchAnimationController : AnimationController<WitchState>
{    
    public WitchAnimationController(WitchState witch) : base(witch) 
    {}

    public void UpdateAnimations() 
    {
        base.UpdateAnimations();

        _character.SomeMethodOnWitchState();
    }
}

The _character.SomeMethodOnWitchState() call will be valid within WitchAnimationController because _character is effectively of type WitchState.

Upvotes: 8

BradleyDotNET
BradleyDotNET

Reputation: 61369

What you have isn't terrible, but consider this design instead:

public class AnimationController 
{
    public AnimationController(  )
    {
    }

    public void UpdateAnimations( CharacterState character ) 
    {
        /* call on some CharacterState functions... */
    }
}

public class WitchAnimationController : AnimationController
{   
    public AnimationController( )
    {
    }

    public void UpdateAnimations(WitchState witch ) 
    {
        base.UpdateAnimations(witch );

        /* call on some WitchState functions... */
    }
}

You could hold onto all the references, but if the controller is actually just calling functions, you can have some one else maintain the different state objects.

Either approach is equally valid, without more information (like other important members of AnimationController I would go with my approach.

Upvotes: 2

Related Questions