advanced class 6. topics inheritance class methods / static methods class data vs. instance data

25
Learning to Program With Python Advanced Class 6

Upload: archibald-kelly

Post on 20-Jan-2016

230 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: Advanced Class 6. Topics Inheritance Class methods / static methods Class data vs. instance data

Learning to ProgramWith Python

Advanced Class 6

Page 2: Advanced Class 6. Topics Inheritance Class methods / static methods Class data vs. instance data

Topics

Inheritance

Class methods / static methods

Class data vs. instance data

Page 3: Advanced Class 6. Topics Inheritance Class methods / static methods Class data vs. instance data

Inheritance

Inheritance is one of the essential features of object-oriented programming.

After you’ve defined one class, you can define other classes to inherit the methods and properties of that parent class.

Page 4: Advanced Class 6. Topics Inheritance Class methods / static methods Class data vs. instance data

Inheritance

This way, if you need multiple classes that largely overlap in functionality and differ in relatively small ways, you only have to write the central part once.

The other classes can inherit the central functionality, and then add on whatever else they need.

Page 5: Advanced Class 6. Topics Inheritance Class methods / static methods Class data vs. instance data

Inheritance syntax #the class we’re inheriting from ↓ class ChildClassName(ParentClassName):

def __init__(self):#and so on…nothing else changes

here.

A synonymous term for “child class” is “subclass”, and a synonymous term for “parent class” is “superclass.”

Page 6: Advanced Class 6. Topics Inheritance Class methods / static methods Class data vs. instance data

Inheritance examples

Imagine you were writing a video game with different kinds of monsters for the player to fight.

You could create a base Monster class, and have each specific monster inherit from it and differ in whatever ways make that monster unique.

Page 7: Advanced Class 6. Topics Inheritance Class methods / static methods Class data vs. instance data

Inheritance examples#some arbitrary default attributes for a Monsterclass Monster:

def __init__(self):self.health = 100self.attack = 20self.defense = 20self.speed = 10self.accuracy = .50self.magic_resist = .30

Page 8: Advanced Class 6. Topics Inheritance Class methods / static methods Class data vs. instance data

Inheritance examples#Our first specific Monster.#At first we’re not going to change anything.class Banshee(Monster):

pass

Recall that the keyword ‘pass’ indicates ‘nothing happens here’ . . . it is functionally equivalent to blank space, but there has to be something in the class definition, so we put ‘pass’ there to meet that requirement.

Page 9: Advanced Class 6. Topics Inheritance Class methods / static methods Class data vs. instance data

Inheritance examples

Having thus defined the Banshee class, we can now use it.

>>> my_first_banshee = Banshee()>>> my_first_banshee.attack20>>>Why does it have an attack attribute?? We

didn’t define that in the Banshee class…

Page 10: Advanced Class 6. Topics Inheritance Class methods / static methods Class data vs. instance data

Inherited methodsAlthough we didn’t define an __init__ method for the

Banshee class, it already had one– the one it inherited from the Monster class.

We could override the inherited method by redefining it in the subclass Banshee, and then it would use that __init__ method instead of the inherited one.

But as we wrote it, it simply defaults to Monster’s __init__.

Page 11: Advanced Class 6. Topics Inheritance Class methods / static methods Class data vs. instance data

Inheritance examplesNow let’s actually make the Banshee unique.

class Banshee(Monster):def __init__(self):

super().__init__()self.attack = 25self.defense = 10self.accuracy = 1

Page 12: Advanced Class 6. Topics Inheritance Class methods / static methods Class data vs. instance data

About Banshee’s __init__Now that we’ve defined an __init__ method in

Banshee, the inherited one will be ignored.

Within the Banshee’s __init__ method, however, we wrote

super().__init__()

That line calls the __init__ method of the superclass, Monster, thereby setting up all the attributes that we had previously defined.

Page 13: Advanced Class 6. Topics Inheritance Class methods / static methods Class data vs. instance data

About Banshee’s __init__

So after calling super().__init__() inside of Banshee’s __init__, the attributes health, attack, defense, speed, accuracy, and magic_resist are all created on our new Banshee instance. That’s all done by Monster’s __init__ method.

After that, Banshee’s __init__ method goes on to modify those attributes according to however we want the Banshee to be different.

Page 14: Advanced Class 6. Topics Inheritance Class methods / static methods Class data vs. instance data

