Programació oorientada a objectes
1. POO amb Python
És un dels paradigmes més populars per resoldre problemes a través de la programació.
Un objecte té dues característiques:
- atributs (estat)
- funcions (comportament)
Per exemple:
Una persona pot ser un objecte, ja que té les propietats següents:
- nom, edat com a atributs
- cantar, ballar com a comportament
El concepte de POO a Python se centra en la reutilització de codi. Aquest concepte també es coneix com DRY (Don't Repeat Yourself).
2. Classes
Una classe és una definició d'un objecte abstracte, que representa algun ent de la realitat al nostre programa. Conté tots els detalls comuns sobre tots els objectes del mateix tipus.
L'exemple de classe de lloro pot ser:
Ací fem servir la paraula clau class per definir una classe Loro buida.
3. Objectes
Quan es defineix la classe, només es defineix la descripció de l'objecte. Per tant, no s’assignen recursos per a la seua execució, ni s'assignen valors als seus atributs. Quan este fet es produeix, aleshores tenim un objecte en memòria sobre el que podem actuar.
L'exemple d'objecte de classe lloro pot ser:
Python | |
---|---|
Aquí, obj és un objecte de la classe Loro.
Suposem que tenim detalls de lloros. Ara, podem construir la classe i crear un objecte per a cada lloro.
Al programa anterior, hem creat una classe Parrot. A continuació, hem definit uns atributs, que prendran valors diferents en la instanciació d'objectes diferents.
Aquests atributs es defineixen dins del mètode init de la classe, que és el mètode inicialitzador que s’executarà només creem objectes.
Després, creem instàncies de la classe Parrot. blu i woo són referències (valor) als nostres objectes nous.
Podem accedir als atributs de classe mitjançant __class__.species
. Els atributs de classe són els mateixos per a totes les instàncies d’una classe. De la mateixa manera, accedim als atributs de la instància mitjançant objecte.nom_atribut
. Els atributs d’instància (valors) són diferents per a cada instància d’una classe.
4. Mètodes
Són funcions definides dins el cos d'una classe. S'utilitzen per a definir el comportament de l'objecte.
Hem definit dos mètodes sing() i dance(), que són mètodes d'instància, ja que es criden sobre un objecte.
5. Herència
L'herència és una forma de reutilitzar codi sense tindre-lo que reescriure. Açò facilita el manteniment de les aplicacions.
Les noves classes s'anomenen classes derivades (o classe filla). La classes de les que deriven són les classes base (o classe pare).
En l'anterior programa, la classe Penguin hereda de la classe Bird. La classe derivada hereda el mètode swim(), modifica el mètode who_is_this() i extén amb un nou mètode run().
Utilitzem super().__init__()
dins de l'__init()__
per a inicialitzar la classe pare.
6. Encapsulament
Podem restringir l’accés a mètodes i variables, és a dir, definir-los com a privats. Això impedeix que les dades es modifiquen directament accedint als atributs, és el que anomenem encapsulament. Definim atributs o mètodes privats utilitzant el guió baix com a prefix, és a dir, simple _ o doble __.
Com vegem, per canviar el valor, hem d’utilitzar una funció modificadora setter, és a dir, setMaxPrice (), que pren el preu com a paràmetre.
7. Polimorfisme
El polimorfisme és la capacitat d’utilitzar una interfície comuna (crides amb els mateixos noms) en diferents classes derivades.
Suposem que hem de pintar una forma i que hi ha diverses opcions: rectangle, quadrat, cercle, ... Podríem utilitzar el mateix mètode per a pintar qualsevol forma. Aquest concepte s’anomena polimorfisme.
Al programa anterior, hem definit dues classes Parrot i Penguin. Cadascun d'elles té un mètode comú fly(). No obstant això, les seues funcions són diferents.
Per utilitzar el polimorfisme, hem creat una interfície comuna, és a dir, la funció flying_test() que pren com a paràmetre qualsevol objecte i crida al mètode fly() de l’objecte. Així, quan passem els objectes blu i peggy a la funció flying_test(), s'executa el mètode corresponent a cadascuna.
7.1. Activitat 14
Defineix una jerarquia de figures amb les classes Figura, Cercle, Triangle, Rectangle i Quadrat.
-
La clase Figura tindrá dos métodes abstractes area i perimetre, que implementarán la resta de classes. La classe figura serà el que s'anomena una interfície informal, ja que tots els seus mètodes són abstractes. Per a definir que són abstractes, simplement utilitzeu la instrucció pass al bloc de la funció.
-
El Cercle rebrá el radi com a argument al seu constructor, el Triangle el costat i el Rectangle la base i l'altura.
- Cercle, Triangle i Rectangle heredarán de Figura directament.
- Quadrat heredará de Rectangle, però al constructor sols rebrá un argument, el costat.
-
Crea un objecte de cada tipus i imprimeix les seues característiques.
Info
En realitat la classe Figura es pot implementar com a una classe interfície, on tots els seus mètodes siguen abstractes. En Python existeixen dos tipus d'interfícies, formals i informals.
Per altra banda, podem declarar els atributs de les classes com a atributs privats i utilitzar els decoradors @property i @atribut.setter per a indicar els mètodes getters i setters, que seran públics. Fer-ho d'esta forma té alguns avantatges que veurem més endavant.