Download as pdf or txt
Download as pdf or txt
You are on page 1of 31

Conceptes de programació orientada a objectes

Projecte de Programació
Conceptes de programació orientada a objectes

Miquel Bofill
http://imae.udg.edu/~mbofill

IMAE – UdG

Miquel Bofill, IMAE – UdG ProPro – Conceptes de OOP 1 / 22


Herència vs Subtipatge
Sobreescriptura i Sobrecàrrega
Conceptes de programació orientada a objectes Tipus aparent i tipus real
Assignació i lligam missatge-mètode
Utilització vs Refinament

Resum

1 Conceptes de programació orientada a objectes


Herència vs Subtipatge
Sobreescriptura i Sobrecàrrega
Tipus aparent i tipus real
Assignació i lligam missatge-mètode
Utilització vs Refinament

Miquel Bofill, IMAE – UdG ProPro – Conceptes de OOP 2 / 22


Herència vs Subtipatge
Sobreescriptura i Sobrecàrrega
Conceptes de programació orientada a objectes Tipus aparent i tipus real
Assignació i lligam missatge-mètode
Utilització vs Refinament

Herència vs Subtipatge

Definició (Herència)
El fet que una classe (subclasse) contingui les variables i mètodes
definits en una altra classe (superclasse).

Miquel Bofill, IMAE – UdG ProPro – Conceptes de OOP 3 / 22


Herència vs Subtipatge
Sobreescriptura i Sobrecàrrega
Conceptes de programació orientada a objectes Tipus aparent i tipus real
Assignació i lligam missatge-mètode
Utilització vs Refinament

Herència vs Subtipatge

Definició (Herència)
El fet que una classe (subclasse) contingui les variables i mètodes
definits en una altra classe (superclasse).

Definició (Subtipatge)
Forma de polimorfisme en què un determinat tipus de dades
(subtipus) està relacionat amb un altre tipus de dades (supertipus)
per alguna noció de substituı̈bilitat. Tı́picament: si S és subtipus
de T , aleshores qualsevol expressió (objecte) de tipus S pot ser
usat amb seguretat en qualsevol context on s’esperi una expressió
(objecte) de tipus T .

Miquel Bofill, IMAE – UdG ProPro – Conceptes de OOP 3 / 22


Herència vs Subtipatge
Sobreescriptura i Sobrecàrrega
Conceptes de programació orientada a objectes Tipus aparent i tipus real
Assignació i lligam missatge-mètode
Utilització vs Refinament

Herència vs Subtipatge (2)

Quan hi ha herència hi ha també subtipatge


public class A {
void f(A a) { ... }
}
public class B extends A { ... }

A a = new A(); B b = new B();


a.f(a); a.f(b); a = b; // un B es un A
en canvi. . .
Pot haver-hi subtipatge sense herència
int i = 0;
float f = i; // un int es un float
Miquel Bofill, IMAE – UdG ProPro – Conceptes de OOP 4 / 22
Herència vs Subtipatge
Sobreescriptura i Sobrecàrrega
Conceptes de programació orientada a objectes Tipus aparent i tipus real
Assignació i lligam missatge-mètode
Utilització vs Refinament

Herència vs Subtipatge (3)

Definició de nous tipus en Java: classes i interfaces


extends ⇒ herència
extends, implements ⇒ subtipatge
Un altre exemple de subtipatge sense herència
public interface PilaCar {
...
}

public class PilaCarTaula implements PilaCar {


...
}

PilaCar p = new PilaCarTaula(); // PilaCarTaula es subtipus


// de PilaCar i no hereta
Miquel Bofill, IMAE – UdG ProPro – Conceptes de OOP 5 / 22
Herència vs Subtipatge
Sobreescriptura i Sobrecàrrega
Conceptes de programació orientada a objectes Tipus aparent i tipus real
Assignació i lligam missatge-mètode
Utilització vs Refinament

Sobreescriptura i Sobrecàrrega

Definició (Signatura d’un mètode)


Nom del mètode + tipus, ordre i nombre de paràmetres.
f(int,char) 6= g(int,char) 6= g(char,int) 6= g(char,int,int)

Definició (Sobreescriptura)
Substitució d’un mètode heretat per un altre amb idèntica
signatura.

