← Python EnglishChapter 10 of 13

Object-Oriented Programming

## Learning Objectives - Understand classes and objects - Master inheritance and polymorphism - Learn encapsulation and data hiding - Work with special methods ## Classes and Objects ### Defining a Class ```python class Dog: """A simple dog class.""" def __init__(self, name, age): self.name = name # Instance attribute self.age = age def bark(self): return f"{self.name} says Woof!" def get_info(self): return f"{self.name} is {self.age} years old" # Creating an instance my_dog = Dog("Buddy", 3) print(my_dog.bark()) # Buddy says Woof! print(my_dog.get_info()) # Buddy is 3 years old ``` ### The __init__ Method ```python class Dog: def __init__(self, name, age=1): self.name = name self.age = age ``` ### Instance Attributes ```python dog1 = Dog("Rex", 2) dog2 = Dog("Max") print(dog1.name) # Rex print(dog2.age) # 1 (default) ``` ## Class Attributes ```python class Dog: species = "Canis familiaris" # Class attribute def __init__(self, name, age): self.name = name # Instance attribute self.age = age print(Dog.species) # Canis familiaris print(dog1.species) # Canis familiaris ``` ## Instance vs Class Methods ### Instance Methods ```python class Dog: def __init__(self, name): self.name = name def bark(self): # Instance method - takes self return f"{self.name} barks!" ``` ### Class Methods ```python class Dog: species = "Canis" @classmethod def get_species(cls): return cls.species print(Dog.get_species()) # Canis ``` ### Static Methods ```python class Math: @staticmethod def add(a, b): return a + b print(Math.add(2, 3)) # 5 ``` ## Inheritance ### Basic Inheritance ```python class Animal: def __init__(self, name): self.name = name def speak(self): raise NotImplementedError class Dog(Animal): # Inherits from Animal def speak(self): return f"{self.name} says Woof!" class Cat(Animal): def speak(self): return f"{self.name} says Meow!" dog = Dog("Buddy") cat = Cat("Whiskers") print(dog.speak()) # Buddy says Woof! print(cat.speak()) # Whiskers says Meow! ``` ### The super() Function ```python class Animal: def __init__(self, name): self.name = name class Dog(Animal): def __init__(self, name, breed): super().__init__(name) # Call parent's __init__ self.breed = breed dog = Dog("Rex", "Golden Retriever") print(dog.name) # Rex print(dog.breed) # Golden Retriever ``` ### Multiple Inheritance ```python class Flyable: def fly(self): return "Flying!" class Swimmable: def swim(self): return "Swimming!" class Duck(Flyable, Swimmable): pass duck = Duck() print(duck.fly()) # Flying! print(duck.swim()) # Swimming! ``` ## Polymorphism ```python def make_speak(animal): print(animal.speak()) animals = [Dog("Rex"), Cat("Whiskers")] for animal in animals: make_speak(animal) # Rex says Woof! # Whiskers says Meow! ``` ## Encapsulation ### Private Attributes ```python class BankAccount: def __init__(self, balance): self._balance = balance # Convention: private def get_balance(self): return self._balance def deposit(self, amount): if amount > 0: self._balance += amount return True return False account = BankAccount(100) print(account.get_balance()) # 100 # account._balance # Still accessible but discouraged ``` ### Name Mangling ```python class MyClass: def __init__(self): self.__private = 42 # Name mangled to _MyClass__private obj = MyClass() print(obj._MyClass__private) # 42 (don't do this) ``` ### Property Decorator ```python class BankAccount: def __init__(self, balance): self._balance = balance @property def balance(self): return self._balance @balance.setter def balance(self, value): if value >= 0: self._balance = value else: raise ValueError("Balance cannot be negative") account = BankAccount(100) print(account.balance) # 100 account.balance = 200 # Uses setter ``` ## Special Methods (Magic Methods) ### __str__ and __repr__ ```python class Person: def __init__(self, name, age): self.name = name self.age = age def __str__(self): return f"{self.name}, {self.age}" def __repr__(self): return f"Person('{self.name}', {self.age})" p = Person("Alice", 30) print(str(p)) # Alice, 30 print(repr(p)) # Person('Alice', 30) ``` ### __eq__ and __hash__ ```python class Point: def __init__(self, x, y): self.x = x self.y = y def __eq__(self, other): return self.x == other.x and self.y == other.y def __hash__(self): return hash((self.x, self.y)) p1 = Point(1, 2) p2 = Point(1, 2) print(p1 == p2) # True print(hash(p1) == hash(p2)) # True (can use in sets/dicts) ``` ### __len__ and __getitem__ ```python class Inventory: def __init__(self): self.items = [] def add(self, item): self.items.append(item) def __len__(self): return len(self.items) def __getitem__(self, index): return self.items[index] inv = Inventory() inv.add("apple") inv.add("banana") print(len(inv)) # 2 print(inv[0]) # apple ``` ### __call__ ```python class Multiplier: def __init__(self, factor): self.factor = factor def __call__(self, x): return x * self.factor double = Multiplier(2) print(double(5)) # 10 (called like a function) ``` ## Abstract Classes ```python from abc import ABC, abstractmethod class Shape(ABC): @abstractmethod def area(self): pass @abstractmethod def perimeter(self): pass class Rectangle(Shape): def __init__(self, width, height): self.width = width self.height = height def area(self): return self.width * self.height def perimeter(self): return 2 * (self.width + self.height) # shape = Shape() # TypeError: Can't instantiate abstract class rect = Rectangle(5, 3) print(rect.area()) # 15 ``` ## Data Classes (Python 3.7+) ```python from dataclasses import dataclass @dataclass class Person: name: str age: int email: str = "unknown@example.com" # Default person = Person("Alice", 30) print(person) # Person(name='Alice', age=30, email='unknown@example.com') ``` ## Summary - Classes define objects with attributes and methods - `__init__` initializes new instances - Instance attributes belong to objects; class attributes to class - `@classmethod` and `@staticmethod` for alternative method types - Inheritance: `class Child(Parent):` - `super().__init__()` calls parent constructor - Use `_attr` convention for private attributes - `@property` creates managed attributes - Special methods: `__str__`, `__eq__`, `__init__`, etc. - `@dataclass` auto-generates boilerplate

Comments

Comments powered by Giscus

To enable comments, add your Giscus embed code here.

Learn more about Giscus →