Python Classes and Objects

Classes and objects is a tough thing to learn.   It is confusing and difficult for most people, so give it time.  Keep at it and eventually it will start to make sense.  There are many different sites where you can read many different ways to prevent this information.

Getting back to our adventure game, we should discuss what we will attempt before we just start showing code.  We want an adventure game where everything in the adventure world will be an object called “things.”  But a world full of “things” is kinda confusing.  There may be common characteristics to all things like mass, gravity or color.  So we will break things into sub categories.

We will have “alive” and “notAlive” objects to start off with.  So players and monsters might be alive and gold and mountains might be “notAlive.”

We will take a player as an example first.  A player class will have things common to all players.  A “player” is “thing” and it is also “alive.”  So “alive” is players parent class and “thing” is player’s grandparent class.  What about children class you ask?  Great questions.

Follow the flow:   Things -> Alive -> Player -> Elf

If we make a subclass called “elf” with a parent of “player”, elf becomes the child of player.  Maybe elves have some special ability not common to all players like super hearing or the ability to speak to animals.

Follow the flow:   Things -> Alive -> Player -> Elf -> Forest Elf

Forest Elf become a sub-class of Elf.  Maybe Forest elves can do things not all elves can do like “tree magic”

Follow the flow:   Things -> Alive -> Player -> Elf -> Forest Elf -> Forest Elf Female

Turns out Females Forest Elves can magically heal things – something not common to all Forest Elves.

So what is we want to add monster to our adventure game?  Where do you thing monsters would fit into the flow? Can you picture how it the flow would look for a red dragon?

Follow the flow:   Things -> Alive -> Monsters

Follow the flow:   Things -> Alive -> Monsters -> Dragons -> Red Dragons

How about for “Not Alive” things?

Follow the flow:   Things -> Landscape -> Mountain

Follow the flow:   Things -> Landscape -> River

Follow the flow:   Things -> Money -> Gold

 

Now the Code

I hope that you have an idea of what we are trying to code.  So I am just going to give it to you all at once now and see if you can decipher the code based on what we talked about above for planning.

If you see the word pass where code should be do not be alarmed.  It is the equivalent to saying, “I know I want a red dragon in my world, but I am not ready to code a red dragon yet and I do not want an error message over it”

“Sure but what about “self” I see that everywhere?”  Self is required on classes because they are referring to objects.  If the object is a player and I want to change the name of that player, the method simply uses “self” to identify the object which called it.

#Using an adventure game setting for example


#creating a class
class Things:
    pass  #pass means no block of code here - a placeholder to avoid errors
    #this might be for methods that effect all things - like gravity

class Alive(Things):
    pass

class notAlive(Things):
    pass

class Players(Alive):  #create class "Player" a child of Things (the parent)
    #these methods are common to all players
    def health(self):
        print("Your health is: 100")

    def strength(self):
        print("Your strength is: 50")

    def speed(self):
        print("Your speed is: 50")

    def move(self):
        print(self.name, "is now on the move!")

    def attack(self, value):
        print("You are attacking: ", value)

    def nameChange(self, value):
        print(self.name, end="")
        self.name = value
        print(" your new name is: ", self.name)

#created class "Elf" with parent "Players" and grandparent "Things"
class Elf(Players):
    #these methods are common to elf players
    def superHearing(self):
        print("Using super hearing with my big ears!")

    def animalTalk(self):
        print("Just chatting with the animals")

class ForestElf(Elf):
    #these methods are common to forest elf players
    def tree_magic(self):
        print("Tree magic spell performed!")

class ForestElfFemale(ForestElf):
    #these methods are common to female forest elf players
    def healing_magic(self):
        print("You have been healed!")


#create class "Monsters" a child of Things (the parent)
class Monsters(Alive):
    pass

#created class "Dragon" with parent "Monsters" and grandparent "Things"
class Dragon(Monsters):
    pass

class RedDragon(Dragon):
    def __init__(self, gold, silver):
        self.gold_treasure = gold
        self.silver_treasure = silver

class landscape(notAlive):
    pass

class mountain(landscape):
    pass

class money(notAlive):
    pass

class gold(money):
    pass

print()
#create a ForestElfWomen instance (or object)
player1 = ForestElfFemale()  #like a function a class name is followed by ()
player1.name = "Sarah"
print("Welcome ", player1.name, "!")


#below we are calling methods of object class, parents and grandparents
print("Player1 Does This Stuff: ")
player1.nameChange("Syrah")
player1.health()
player1.superHearing()
player1.move()

#initialize player2
print()
player2 = ForestElfFemale()  #now she has a friend
player2.name = "Ryo"
print("Welcome ", player2.name, "!")

#below we are calling methods of object class, parents and grandparents
print("Player2 Does This Stuff: ")
player2.healing_magic()  #this method is inside ForestElfWomen
player2.tree_magic()

#below we are calling methods of object class, parents and grandparents
print("Player2 Does This Stuff: ")
player2.healing_magic()  #this method is inside ForestElfWomen
player2.tree_magic()

#Now we will add a dragon to this world
#We will initialize these dragons with dragon treasure
print()
dragon1 = RedDragon(100, 200)
print("Dragon Gold: ", dragon1.gold_treasure)
print("Dragon Silver: ", dragon1.silver_treasure)

Hold on!  What about that Red Dragon code I slipped in there you ask?  Well when we initialize (create) objects with can write an initializing function for those objects that receive parameters.  If every dragon will have some treasure, like gold and silver, then we can give them some when we create them.  The double underscore “init” is the initializing code for objects.  When methods are inside a class they always get the “self” argument.  Then all you have to do is list the things you want to give to the object.

class RedDragon(Dragon):
    def __init__(self, gold, silver):
        self.gold_treasure = gold
        self.silver_treasure = silver

OK this is one of harder concepts to grasp when delving into object oriented programming.  Classifying objects is simply a matter of starting with common characteristics and moving down the flow to more specialized characteristics.

Next time you are walking around in the world, try classifying things you are looking at for fun.  Maybe start with “Atoms” and work your way down from there.  You will begin to have a whole new appreciation for the complexity of our world!