Definició (Sobrecàrrega)
Existència dins un mateix àmbit de visibilitat de mètodes amb
mateix nom i
diferent signatura.
Miquel Bofill, IMAE – UdG ProPro – Conceptes de OOP 6 / 22
Herència vs Subtipatge
Sobreescriptura i Sobrecàrrega
Conceptes de programació orientada a objectes Tipus aparent i tipus real
Assignació i lligam missatge-mètode
Utilització vs Refinament

Tipus aparent i tipus real

Donat un identificador (variable, paràmetre)


Tipus aparent (tipus estàtic) és el tipus indicat a la declaració.
Tipus real (tipus dinàmic) és el tipus que té l’objecte
referenciat per l’identificador: l’utilitzat en el new.
El tipus real sempre és un subtipus de l’aparent.
Exemple
public interface Punt {...}
public class Punt2D implements Punt {...}
public class Punt3D extends Punt2D {...}

dibuixa(new Punt2D(0.0,3.0));
dibuixa(new Punt3D(2.5,4.3,0.0));

void dibuixa(Punt p) { // Tipus aparent de p: Punt


if (p instanceof Punt3D) ...
else if (p instanceof Punt2D) ...
}
Miquel Bofill, IMAE – UdG ProPro – Conceptes de OOP 7 / 22
Herència vs Subtipatge
Sobreescriptura i Sobrecàrrega
Conceptes de programació orientada a objectes Tipus aparent i tipus real
Assignació i lligam missatge-mètode
Utilització vs Refinament

Assignació

Recordem que si un tipus S és subtipus de T (S ≤ T ),


aleshores una expressió de tipus S es pot usar a tot arreu on
s’espera una expressió de tipus T .
Predefinit en tipus elementals (p.ex. int ≤ float)
Definit per l’usuari en base a extends o implements (p.ex.
Punt3D ≤ Punt2D ≤ Punt)
La relació ≤ és reflexiva (p.ex. Punt3D ≤ Punt3D) i transitiva
(p.ex. Punt3D ≤ Punt)
Podem assignar (passar com a paràmetre) un objecte de tipus
S a un identificador declarat de tipus T sempre i quan S ≤ T .

Miquel Bofill, IMAE – UdG ProPro – Conceptes de OOP 8 / 22


Herència vs Subtipatge
Sobreescriptura i Sobrecàrrega
Conceptes de programació orientada a objectes Tipus aparent i tipus real
Assignació i lligam missatge-mètode
Utilització vs Refinament

Lligam missatge-mètode

Quan fem
objecte.nomMetode(p1,...,pn )
diem que estem enviant un missatge a l’objecte.
Quin mètode executarà l’objecte en rebre el missatge?
Evidentment, un mètode amb el mateix nom que el missatge,
però. . .

Miquel Bofill, IMAE – UdG ProPro – Conceptes de OOP 9 / 22


Herència vs Subtipatge
Sobreescriptura i Sobrecàrrega
Conceptes de programació orientada a objectes Tipus aparent i tipus real
Assignació i lligam missatge-mètode
Utilització vs Refinament

Lligam missatge-mètode

Quan fem
objecte.nomMetode(p1,...,pn )
diem que estem enviant un missatge a l’objecte.
Quin mètode executarà l’objecte en rebre el missatge?
Evidentment, un mètode amb el mateix nom que el missatge,
però. . .
I si hi ha sobreescriptura?

Miquel Bofill, IMAE – UdG ProPro – Conceptes de OOP 9 / 22


Herència vs Subtipatge
Sobreescriptura i Sobrecàrrega
Conceptes de programació orientada a objectes Tipus aparent i tipus real
Assignació i lligam missatge-mètode
Utilització vs Refinament

Lligam missatge-mètode

Quan fem
objecte.nomMetode(p1,...,pn )
diem que estem enviant un missatge a l’objecte.
Quin mètode executarà l’objecte en rebre el missatge?
Evidentment, un mètode amb el mateix nom que el missatge,
però. . .
I si hi ha sobreescriptura?
I si hi ha sobrecàrrega?

Miquel Bofill, IMAE – UdG ProPro – Conceptes de OOP 9 / 22


Herència vs Subtipatge
Sobreescriptura i Sobrecàrrega
Conceptes de programació orientada a objectes Tipus aparent i tipus real
Assignació i lligam missatge-mètode
Utilització vs Refinament

Lligam missatge-mètode

