Search code examples
c#genericsinheritancestaticpolymorphism

Static Inheritance Alternative?


I'm trying to make a generic 'string to command' method in each of my animal's classes that I can call to make them do things. I can think of a hundred work arounds, but none seem... good. They feel like volatile code.

So I have multiple classes which all inherit from the base class. Each of these subclasses needs to have an 'Interpret()' static method(But you can't/shouldn't do this in C#).

So here's what I wanted to do:

abstract class Action {
}

class Roar : Action {
    public void DoTheRoar() { /* Make the beast roar */ }
}
class Clap : Action {
    public void ClapFinsTogether() { /* Make the animal clap its fins */ }
}
class Jump : Action {
    public void Jump() { /* Epic jump animation */ }
}


abstract class Animal {
    public Action[] actionsToPerform;
    
    public static abstract bool InterpretCommand(string commandFromCircusPerformer, out Action outAction);
}

class Bear : Animal {
    public static override bool InterpretCommand(string commandFromCircusPerformer, out Action outAction){

        //if command is "Roar" then output roar action

        if(commandFromCircusPerformer=="Roar") {
             outAction = new Roar();
        } else {
             outAction = null;
        }

        return outAction != null;
    }
}
class Seal : Animal {
    public static override bool InterpretCommand(string commandFromCircusPerformer, out Action outAction){

        //if command is "Clap" output a clap action

        if(commandFromCircusPerformer == "Jump") {
            outAction = new Jump();
        } else if (commandFromCircusPerformer == "Clap") {
            outAction = new Clap();
        } else {
            outAction = null;
        }

        return outAction != null;
    }
}

Anyone got any ideas on how to accomplish what I'm trying to do correctly? I'd prefer to have a static method that I can refer to from each animal's individual class. Any ideas? I've seen people do use generics to create instances of objects, but that doesn't accomplish what I want(Unless I'm doing it wrong). This is the post i'm refering to: What's the correct alternative to static method inheritance?

--Edit--

I forgot critical information. Each animal has a unique ability or action. The reason I want a static virtual/abstract method is to be able to iterate over every subclass and ask it if it can do this action. For example (In poorly written psuedo code) "Can bears fly?... No...(next)... Can dogs fly?... No... (next)... Hey bird, can you fly?... Yes...[Success, Select Bird and perform Bird Actions]"

After doing some more research and after reading a few replies and comments, I think my code's structure is the problem. I'm ganna try to start from scratch(It's only like 300 lines of code) and see if I can add dictionary of actions or something.

P.S. I want this 'Generic' ability so that I can add creatures in the future by simply creating a subclass of 'Animal' and defining it's custom actions


Solution

  • Welp, I found a simple work around that works for my application. Though the downside is that the compiler doesn't let you know that the method needs to be 'overriden'.

    So static abstract and static virtual don't work in C#(as far as I know), but I still want the ability to call any subclass of my parent class and call InterpretCommand() and each subclass be able to individually handle the interpretation. We do this by simply adding the new prefix to the methods.

    Something like this:

    //The parent class for the actions
    public abstract class animalAction {
        public abstract void DoAnimalAction();
    }
    public class Jump : animalAction {
        public override void DoAnimalAction() {
            /* Activate cool jump animation */
        }
    }
    public class Roar : animalAction {
        public override void DoAnimalAction() {
            /* Activate roar animation */
        }
    }
    public class Clap : animalAction {
        public override void DoAnimalAction() {
            /* Do the seals clapping animation */
        }
    }
    
    //The parent class for all animals
    public class Animal {
        //This is the command that all Animal subclasses will call
        public static animalAction InterpretCommand(string inCommand) {
            throw new System.NotImplementedException();
        }
    }
    public class Bear : Animal {
        //The 'new' keyword here hides 'Animal.InterpretCommand()'
        new public static animalAction InterpretCommand(string inCommand) {
            if (inCommand == "Roar") {
                return new Roar();
            }
            else {
                return null;
            }
        }
    }
    public class Seal : Animal {
        //The 'new' keyword here hides 'Animal.InterpretCommand()'
        new public static animalAction InterpretCommand(string inCommand) {
            if(inCommand == "Jump") {
                return new Jump();
            } else if (inCommand == "Clap") {
                return new Clap();
            } else {
                return null;
            }
        }
    }
    

    This method works, but later on if I forget to 'override' the InterpretCommand() method on a new animal, the game will throw an error which in a build would result in a crash(I think). Not the perfect solution, but it gets the job done.