Python OOP

CSCI 1913 – Introduction to Algorithms, Data Structures, and Program Development
Adriana Picoral

OOP in Python

  • Python’s OOP shares many concepts with Java
  • Key Principles: Inheritance, Encapsulation, Polymorphism, Abstraction
    • Dynamic typing means some of those aspects differ from Java’s strongly typed model
    • Weaker Encapsulation
    • No explicit interface or abstract keywords, but similar functionality can be achieved

Classes and Objects

No primitives in python, everything is an object and everything has a class.

Use the class keyword to write your own classes

class MyClass:
  # code for class goes here

To create an object:

obj = MyClass()

init method and Instance Variables

  • Similar to Java constructors
    • not the only initialization hook, but the only one we use
  • Called automatically when creating an instance of an object
class Point:
  
  def __init__(self, x, y):
    self.x = x
    self.y = y

self and methods

  • The first parameter to every method should be self
  • This is a pointer to the object for which the method is being called, and can be used to access instance variables, or other methods.
  • When you call a method on an object, or construct a new object python passes self automatically
class Dog:
  def __init__(self, name):
    self.name = name
  
  def bark(self):
    print(f"{self.name} says Woof!")

Use

import dog

if __name__ == "__main__":
    myDog = dog.Dog("Daisy")
    myDog.bark()

Static methods and class variables

class Circle:
  pi = 3.14159
  
  @classmethod 
  def circumference(self, radius):
    return 2 * self.pi * radius

if __name__ == "__main__":
    circ1 = Circle.circumference(5)
    print(circ1)
31.4159

Inheritance in Python

Syntax: `class Childclass(Parentclass):``

Supports single and multiple inheritance

class Animal:
  
  def eat(self):
    print("Eating...")

Subclass:

class Cat(Animal):
  def meow(self):
    print("Meow!")

Subclass inherits methods from parent classes automatically (not instance variables though)

Use

class Dog(Animal):
  def __init__(self, name):
    self.name = name
  
  def bark(self):
    print(f"{self.name} says Woof!")


if __name__ == "__main__":
  myDog = Dog("Daisy")
  myDog.eat()
Eating...

Method Overriding

  • you can do method overriding, but not method overloading
  • use super(). or your parent class name (for example Animal.) to access parent things

Override def __str__(self): to return a string, and is called when the object is argument in print()

Encapsulation and Access Modifiers

  • Python relies on conventions rather than enforcement for encapsulation (boo)
  • “Private” attributes indicated by a leading underscore (e.g., _attr)
  • Double underscores (__attr) trigger name mangling (Python automatically renames it internally) to reduce accidental overrides
  • No strict private/public keywords as in Java
  • These conventions are for both attributes and methods

Encapsulation and Access Modifiers

class MyClass:
    def __init__(self):
        self.public_attribute = "I am public"
        self._protected_attribute = "I am protected (by convention)"
        self.__private_attribute = "I am private (mangled)"

    def get_private(self):
        return self.__private_attribute

Polymorphism in Python

Duck class

class Duck:
  def quack(self):
    print("Quack!")

Person

class Person:
  def quack(self):
    print("I can mimic a duck sound.")

Function definition with object as argument:

def make_it_quack(quacker):
  quacker.quack() # works for both Duck and Person