Quan fem
objecte.nomMetode(p1,...,pn )
diem que estem enviant un missatge a l’objecte.
Quin mètode executarà l’objecte en rebre el missatge?
Evidentment, un mètode amb el mateix nom que el missatge,
però. . .
I si hi ha sobreescriptura?
I si hi ha sobrecàrrega?
Per triar el mètode, es tindrà en compte:
El tipus aparent de l’objecte receptor del missatge
. . . o el tipus real de l’objecte receptor del missatge?
El tipus aparent dels paràmetres
. . . o el tipus real dels paràmetres?
En això cada llenguatge de programació és diferent!
Miquel Bofill, IMAE – UdG ProPro – Conceptes de OOP 9 / 22
Herència vs Subtipatge
Sobreescriptura i Sobrecàrrega
Conceptes de programació orientada a objectes Tipus aparent i tipus real
Assignació i lligam missatge-mètode
Utilització vs Refinament

Lligam missatge-mètode del Java

class Llista {
public Llista unio(Llista l) [1]
{ codi per fer la unio de dues llistes }
}

class LlistaOrd extends Llista {


public LlistaOrd unio(LlistaOrd l) [2]
{ codi per fer la unio de dues llistes ordenades }
}

Miquel Bofill, IMAE – UdG ProPro – Conceptes de OOP 10 / 22


Herència vs Subtipatge
Sobreescriptura i Sobrecàrrega
Conceptes de programació orientada a objectes Tipus aparent i tipus real
Assignació i lligam missatge-mètode
Utilització vs Refinament

Lligam missatge-mètode del Java (2)

Llista = new Llista();

Llista = new LlistaOrd();

LlistaOrd = new LlistaOrd();

tipus aparent tipus real

Miquel Bofill, IMAE – UdG ProPro – Conceptes de OOP 11 / 22


Herència vs Subtipatge
Sobreescriptura i Sobrecàrrega
Conceptes de programació orientada a objectes Tipus aparent i tipus real
Assignació i lligam missatge-mètode
Utilització vs Refinament

Lligam missatge-mètode del Java (3)

Bé

.unio( ) executa [1]


.unio( ) executa [1]
.unio( ) executa [2]

No tan bé?

.unio( ) executa [1]


.unio( ) executa [1]
.unio( ) executa [1]

Miquel Bofill, IMAE – UdG ProPro – Conceptes de OOP 12 / 22


Herència vs Subtipatge
Sobreescriptura i Sobrecàrrega
Conceptes de programació orientada a objectes Tipus aparent i tipus real
Assignació i lligam missatge-mètode
Utilització vs Refinament

Lligam missatge-mètode del Java (4)

Tal com és


receptor

paràmetre [1] [1] [1]


[1] [1] [1]
[1] [1] [2]

Tal com podria (hauria de?) ser


receptor

paràmetre [1] [1] [1]


[1] [2] [2]
[1] [2] [2]
Miquel Bofill, IMAE – UdG ProPro – Conceptes de OOP 13 / 22
Herència vs Subtipatge
Sobreescriptura i Sobrecàrrega
Conceptes de programació orientada a objectes Tipus aparent i tipus real
Assignació i lligam missatge-mètode
Utilització vs Refinament

Lligam missatge-mètode del Java (5)

COM FUNCIONA
1 En temps de compilació es determina la signatura S del
mètode “més proper” al missatge, considerant el tipus aparent
del receptor i dels paràmetres del missatge.
2 En temps d’execució es busca un mètode amb signatura S,
“pujant en la jerarquia” a partir del tipus real del receptor.

Miquel Bofill, IMAE – UdG ProPro – Conceptes de OOP 14 / 22


Herència vs Subtipatge
Sobreescriptura i Sobrecàrrega
Conceptes de programació orientada a objectes Tipus aparent i tipus real
Assignació i lligam missatge-mètode
Utilització vs Refinament

Lligam missatge-mètode del Java (5)

