Sponsored By

Featured Blog | This community-written post highlights the best of what the game industry has to offer. Read more like it on the Game Developer Blogs.

OOPsie: The Basics of Classes and Inheritance

Many beginning programmers ask 'What language should I learn to make games?' but they never realize how useful object-oriented techniques are to a beginner.

Matt Christian, Blogger

September 30, 2010

10 Min Read

Object-oriented programming (OOP) is standard fare for the typical programmer in today's workplace, especially in the games industry.  However, the first question all beginning game programmers ask is: 'What programming language should I learn?'  I always respond with some useful information about a language (typically C# and XNA) and always include something suggesting them to look at a book or set of websites about object oriented techniques.

Why do I suggest this?  Well, not only will it make them a more solid programmer, but it will take some of the redundancy (and headaches) out of their work.  Also, the high amount of OOP in the workplace is relatively new (which is why we are seeing company after company creating large-scale system-replacement projects).  If you have even a slight passion for creating object oriented code, you'll be a valued asset to anywhere you work.  I don't know how many times I've been commended for my desire to rework non-OOP code.

What is OOP?

Object-oriented programming (OOP) is a programming paradigm that puts an emphasis on several concepts to create reusable and easily extendable code.  The core of OOP focuses on objects (hence object-oriented programming).  Other techniques in OOP include the basics such as classes and their members and goes through more advanced techniques like polymorphism.  Don't worry if you don't know what most (or any) of these are, we will discuss everything just mentioned and give simple, game-development focused examples (polymorphism will be in a future article).

Classes & Objects

Classes are one half of the core concept behind objects.  In the most simple sense of the definition, classes are the blueprints for an object.  Well that's great and all, but what the heck is an object?  An object is an instance of something, typically something definable in the real-world.  Great, two definitions in and you're already confused.  Let's take a real-world example of classes and objects before we get into a game-development example.

How did your house or work building get developed?  Well, first someone drew up a blueprint of a house, defining things like where the bathrooms are and where the stairs will be.  After the blueprint was finished, the construction team came in a built the house based on the blueprints.  In this case the blueprints for the house is the class, and the finished, physical house is the object.

In programming, we call the house an instance of the class (because it is a physical version of the blueprint).  Let's combine all these concepts into an example using the Gran Turismo series.

Gran Turismo, as most gamers know, is a racing game.  As such, it features cars (shocker, I know).  It wouldn't make sense to go through the entire process of writing up a car from scratch and then having to redevelop the entire thing would it?  No.  That's why we come up with a blueprint for a car.  Then we can create multiple cars off that blueprint and suddenly, voila, we have a screen filled with cars:

Gran Turismo Cars (Sony)

Gran Turismo Cars (Sony)

A Deeper Look at Classes - Members

After that picture and description, one question should stick out in your mind.  "But Matt, if we use a blueprint, we should get a screen full of cars that all look the same right?  Because each house has a unique blueprint right?"  Right!  There's hope for you yet young programmer.

But before we get into the differences with the cars, lets look at the similarities.  Each car shown above has 4 wheels and has the abilities to start up and honk the horn.  All of these things can be defined in the class blueprint so that every car we create using that blueprint will automatically have 4 wheels and the two abilities.  These similarities will be what defines our class members.  Class members are essentially the collection of methods, variables, and other features found in that class.

While variables and methods (sometimes called functions) are important aspects in OOP, they are examples of more generalistic programming terms that hopefully you already know about, if not simply Google the terms.  If you aren't sure, variables are essentially data stores (think of a variable in mathematics, it stores something) and a method is some process that can be run to do something (typically like a verb; such as Jump or Move).

In our example, the 4 tires can be stored in our Car class as a variable called numberOfTires.  The two abilities can be created as methods, startUp() and honkHorn().  Here's an example of some C# code that would define a class called Car.

public class Car
{
    public int numberOfTires = 4;

    public Car() {

    }

    public void startUp() {
        Console.WriteLine("VROOOM");
    }

    public void honkHorn() {
        Console.WriteLine("Beep-Beep!");
    }
}

public class MainProgram
{
    static void Main(string[] args) {
        // Create a new car object
        Car ferrari = new Car();
        ferrari.startUp();
        ferrari.honkHorn();
    }
}

Output:
VROOOM
Beep-Beep!

Don't worry if you aren't that familiar with C#, hopefully you can still grasp the concept.  Both methods simply print the statements and the variable for tire count defaults to 4.  The MainProgram class is required for C# and the Main() method is automatically called for C# console programs.  Inside it, the Main() method creates a new car object and then calls the methods on the car to print the statements.

One big point, the method you see above in the Car class called Car() that doesn't specify a return type is called the constructor.  The constructor is what creates (or constructs) an instance of our object.  In the house example given earlier, think of it as the construction crew that built the house.

Differences - The Core of Inheritance

We have finally been able to reach the concept of inheritance.  What is it?  Inheritance is the concept where one class 'inherits' from another class and thus inherits given functionality and members.

