Home > other >  Is there a way to pull specific child class from a parent class object variable?
Is there a way to pull specific child class from a parent class object variable?

Time:12-06

I have a Room class which holds a Mob object. A Mob object can either be of type Passive or of type Hostile and each have their own specific behavior. These Mob objects will move around from Room to Room. If a Player tries to fight one of them, I need a way to call the specific behavior of the Mob's actual type. As in, Passive will try to evade while Hostile will try to fight back. Is there a way to do this without casting?

public class Room {
    private Mob mob;
    public Mob Mob { get; set; }
}

public abstract class Mob {
    protected Room room;
}

public class Passive : Mob {
    // Some passive-specific code
    public void Run() { }
    public void SayGreeting() { }
    public void SayGoodbye() { }
}

public class Hostile : Mob {
    // Some hostile-specific code
    public void Fight() { }
    public void SayOnLose() { }
    public void SayOnWin() { }
}

I know (Passive)myRoom.Mob and (Hostile)myRoom.Mob can do the trick but I'm wondering if there is a better option. Thanks.

CodePudding user response:

You should make use of inheritance and polymorphism. One option would be declare a method for the default action in the base class, then override that and implement it appropriately in each base class, e.g.

public abstract class Mob
{
    protected Room room;

    public abstract void PerformDefaultAction();
}

public class Passive : Mob
{
    // Some passive-specific code
    public void Run() { }

    public override void PerformDefaultAction()
    {
        Run();
    }
}

public class Hostile : Mob
{
    // Some hostile-specific code
    public void Fight() { }

    public override void PerformDefaultAction()
    {
        Fight();
    }
}

Now you can just call PerformDefaultAction on each Mob reference and it will behave appropriately based on its run-time type without you having to know what that is.

You don't even necessarily need the Run and Fight methods any more, as you can just put the type-specific code in the PerformDefaultAction method. There may be a reason that you want to keep them though.

CodePudding user response:

you can use like this


var room = new Room();
if (room.Mob is Passive) // validate if mob is passive type
{
var passive = room.Mob as Passive; // cast mob to passive type
//perform passive related operation
}
else
{
var hostile = room.Mob as Hostile; // cast mob to hostile type
//perform hostile related operation
}
  • Related