Objektově orientované programování (OOP) v Pythonu

Úvod

Objektově orientované programování (OOP) je programovací paradigma, které organizuje kód do objektů.

Objekt je instance třídy a kombinuje data (atributy) a chování (metody).

Cílem OOP je:

  • zvýšit přehlednost kódu

  • zlepšit znovupoužitelnost

  • usnadnit údržbu a rozšiřování aplikací

Python je plně podporuje OOP, ale zároveň umožňuje i procedurální a funkcionální styl.

Základní principy OOP

OOP stojí na čtyřech hlavních principech:

1. Zapouzdření (Encapsulation)

Zapouzdření znamená skrytí interní implementace objektu a zpřístupnění pouze definovaného rozhraní.

  • chrání data před nechtěnou manipulací

  • odděluje rozhraní od implementace

Python nepoužívá striktní private/public, ale konvence:

class BankAccount:
    def __init__(self, balance):
        self._balance = balance  # "protected"
        self.__secret = "hidden" # "private"

    def deposit(self, amount):
        self._balance += amount

    def get_balance(self):
        return self._balance

Poznámka:

  • _variable = interní použití (konvence)

  • __variable = name mangling (silnější ochrana)

2. Dědičnost (Inheritance)

Dědičnost umožňuje vytvářet nové třídy na základě existujících.

  • znovupoužití kódu

  • hierarchie tříd

class Animal:
    def speak(self):
        print("Some sound")

class Dog(Animal):
    def speak(self):
        print("Woof")

3. Polymorfismus (Polymorphism)

Polymorfismus znamená, že různé objekty mohou mít stejnou metodu, ale chovat se odlišně.

class Cat:
    def speak(self):
        return "Meow"

class Dog:
    def speak(self):
        return "Woof"

animals = [Cat(), Dog()]

for animal in animals:
    print(animal.speak())

Výstup:

Meow
Woof

4. Abstrakce (Abstraction)

Abstrakce znamená zaměření na to, co objekt dělá, ne jak to dělá.

Python podporuje abstraktní třídy pomocí modulu abc.

from abc import ABC, abstractmethod

class Shape(ABC):
    @abstractmethod
    def area(self):
        pass

class Rectangle(Shape):
    def __init__(self, w, h):
        self.w = w
        self.h = h

    def area(self):
        return self.w * self.h

Třídy a objekty v Pythonu

Definice třídy

class Person:
    def __init__(self, name, age):
        self.name = name
        self.age = age

    def greet(self):
        print(f"Ahoj, jmenuji se {self.name}")

Vytvoření objektu

p = Person("Martin", 30)
p.greet()

Konstruktor (init)

Metoda init se volá při vytvoření instance.

class Car:
    def __init__(self, brand):
        self.brand = brand

Instance vs. třídní atributy

class Counter:
    count = 0  # třídní atribut

    def __init__(self):
        Counter.count += 1

Metody

Instance metoda

def method(self):
    pass

Třídní metoda

@classmethod
def method(cls):
    pass

Statická metoda

@staticmethod
def method():
    pass

Dědičnost v praxi

Volání rodičovské třídy

class A:
    def __init__(self):
        print("A")

class B(A):
    def __init__(self):
        super().__init__()
        print("B")

Magic metody (dunder metody)

Speciální metody definují chování objektů.

class Vector:
    def __init__(self, u, v):
        self.u = u
        self.v = v

    def __add__(self, other):
        return Vector(self.u + other.u, self.v + other.v)

    def __repr__(self):
        return f"Vector({self.u}x{self.v})"

Kompozice vs. dědičnost

Kompozice (doporučeno)

class Engine:
    def start(self):
        print("Engine started")

class Car:
    def __init__(self):
        self.engine = Engine()

Výhody: - flexibilita - menší provázanost

Výhody OOP

  • modularita

  • znovupoužitelnost kódu

  • lepší organizace projektu

  • snadnější testování

Nevýhody OOP

  • větší složitost u malých projektů

  • může vést k překomplikovanému návrhu

  • vyšší režie (overhead)

Shrnutí

OOP v Pythonu poskytuje silný nástroj pro strukturování aplikací:

  • třídy = šablony

  • objekty = instance

  • zapouzdření chrání data

  • dědičnost umožňuje rozšiřování

  • polymorfismus zjednodušuje práci s objekty

  • abstrakce odděluje rozhraní od implementace

Používej OOP tam, kde dává smysl – zejména u větších aplikací nebo komplexních domén.