L'encapsulació és un dels quatre pilars de la programació orientada a objectes (POO), juntament amb l'herència, el polimorfisme i l'abstracció. L'encapsulació consisteix a restringir l'accés a certs components d'un objecte i només permetre la seva modificació a través de mètodes específics. Això ajuda a protegir la integritat de les dades i a mantenir el codi més organitzat i fàcil de mantenir.
Conceptes Clau
- Atributs Privats: Atributs que no es poden accedir directament des de fora de la classe.
- Mètodes Accessors: Mètodes que permeten accedir als atributs privats.
- Mètodes Mutadors: Mètodes que permeten modificar els atributs privats.
- Propietats: Una manera més elegant i Pythonica d'accedir i modificar els atributs privats.
Atributs Privats
En Python, els atributs privats es defineixen prefixant el nom de l'atribut amb dos guions baixos (__). Això no impedeix completament l'accés a l'atribut, però fa que sigui més difícil accedir-hi accidentalment.
class Persona:
def __init__(self, nom, edat):
self.__nom = nom
self.__edat = edat
def mostrar_informacio(self):
print(f"Nom: {self.__nom}, Edat: {self.__edat}")
persona = Persona("Joan", 30)
# persona.__nom # Això donarà un error
persona.mostrar_informacio() # Això funciona correctamentMètodes Accessors i Mutadors
Els mètodes accessors (getters) i mutadors (setters) permeten accedir i modificar els atributs privats de manera controlada.
class Persona:
def __init__(self, nom, edat):
self.__nom = nom
self.__edat = edat
def get_nom(self):
return self.__nom
def set_nom(self, nom):
self.__nom = nom
def get_edat(self):
return self.__edat
def set_edat(self, edat):
if edat > 0:
self.__edat = edat
else:
print("L'edat ha de ser un valor positiu")
persona = Persona("Joan", 30)
print(persona.get_nom()) # Joan
persona.set_edat(35)
print(persona.get_edat()) # 35Propietats
Les propietats en Python permeten definir mètodes accessors i mutadors d'una manera més elegant utilitzant el decorador @property.
class Persona:
def __init__(self, nom, edat):
self.__nom = nom
self.__edat = edat
@property
def nom(self):
return self.__nom
@nom.setter
def nom(self, nom):
self.__nom = nom
@property
def edat(self):
return self.__edat
@edat.setter
def edat(self, edat):
if edat > 0:
self.__edat = edat
else:
print("L'edat ha de ser un valor positiu")
persona = Persona("Joan", 30)
print(persona.nom) # Joan
persona.edat = 35
print(persona.edat) # 35Exercicis Pràctics
Exercici 1
Crea una classe CompteBancari amb els següents atributs privats: titular, saldo. Defineix mètodes accessors i mutadors per aquests atributs, assegurant-te que el saldo no pugui ser negatiu.
Solució
class CompteBancari:
def __init__(self, titular, saldo):
self.__titular = titular
self.__saldo = saldo
@property
def titular(self):
return self.__titular
@titular.setter
def titular(self, titular):
self.__titular = titular
@property
def saldo(self):
return self.__saldo
@saldo.setter
def saldo(self, saldo):
if saldo >= 0:
self.__saldo = saldo
else:
print("El saldo no pot ser negatiu")
# Prova
compte = CompteBancari("Anna", 1000)
print(compte.titular) # Anna
print(compte.saldo) # 1000
compte.saldo = 500
print(compte.saldo) # 500
compte.saldo = -100 # El saldo no pot ser negatiuExercici 2
Crea una classe Rectangle amb atributs privats ample i alt. Defineix mètodes per calcular l'àrea i el perímetre del rectangle. Utilitza propietats per accedir i modificar els atributs.
Solució
class Rectangle:
def __init__(self, ample, alt):
self.__ample = ample
self.__alt = alt
@property
def ample(self):
return self.__ample
@ample.setter
def ample(self, ample):
if ample > 0:
self.__ample = ample
else:
print("L'ample ha de ser un valor positiu")
@property
def alt(self):
return self.__alt
@alt.setter
def alt(self, alt):
if alt > 0:
self.__alt = alt
else:
print("L'alt ha de ser un valor positiu")
def area(self):
return self.__ample * self.__alt
def perimetre(self):
return 2 * (self.__ample + self.__alt)
# Prova
rectangle = Rectangle(5, 10)
print(rectangle.area()) # 50
print(rectangle.perimetre()) # 30
rectangle.ample = 7
print(rectangle.area()) # 70Conclusió
L'encapsulació és una tècnica fonamental en la programació orientada a objectes que ajuda a protegir les dades i a mantenir el codi més organitzat. Utilitzant atributs privats, mètodes accessors i mutadors, i propietats, podem controlar l'accés i la modificació dels atributs d'una classe de manera segura i eficient.
Curs de Programació en Python
Mòdul 1: Introducció a Python
- Introducció a Python
- Configuració de l'Entorn de Desenvolupament
- Sintaxi de Python i Tipus de Dades Bàsics
- Variables i Constants
- Entrada i Sortida Bàsiques
Mòdul 2: Estructures de Control
Mòdul 3: Funcions i Mòduls
- Definició de Funcions
- Arguments de Funció
- Funcions Lambda
- Mòduls i Paquets
- Visió General de la Biblioteca Estàndard
Mòdul 4: Estructures de Dades
Mòdul 5: Programació Orientada a Objectes
Mòdul 6: Gestió de Fitxers
- Lectura i Escriptura de Fitxers
- Treballant amb Fitxers CSV
- Gestió de Dades JSON
- Operacions amb Fitxers i Directoris
Mòdul 7: Gestió d'Errors i Excepcions
Mòdul 8: Temes Avançats
- Decoradors
- Generadors
- Gestors de Context
- Concurrència: Fils i Processos
- Asyncio per a Programació Asíncrona
Mòdul 9: Proves i Depuració
- Introducció a les Proves
- Proves Unitàries amb unittest
- Desenvolupament Guiat per Proves
- Tècniques de Depuració
- Ús de pdb per a la Depuració
Mòdul 10: Desenvolupament Web amb Python
- Introducció al Desenvolupament Web
- Conceptes Bàsics del Framework Flask
- Construcció d'APIs REST amb Flask
- Introducció a Django
- Construcció d'Aplicacions Web amb Django
Mòdul 11: Ciència de Dades amb Python
- Introducció a la Ciència de Dades
- NumPy per al Càlcul Numèric
- Pandas per a la Manipulació de Dades
- Matplotlib per a la Visualització de Dades
- Introducció al Machine Learning amb scikit-learn
