Presentation is loading. Please wait.

Presentation is loading. Please wait.

Object-Oriented Programming (OOP) in Python

Similar presentations


Presentation on theme: "Object-Oriented Programming (OOP) in Python"— Presentation transcript:

1 Object-Oriented Programming (OOP) in Python
References: Chapter 8 & 9

2 OOP in general Break your program into types of Objects
Player Enemy Map Application Collect all data and functions for that type into a class. Example (Player): Data: position, health, inventory, … Functions: draw, handleInput, update, hitDetect, … Most modern software engineers use this approach to programming

3 Classes and Objects Classes. Objects (instances)
A blueprint for a new python type Includes: Variables (attributes) Functions (methods) Objects (instances) A variable built using a class "blueprint" All python variables are objects. Creating an object creates a new set of attributes for that object. You call methods of the class through an instance.

4 Example class Player(object):
"""This is the docstring for the player class.""" def attack(self): """ This is the docstring for a method.""" print "HIII-YA!" P = Player() # This creates a new instance of Player Q = Player() # Another instance P.attack() # This calls the attack method of P. Q.attack() # self will refer to Q here. Self: Note when we call P's attack method, we don't pass an argument for self. self is a reference (alias) to the calling object. So…while we're in the attack method called from line 10, self refers to P. But…while we're in the attack method called from line 11, self refers to Q. Both calls use the same method definition, but self refers to different things. All "normal" methods will have self as their first parameter.

5 Adding attributes. To really do something useful, the class needs data (attributes). The first (bad) way of doing it would be: class Player(object): """This is the docstring for the player class.""" def attack(self): """ This is the docstring for a method.""" print(self.name + " says 'HIII-YA!'") P = Player() # This creates a new instance of Player Q = Player() # Another instance P.name = "Bob" P.attack() # This calls the attack method of P. Q.attack() # Error! Problem: we have to "manually" add attributes to all instances (error-prone)

6 Adding attributes the "right" way (constructors)
Python allows you to write a special method which it will automatically call (if defined). Called the constructor. In python it is __init__ Example: class Player(object): def __init__(self): print("Hi! I'm a new player") P = Player() # Calls __init__ (passing P) automatically.

7 Adding attributes the "right" way (constructors)
Pass arguments to __init__ and creating attributes. Example: class Player(object): def __init__(self, newName): self.name = newName # A new attribute def attack(self): print(self.name + " says 'HIII-YA!'") #P = Player() # Error. __init__ requires an argument. P = Player("Bob") # Calls __init__ (passing P and "bob") automatically. Q = Player("Sue") P.attack() Q.attack() Now we are guaranteed every player has a name attribute.

8 string conversion of objects
Normally, if you do this: P = Player("Bob") x = str(P) print(x) you get output similar to: <__main.Player object at 0x00A0BA90> This is the "default" way of converting an object to a string Just like the "default" way of initializing an object is to do nothing. Python allows us to decide how to do it.

9 string conversion of objects
Example class Player(object): def __init__(self, newName): self.name = newName def __str__(self): return "Hi, I'm " + self.name P = Player("Bob") x = str(P) print(x) # Prints 'Hi, I'm Bob' A common mis-conception: The __str__ method needs to return a string, not directly print it.

10 Static (class) attributes / methods
"Normal" methods and attributes: One copy of attributes for each instance All instances share the same methods, but self has a different value for each call. Static (class) methods and attributes: All instances share the same attributes Methods don't include self, and can't access the "normal" attributes

11 Example class Foo(object): staticAttribute = "ABC"
def __init__(self, x): self.normalAttribute = x def staticMethod(): print("This is a static method.") print("\tI can access a static attribte: " + str(Foo.staticAttribute)) #print("\tBut this would cause an error: " + str(self.normalAttribute)) #print("\tSo would this: " + str(Foo.normalAttribute)) def normalMethod(self): print("This is a normal method.") print("\tThis is OK: " + str(self.normalAttribute)) #print("\tBut never this: " + str(Foo.normalAttribute)) V = Foo(19) Foo.staticMethod() print(Foo.staticAttribute) V.normalMethod() print(V.normalAttribute)

12 Static attributes / methods, cont.
Some "good" uses for this: In an enemy class, load a sprite common to all enemies. Include variables for things like: speed, baseHP, etc, that are common to all instances of a class. Some "bad" uses for this: Using only static attributes / methods. You'll have to make a new class for similar instances.

13 private Methods / Attributes + Properties + Decor
I'm going to skip these: private methods and attributes (p ) class properties (p ) decorators (p.232) I'd rather (this semester) that you focus on "normal" methods / attributes. They definitely have their place, though. We may talk about them in ETGG1802 if we need them. You'll definitely see them in later ETEC / ETGG classes

14 Example [UFO (or a new game) using OOP] [ParticleEmitters]

15 Inheritance (Chapter 9)
Basically, basing a new (derived) class from an existing one (base) . You "inherit" all methods (and attributes) from the base class. You then: Add new methods Replace existing methods Although you can still call the base class's version

16 Abstract example class Base(object): def __init__(self, x):
self.num = x def foo(self, string): return string * self.num class Derived(Base): def bar(self): return self.num ** 2 A = Derived(4) # Note, we're using Base's __init__ method. print(A.foo("ABC")) # Calling the inherited method print(A.bar()) # Call a new method. One problem: If we want to add new attributes to Derived…

17 Calling (hidden) base class methods.
class A(object): def f(self): print("A.f") class B(A): print("B.f") obj = B() obj.f() # Print's B.f It appears as if we've replaced A's version of f, but it's actually just hidden.

18 Calling (hidden) base class methods, cont.
class A(object): def f(self): print("A.f") class B(A): A.f(self) # Calls the "hidden" f. print("B.f") obj = B() obj.f() # Print's 'A.f' then 'B.f' When you call base class methods like this, it is the only time self isn't passed automatically.

19 Adding attributes to a new class
class Base(object): def __init__(self, x): self.num = x def foo(self, string): return string * self.num class Derived(Base): def __init__(self, x, y): Base.__init__(x) self.num2 = y def bar(self): return self.num ** 2 + self.num2 ** 2 A = Derived(4) # Note, we're using Base's __init__ method. print(A.foo("ABC")) # Calling the inherited method print(A.bar()) # Call a new method.

20 Example [Derived particle (emitter) classes]


Download ppt "Object-Oriented Programming (OOP) in Python"

Similar presentations


Ads by Google