COM FUNCIONA
1 En temps de compilació es determina la signatura S del
mètode “més proper” al missatge, considerant el tipus aparent
del receptor i dels paràmetres del missatge.
2 En temps d’execució es busca un mètode amb signatura S,
“pujant en la jerarquia” a partir del tipus real del receptor.
Tots els compiladors utilitzen tipus aparents en temps de
compilació. Les diferències apareixen en temps d’execució.
Tipus de lligam Usa (temps exec.) Llenguatge
Static binding Tipus aparents C++, C#, . . .
Dynamic binding Tipus real receptor,
amb single dispatching tipus aparent paràm. Java, C++(virtual)
amb multiple dispatch. tipus real paràm. Multijava
Miquel Bofill, IMAE – UdG ProPro – Conceptes de OOP 14 / 22
Herència vs Subtipatge
Sobreescriptura i Sobrecàrrega
Conceptes de programació orientada a objectes Tipus aparent i tipus real
Assignació i lligam missatge-mètode
Utilització vs Refinament

Lligam missatge-mètode del Java (6)

Per què el compilador utilitza els tipus aparents en temps de


compilació?

Miquel Bofill, IMAE – UdG ProPro – Conceptes de OOP 15 / 22


Herència vs Subtipatge
Sobreescriptura i Sobrecàrrega
Conceptes de programació orientada a objectes Tipus aparent i tipus real
Assignació i lligam missatge-mètode
Utilització vs Refinament

Lligam missatge-mètode del Java (6)

Per què el compilador utilitza els tipus aparents en temps de


compilació?
Es podria saber, en temps de compilació, quin serà el tipus
real dels objectes en temps d’execució?

Miquel Bofill, IMAE – UdG ProPro – Conceptes de OOP 15 / 22


Herència vs Subtipatge
Sobreescriptura i Sobrecàrrega
Conceptes de programació orientada a objectes Tipus aparent i tipus real
Assignació i lligam missatge-mètode
Utilització vs Refinament

Lligam missatge-mètode del Java (6)

Per què el compilador utilitza els tipus aparents en temps de


compilació?
Es podria saber, en temps de compilació, quin serà el tipus
real dels objectes en temps d’execució? NO
void omplir(PilaCar p, char delim) {
... p.empilar(c); ...}
No podem saber si p serà una PilaCarTaula, una
PilaCarDinamica, o qualsevol altre subtipus (que potser en
aquest moment ni tan sols existeix).

Miquel Bofill, IMAE – UdG ProPro – Conceptes de OOP 15 / 22


Herència vs Subtipatge
Sobreescriptura i Sobrecàrrega
Conceptes de programació orientada a objectes Tipus aparent i tipus real
Assignació i lligam missatge-mètode
Utilització vs Refinament

Lligam missatge-mètode del Java (6)

Per què el compilador utilitza els tipus aparents en temps de


compilació?
Es podria saber, en temps de compilació, quin serà el tipus
real dels objectes en temps d’execució? NO
void omplir(PilaCar p, char delim) {
... p.empilar(c); ...}
No podem saber si p serà una PilaCarTaula, una
PilaCarDinamica, o qualsevol altre subtipus (que potser en
aquest moment ni tan sols existeix).
El tipus aparent s’usa per determinar quines crides són legals
(saber si existirà mètode en temps d’execució).
En temps d’execució, el tipus real serà sempre un subtipus de
l’aparent, i per tant tindrà el mètode de l’aparent (ja sigui per
herència, o sobreescrit).
Miquel Bofill, IMAE – UdG ProPro – Conceptes de OOP 15 / 22
Herència vs Subtipatge
Sobreescriptura i Sobrecàrrega
Conceptes de programació orientada a objectes Tipus aparent i tipus real
Assignació i lligam missatge-mètode
Utilització vs Refinament

Utilització vs Refinament (o Composició vs Herència)

Vegem primer què és la composició. La composició és una


relació d’associació entre objectes.

Vol Reserva

+ afegirReserva (r:Reserva):void + anotarVol (v:Vol ):void


*
+ anularReserva (r:Reserva):void + esborrarVol ():void

+ reserves ():Iterator + vol ():Vol

Miquel Bofill, IMAE – UdG ProPro – Conceptes de OOP 16 / 22


Herència vs Subtipatge
Sobreescriptura i Sobrecàrrega
Conceptes de programació orientada a objectes Tipus aparent i tipus real
Assignació i lligam missatge-mètode
Utilització vs Refinament

Utilització vs Refinament (o Composició vs Herència)

Vegem primer què és la composició. La composició és una


relació d’associació entre objectes.

Vol Reserva

+ afegirReserva (r:Reserva):void + anotarVol (v:Vol ):void


*
+ anularReserva (r:Reserva):void + esborrarVol ():void

+ reserves ():Iterator + vol ():Vol

