Curs 3 - Metode și Atribute Statice, Proprietăți, Suprascrierea Operatorilor, Visitor Pattern și Genericitate în Python

Acest curs explorează atributele și metodele statice, proprietățile, suprascrierea operatorilor, pattern-ul Visitor și genericitatea în Python.

1. Metode și Atribute Statice

Atributele statice aparțin clasei, nu instanțelor, iar metodele statice sunt definite cu `@staticmethod`.

class Contor:
    valoare = 0  # Atribut static

    @staticmethod
    def increment():
        Contor.valoare += 1

Contor.increment()
print(Contor.valoare)  # Output: 1

2. Proprietăți (`@property`)

Proprietățile permit controlul asupra accesării atributelor folosind `@property` și `@.setter`.

class Cerc:
    def __init__(self, raza):
        self._raza = raza
    
    @property
    def raza(self):
        return self._raza
    
    @raza.setter
    def raza(self, valoare):
        if valoare > 0:
            self._raza = valoare
        else:
            raise ValueError("Raza trebuie să fie pozitivă!")

c = Cerc(10)
c.raza = 5  # Se modifică raza folosind setter
print(c.raza)  # Output: 5

3. Suprascrierea Operatorilor

Python permite redefinirea operatorilor (`+`, `-`, `*`, `==`, etc.) prin metode speciale.

class Vector:
    def __init__(self, x, y):
        self.x = x
        self.y = y
    
    def __add__(self, other):
        return Vector(self.x + other.x, self.y + other.y)
    
    def __str__(self):
        return f"({self.x}, {self.y})"

v1 = Vector(2, 3)
v2 = Vector(1, 1)
v3 = v1 + v2  # Se apelează __add__
print(v3)  # Output: (3, 4)

4. Design Pattern: Visitor

Pattern-ul Visitor permite definirea de noi operații fără a modifica clasele existente, aplicând separarea logicii de date.

class Element:
    def accept(self, visitor):
        visitor.visit(self)

class ConcretElementA(Element):
    pass

class ConcretElementB(Element):
    pass

class Visitor:
    def visit(self, element):
        print(f"Vizităm elementul de tip {element.__class__.__name__}")

visitor = Visitor()
a = ConcretElementA()
b = ConcretElementB()
a.accept(visitor)
b.accept(visitor)

5. Genericitate în Python

Python suportă genericitate prin `typing.Generic`, permițând tipuri parametrizabile pentru reutilizare.

from typing import TypeVar, Generic

T = TypeVar('T')

class Container(Generic[T]):
    def __init__(self, valoare: T):
        self.valoare = valoare
    
    def get_valoare(self) -> T:
        return self.valoare

c1 = Container(10)
c2 = Container("Python")
print(c1.get_valoare())  # Output: 10
print(c2.get_valoare())  # Output: Python

Resurse suplimentare: