Setting up the StateManager controller

Now, look at line 6 of the StateManager class in the following screenshot. We have a big problem right off the bat:

Setting up the StateManager controller

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:

Setting up the StateManager controller

Studying an example of inheritance

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:

Studying an example of inheritance

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.

Studying an example of inheritance

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:

  • If we use inheritance, every method that's inherited will be identical, which is not what we want. The State methods need to have a code block specific to its needs.
  • Using an inherited method is optional which is not what need what. We want to guarantee that the methods will be used.
  • If we chose not to use an inherited method, then why bother creating the class in the first place?
  • Also, if we created a State system using inheritance, and later wished we could inherit from more than one class, we're out of luck.

    Note

    A C# class can only inherit from one class.

The question is what to do now?

Enter the IStateBase interface again

We don't have to create another class for the State classes to inherit and get the State Machine to work.

Note

An interface behaves just like inheritance, plus a class can implement more than one interface.

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:

Enter the IStateBase interface again

The IStateBase interface is providing a double guarantee that:

  • The State objects will have the required methods that StateManager needs to access
  • The activeState variable, of type IStateBase, requires all States to implement IStateBase
..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.144.107.193