About Banshee’s __init__So in this case, we went ahead and increased

Banshee’s attack, reduced its defense, and gave it perfect accuracy, since it’s more or less impossible to dodge a scream.

We wanted to leave the other attributes as they were, so we did nothing else.

We only had to specify what made Banshee different from the default Monster. The superclass’s __init__ did the rest.

Page 15: Advanced Class 6. Topics Inheritance Class methods / static methods Class data vs. instance data

Inheritance examples

#Another specific monster for our game.class Dragon(Monster):

def __init__(self):super().__init__()self.attack = 200self.defense = 200self.health = 1000

Page 16: Advanced Class 6. Topics Inheritance Class methods / static methods Class data vs. instance data

About Dragon’s __init__Just like the Banshee class, Dragon inherits from

Monster. Which means when we create an instance of the Dragon class, all those default attributes are created.

We then customized the Dragon __init__ method to give the Dragon quite a lot of attack, defense, and health.

Again, we only had to specify how it was different from our base Monster.

Page 17: Advanced Class 6. Topics Inheritance Class methods / static methods Class data vs. instance data

The power of inheritance

This is a very simple example, where inheritance only saved us from having to specify a handful of additional attributes for each new Monster.

But it demonstrates the basic principle: inheritance saves us from having to redefine methods and attributes that we want to have in multiple classes.

Page 18: Advanced Class 6. Topics Inheritance Class methods / static methods Class data vs. instance data

The power of inheritance

We may or may not ever actually use the Monster class by itself. We could of course write:

>>> jimbob = Monster()

And now we have an instance of the base Monster class, with all the attributes defined accordingly.

Page 19: Advanced Class 6. Topics Inheritance Class methods / static methods Class data vs. instance data

The power of inheritance

We may or may not ever need to use it that way.

Possibly we created the Monster class simply to serve as a mold on which to base all the other classes we write . . . and as we saw, it serves its purpose well.

All redundancy was eliminated from the code.

Page 20: Advanced Class 6. Topics Inheritance Class methods / static methods Class data vs. instance data

Accessing inherited methodsFrom the outside, nothing is different. There’s

no way to tell if a method is inherited or not.

Either way, you write the same thing.

Let’s imagine we had defined an attack method in the Monster class, which takes one argument, the monster we’re attacking. Dragon and Banshee would have inherited this method.

Page 21: Advanced Class 6. Topics Inheritance Class methods / static methods Class data vs. instance data

Accessing inherited methodsI’ve made a Monster and a Dragon. The

attack method is only defined for Monster, but Dragon inherits it, so both classes have access to it.

>>> my_monster = Monster()>>> my_dragon = Dragon()>>> my_monster.attack(my_dragon)>>> my_dragon.attack(my_monster)

Page 22: Advanced Class 6. Topics Inheritance Class methods / static methods Class data vs. instance data

Accessing inherited methodsfrom inside the subclass

In a previous example, we used super().__init__() to invoke the functionality of the superclass’s __init__ method.

But this is only necessary if you want to specify that you’re calling the superclass’s implementation of the method as opposed to the subclass’s once the method has been redefined, as in the case of __init__.

Page 23: Advanced Class 6. Topics Inheritance Class methods / static methods Class data vs. instance data

Accessing inherited methods from inside the subclass

Just as you can simply call the inherited method on the class instance from the outside without doing anything special, you can simply call the inherited method from the inside without doing anything special.

Just treat it like any other method and write self.methodName(arguments).

Page 24: Advanced Class 6. Topics Inheritance Class methods / static methods Class data vs. instance data

Inherited methodsSo if the Dragon class had a method attackEveryone(),

it might call self.attack() on every monster in the vicinity, which is okay because it inherited the attack() method from its parent class Monster.

class Dragon:#def __init__ etcdef attackEveryone(nearbyMonsters):

for m in nearbyMonsters:self.attack(m)

Page 25: Advanced Class 6. Topics Inheritance Class methods / static methods Class data vs. instance data

Overriding methodsWe’ve already done this– we did it with the __init__

method. But you can do it with any inherited method.

If you want a subclass to have a different implementation of an inherited method, you simply redefine it inside the subclass however you want it to be, and it overrides the method.

When you call the method on the subclass, it will call the subclass’s implementation of the method, not the inherited version.