Classes Intro
Writing your code utilizing classes are regarded as a more refined code structure. There are many benefits to this architecture and only the simplest of applications should avoid using them. Â
Â
What is object oriented programming? Â
Lets assume you are writing a drag racing game. Building this using functions would get very complex pretty quick. The best way would be to break your application up into its elemental parts. In this game you obviously need various cars that will race each other and potentially different tracks they would race on. Each car would have different properties but similar functionality. The will probably all have 4 wheels and an engine but the details about traction, horse power and weight would be different. You could encapsulate this "Object" into a python class.
class RaceCar():
"""Represents a race car"""
def __init__(self, traction=10, hp=1000, lbs=2500):
self.traction = traction
self.hp = hp
self.lbs = lbs
In the above example we have defined a class and created some attributes about it. The "__init__" function is run any time a class is instantiated or created. The "self" argument is required and it references the instance of that class rather than all of the race cars at once. Think of this as a map of how a race car is created. Using this map you can create any number of race cars and each of them can have different properties. Â
pensoil = RaceCar() # Instantiates a race car with default properties
mobile1 = RaceCar(hp=3000) # Instantiates a race car while specifying its horse power
# Then you can reference each car individually and get its attributes
print(pensoil.hp) # result: 1000
print(mobile1.hp) # result: 3000
Thinking about this racecar you could imagine that there might be specific things you could do to modify that car. For instance, you might want to upgrade it's engine. For that define a method or a function within this class.
class RaceCar():
"""Represents a race car"""
def __init__(self, traction=10, hp=1000, lbs=2500):
self.traction = traction
self.hp = hp
self.lbs = lbs
def engineUpgrade(self, additionalHP):
"""Adds HP to the Race Car"""
self.hp += additionalHP
You would then call that method of that instance to increase its power.
pensoil.engineUpgrade(1000)
print(pensoil.hp) # result: 2000
Eventually you might want to race two of these cars. In order to do that we might want to get a speed value from them. To do that we might want to create another method. This one has a decorator "@property" which makes it act like a property so you would collect that information like a variable but the function runs each time it is called.
class RaceCar():
"""Represents a race car"""
def __init__(self, traction=10, hp=1000, lbs=2500):
self.traction = traction
self.hp = hp
self.lbs = lbs
def engineUpgrade(self, additionalHP):
"""Adds HP to the Race Car"""
self.hp += additionalHP
@property
def speed(self):
"""Calculate a race car's speed given its attributes"""
return self.hp * self.traction - self.lbs
Racing these two cars might look something like this
winner = race(pensoil, mobil1)
def race(car1, car2):
if car1.speed > car2.speed:
return car1
elif car2.speed > car1.speed:
return car2
else:
print('Its a TIE')
In this example, there is a problem. The function returns either car1 or car2 if there is a clear winner and a string if it is a tie. It would be better if these cars had a name associated with them.
class RaceCar():
"""Represents a race car"""
def __init__(self, name, traction=10, hp=1000, lbs=2500):
self.name = name
self.traction = traction
self.hp = hp
self.lbs = lbs
def engineUpgrade(self, additionalHP):
"""Adds HP to the Race Car"""
self.hp += additionalHP
@property
def speed(self):
"""Calculate a race car's speed given its attributes"""
return self.hp * self.traction - self.lbs
# Define the class that will race and return the results of the race
def race(car1, car2):
"""Pits two cars in a bout of contest"""
if car1.speed > car2.speed:
return car1.name
elif car2.speed > car1.speed:
return car2.name
else:
return 'Its a TIE'
# Instantiate two race cars with different properties
pensoil = RaceCar('Pensoil Car', hp=1000)
mobil1 = RaceCar('Mobil 1 Car')
#race them and print the results
print(race(pensoil, mobil1))