En Java és molt fàcil expressar aquesta relació, usant la classe


Vector (taula extensible).
Per cada Vol tindrem un Vector d’objectes de tipus Reserva
Per cada Reserva, una referència al seu Vol.

Miquel Bofill, IMAE – UdG ProPro – Conceptes de OOP 16 / 22


Herència vs Subtipatge
Sobreescriptura i Sobrecàrrega
Conceptes de programació orientada a objectes Tipus aparent i tipus real
Assignació i lligam missatge-mètode
Utilització vs Refinament

Utilització vs Refinament (2)

Gràficament:
Vol v

Vector reserves
...

Reserva c Vol vol


...

Reserva b Vol vol


...

Reserva a Vol vol


...

Miquel Bofill, IMAE – UdG ProPro – Conceptes de OOP 17 / 22


Herència vs Subtipatge
Sobreescriptura i Sobrecàrrega
Conceptes de programació orientada a objectes Tipus aparent i tipus real
Assignació i lligam missatge-mètode
Utilització vs Refinament

Utilització vs Refinament (3)

Codi
public class Vol {
protected Vector reserves = new Vector();
...
public void afegirReserva(Reserva r) {
reserves.addElement(r); }
public void anularReserva(Reserva r) {
reserves.removeElement(r); }
public Iterator reserves() {
return reserves.iterator(); }
}
public class Reserva {
protected Vol vol;
...
public void anotarVol(Vol v) { vol = v; }
public void esborrarVol() { vol = null; }
public Vol vol() { return vol; }
}

Miquel Bofill, IMAE – UdG ProPro – Conceptes de OOP 18 / 22


Herència vs Subtipatge
Sobreescriptura i Sobrecàrrega
Conceptes de programació orientada a objectes Tipus aparent i tipus real
Assignació i lligam missatge-mètode
Utilització vs Refinament

Utilització vs Refinament (4)

Exemple d’utilització
Vol v = new Vol();
Reserva a = new Reserva();
Reserva b = new Reserva();
Reserva c = new Reserva();
v.afegirReserva(a);
a.anotarVol(v);
v.afegirReserva(b);
b.anotarVol(v);
v.afegirReserva(c);
c.anotarVol(v);

Miquel Bofill, IMAE – UdG ProPro – Conceptes de OOP 19 / 22


Herència vs Subtipatge
Sobreescriptura i Sobrecàrrega
Conceptes de programació orientada a objectes Tipus aparent i tipus real
Assignació i lligam missatge-mètode
Utilització vs Refinament

Utilització vs Refinament (5)

La utilització (composició) pot ser una bona alternativa al


refinament (herència).
L’herència pot ser adequada quan hi ha una relació
d’especialització, però no si a més hi ha una relació de rol.
P.ex. considerem Persona i les seves especialitzacions:
Persona

Soci Empleat

Aquı́ el refinament (herència) no és gens adequat. . .

Miquel Bofill, IMAE – UdG ProPro – Conceptes de OOP 20 / 22


Herència vs Subtipatge
Sobreescriptura i Sobrecàrrega
Conceptes de programació orientada a objectes Tipus aparent i tipus real
Assignació i lligam missatge-mètode
Utilització vs Refinament

Utilització vs Refinament (6)

Poden haver-hi canvis de rol!


Un Empleat pot passar a ser Soci. Solucions?
1 Esborrar un objecte de tipus Empleat i crear-ne un de tipus
Soci.
Possible problema de pèrdua d’informació!
2 Crear el tipus SociEmpleat
Persona

Soci Empleat

SociEmpleat

Miquel Bofill, IMAE – UdG ProPro – Conceptes de OOP 21 / 22


Herència vs Subtipatge
Sobreescriptura i Sobrecàrrega
Conceptes de programació orientada a objectes Tipus aparent i tipus real
Assignació i lligam missatge-mètode
Utilització vs Refinament

Utilització vs Refinament (7)

Solució alternativa (millor): Composició de rols


“Una persona pot portar diferents barrets”

Persona
RolPersona

+ nom ():String 1..*


+ numero ():int
+ adreca ():String

Soci Empleat

+ capital ():float + nivellAutoritzacio ():int

Amb la composició, afegir un nou rol no costa res.


Miquel Bofill, IMAE – UdG ProPro – Conceptes de OOP 22 / 22

You might also like