Remember earlier you had that question why all the cars looked different if they came from the same blueprint?  Inheritance.  The relationship of inheritance is often called the 'is-a' relationship.  For example, a Ferrari is-a car, it's just a specific type of car.  Similarily, a Ford is-a car, but it's not a Ferrari (technically they are brands, but I'm a programmer, not a mechanic).

Even something as simple as the color of the car could promote a different blueprint (class).  For example, we could have the Car class, and then 3 classes that inherit from it, BlueFord, RedFord, GreenFerrari.  However, and this is a point I want to make EXTREMELY clear, while inheritance is useful and made to create these types of relationships, there are instances where you can abuse using it.  Creating seperate classes simply for a color change isn't a good idea.  If you suddenly want a Cornflower Blue car, you need to write a whole new class.  What we should do, is create a variable member on the Car class called carColor and pass the color as an argument to the constructor.

The factories that cars are built at don't have a specific color related to a given blueprint.  However, when you order your brand new car, they ask you 'What color do you want?'  When they put in the order they say 'I want a car of brand XX painted blue'.  The 'I want a car of brand XX' is defining the blueprint, while 'painted blue' is defining the arguments.

With that said, lets look at an example of creating 2 cars, a red and a blue Ferrari:

public class Car
{
    public int numberOfTires = 4;
    protected string carColor;

    public Car(String color) {
        carColor = color;
    }

    public void startUp() {
        Console.WriteLine("VROOOM");
    }

    public void honkHorn() {
        Console.WriteLine("Beep-Beep!");
    }

    public string getColor() {
        return carColor;
    }
}

public class Ferrari : Car
{
    public Ferrari(String color)
        : base(color)
    {
       
    }
}

public class MainProgram
{
    static void Main(string[] args) {
        // Create a new blue ferrari object
        Ferrari blueFerrari = new Ferrari("Blue");
        Ferrari redFerrari = new Ferrari("Red");
        Console.WriteLine("I'm a " + blueFerrari.getColor() + " Ferrari!")
        Console.WriteLine("I'm a " + redFerrari.getColor() + " Ferrari!")
        
        blueFerrari.startUp();
        redFerrari.startUp();
    }
}

Output:
I'm a Blue Ferrari!
I'm a Red Ferrari!
VROOOM
VROOOM

Whew, lots of new stuff to talk about.  First our Car class, which has been updated to include a new variable, a new method, and an updated constructor that takes an argument.  The method is pretty standard, it just returns the stored color.  The constructor is also standard, it just stores the color.  The unique part is the variable itself, more specifically, the scope of the variable which is protected.  Essentially, a protected member in a class defines the member as private for itself and all classes that inherit from it.  Hopefully you already know the difference between public and private.

A new class has appeared as well, the Ferrari class.  The colon after 'Ferrari' tells the class to inherit from the class defined after it.  So in our case, Ferrari inherits from Car ( Ferrari : Car ).  Ferrari also has it's own constructor, but since it inherits from Car and Car has a constructor, we need some way to pass an argument from the Ferrari class to it's parent.  C# includes the base operation which refers to members of the parent class and allows us to call what we need (in this case, the constructor).

Finally, in Main() we create 2 new Ferrari's and call some of the methods stored on them.  Now, every car has a private color member as well as a new function getColor.  As you can see from the final output, the method can be called from both new objects and return results unique to that object.  Also notice, they both also gain their own access to the public startUp() and honkHorn() methods.

Applications

At this point, I think we've learned plenty of OOP and lots of stuff the paradigm includes, why don't we discuss more about how OOP is used in games.  It's a safe bet that everything you notice in a game is some object, after all, most everything in a game has some kind of real-life translation.  And, since we know objects are instances of class blueprints, we know each object has some class behind it.  That leads us to believe games are comprised of hundreds of thousands of classes and objects!

Inheritance could be something we might be able to point out with a more concrete example.

Halo Reach

Halo Reach

In Halo Reach, you are often accompanied by multiple friendly, AI-controlled teammates (assuming you aren't playing co-op).  A lot of the code between these teammates is probably shared, including things like the way the AI might dodge or when it determines to throw a grenade.  In fact, that code might even be shared with the Covenant enemy AI at some point (though probably is modified somewhat).  However, each teammate is represented with a unique character model featuring a voice unique to that character.  In some cases, even the weapons are unique (notice the big turret gun that guy above is holding!) which could slightly modify some of the AI they share with the others, making them their own unique entity.

If you hop into Halo Reach's matchmaking, you'll end up in an arena with a set of teammates and a set of enemies.  It's possible both inherit from a generic class to display the user on your screen while teammates and enemies have different attributes changing how you interact with them.

Conclusion

As we can see from the given examples, objects and classes are extremely useful, not only do they form a very clean programming paradigm, but they are extremely easy to visual since they essentially create code that resemble objects in real life.  There are much larger benefits to OOP and while this beginner article only shows the foundation of OOP and it's benefits, the bonuses to using OOP only get better and better.  Whether you're a beginning programmer or a seasoned vet, you'll find outstanding plusses to learning and developing with OOP.

Read more about:

Featured Blogs
Daily news, dev blogs, and stories from Game Developer straight to your inbox

You May Also Like