Now, look at line 6 of the StateManager
class in the following screenshot. We have a big problem right off the bat:
The
activeState
variable needs to be able to store all of the State types. Right now it can only store a reference to a BeginState
type of object. This looks like a huge problem! What about the classes PlayState
, WonState
, and LostState
? What if we had 50 different States that needed to be referenced in activeState
?
The following diagram is our dilemma:
Let's look at this issue using objects we all use all the time.
How about a Potato? Let's also imagine we have a Potato bag. Now to connect these real objects into the scripting world, the following is a simple declared variable:
public Potato bag;
So we have a variable named bag
. The type of object it can store is a Potato
. Saying this in another way: I have a Potato bag, and the only thing I can put in it is a potato.
The issue is shown in the following diagram:
We're not allowed to put a Steak, a Lettuce, or a Donut object into a Potato bag.
This is exactly the same issue we have with our activeState
variable that is declared to only store one type of object, a BeginState
object. We can put a BeginState
object in activeState
, but not a PlayState
, a WonState
, or a LostState
object.
So what do we do now?
Let's get back to the Potato example. Instead of using a very specific Potato bag, how about making the bag a bit more general, like a Food bag? Can we put a Potato in a Food bag? Is a Potato a Food? Well, we eat it, so it is a food. How about a Steak? Is that a food? Sure it is.
Look at each class declaration right below each Food object. Each class inherits properties from the Food
class. Now that we're also classifying each object in the more general class of Food
, we can now declare that the variable bag
can hold a type of Food
.
That's great. So, we can do something similar with our classes as well, such as create a more general StateBase
class for the State Machine, and then modify each State class to inherit from StateBase
, and the problem is solved. Yes, we could do that and make the State Machine work. However, inheritance does have some limitations in a State Machine and they are as follows:
The question is what to do now?
We don't have to create another class for the State classes to inherit and get the State Machine to work.
Each of our States is already implementing the IStateBase
interface to guarantee the methods are included. Now, since IStateBase
acts like it's being inherited, it means each of our States can be treated as if they're an IStateBase
type of object.
What we'll have after we modify StateManager
is shown in the following diagram:
The IStateBase
interface is providing a double guarantee that:
StateManager
needs to accessactiveState
variable, of type IStateBase
, requires all States to implement IStateBase
3.144.107.193