Object-Oriented Programming
Objective
Implement classes, understand instance vs class attributes, use properties, inheritance, and abstract base classes.
Tools & Technologies
class__init__@property@classmethod@staticmethoddataclassabc
Key Commands
class MyClass:@dataclass@propertysuper().__init__()from abc import ABC, abstractmethodArchitecture Overview
classDiagram
class Animal {
+name: str
+sound: str
+speak() str
}
class Dog {
+breed: str
+fetch()
+speak() str
}
class Cat {
+indoor: bool
+purr()
+speak() str
}
Animal <|-- Dog
Animal <|-- Cat
Step-by-Step Process
01
Class Basics
Define a class with attributes and methods.
class BankAccount:
interest_rate = 0.02 # class attribute
def __init__(self, owner: str, balance: float = 0):
self.owner = owner # instance attribute
self._balance = balance # 'private' by convention
@property
def balance(self):
return self._balance
def deposit(self, amount: float):
if amount <= 0:
raise ValueError('Amount must be positive')
self._balance += amount
def __repr__(self):
return f'BankAccount({self.owner!r}, {self._balance})'
02
Inheritance
Extend classes and override methods.
class SavingsAccount(BankAccount):
def __init__(self, owner, balance=0, goal=None):
super().__init__(owner, balance) # call parent init
self.goal = goal
def deposit(self, amount):
super().deposit(amount) # call parent method
if self.goal and self._balance >= self.goal:
print(f'Goal of ${self.goal} reached!')
ac = SavingsAccount('Alice', goal=1000)
ac.deposit(1200)
03
dataclasses
Reduce boilerplate with @dataclass.
from dataclasses import dataclass, field
@dataclass
class Point:
x: float
y: float
label: str = ''
tags: list = field(default_factory=list)
def distance_to(self, other: 'Point') -> float:
return ((self.x-other.x)**2 + (self.y-other.y)**2)**0.5
p1 = Point(1.0, 2.0)
p2 = Point(4.0, 6.0)
print(p1.distance_to(p2)) # 5.0
Challenges & Solutions
- Mutable default arguments in __init__ — use None and assign in body
- Class attributes shared across all instances — modify carefully
Key Takeaways
- @dataclass auto-generates __init__, __repr__, __eq__ — use for data containers
- Use @property for computed attributes and validation without changing the interface