1 Simulated multiple inheritance Sandro Pedrazzini Approfondimento Simulated multiple inheritance in...

Preview:

Citation preview

1 Simulated multiple inheritanceSandro Pedrazzini

Approfondimento

Simulated multiple inheritance in Java

2 Simulated multiple inheritanceSandro Pedrazzini

Multiple inheritance in Java

• In Java esiste solo eredità semplice (eredità di implementazione)

• Una classe può però rappresentare più tipi (implementare più interfacce)

• Ogni relazione di ereditarietà può essere ricondotta a delegation

3 Simulated multiple inheritanceSandro Pedrazzini

Classi e tipi

PersistentObjFigura

Triangolo

ElasticObject

public interface PersistentObject { void write(); void read();}

public interface ElasticObject { void enlarge(int offset); void restrict(int offset);}

public class Triangolo extends Figura implements PersistentObject, ElasticObject { ...}

4 Simulated multiple inheritanceSandro Pedrazzini

Delegation

Utilizzo della composizione al posto dell'ereditarietàottenendo lo stesso grado di riutilizzo.

Dalla relazione "is-a" alla relazione "has-a"

Nel caso ideale basterebbe assemblare le varie componentiper realizzare una nuova funzionalità.

FilledBox

Box

FilledBox

Box

move() move()

box.move()

move()

5 Simulated multiple inheritanceSandro Pedrazzini

Problema

• Necessità di estendere contemporaneamente più implementazioni

Person (caratteristiche di una persona)

Employment(dettagli di una persona impiegata)

Employee(caratteristiche complete di un impiegato)

6 Simulated multiple inheritanceSandro Pedrazzini

Person

public class Person { private String fName; private Date fBirthDate;

public Person(String name, Date birthDate) { fName = name; fBirthDate = birthDate; }

public String getName(){ return fName; }

public Date getBirthDate(){ return fBirthDate; }}

7 Simulated multiple inheritanceSandro Pedrazzini

Employment

public class Employment { private float fSalary; private Date fHireDate;

public Employment(float salary, Date hireDate) { fSalary = salary; fHireDate = hireDate; }

public float getSalary() { return fSalary; }

public Date getHireDate() { return fHireDate; }}

8 Simulated multiple inheritanceSandro Pedrazzini

Desiderato

public class Employee extends Person, Employment { ...}

Questo non è però possibile in Java

Soluzione:

- usare delegation per riutilizzare la funzionalità - aggiungere interface per mantenere il polimorfismo

=> Proxy / Decorator

9 Simulated multiple inheritanceSandro Pedrazzini

Extract interfaces (1)

public interface IEmployment { float getSalary(); Date getHireDate();}

public class Employment implements IEmployment { ...}

10 Simulated multiple inheritanceSandro Pedrazzini

Extract interfaces (2)

public interface IPerson { String getName(); Date getBirthDate();}

public class Person implements IPerson { ...}

11 Simulated multiple inheritanceSandro Pedrazzini

Utilizzo delle interface

public class Employee implements IPerson, IEmployment { ...}

• In Java una classe può rappresentare più tipi contemporaneamente

12 Simulated multiple inheritanceSandro Pedrazzini

Utilizzo delle interface (2)

• Utilizzando le interface otteniamo riutilizzo di design

• Come riutilizzare codice?

• Come sfruttare le implementazioni esistenti di Person e Employment?

13 Simulated multiple inheritanceSandro Pedrazzini

Riutilizzo delle classi esistenti

public class Employee extends Person implements IPerson, IEmployment { ...}

oppure:

public class Employee extends Employment implements IPerson, IEmployment { ...}

14 Simulated multiple inheritanceSandro Pedrazzini

Sfruttamento multiplo

• La soluzione proposta permette di sfruttare attraverso ereditarietà solo una delle implementazioni presenti nelle due classi già disponibili (Person oppure Employment)

• Per sfruttare la seconda (o eventualmente anche entrambe) potremmo usare la delegation

• Il polimorfismo è garantito dal fatto di aver implementato le due interfacce

15 Simulated multiple inheritanceSandro Pedrazzini

Sfruttamento multiplo (variante 1)

IPersonPerson

Employee

IEmployment

Employment

16 Simulated multiple inheritanceSandro Pedrazzini

Sfruttamento multiplo (variante 2)

IPerson

Person

Employee

IEmployment

Employment

17 Simulated multiple inheritanceSandro Pedrazzini

Implementazione (variante 1)

public class Employee extends Person implements IPerson, IEmployment {

private IEmployment fEmploymentMixin;

public Employee(String name, Date birthDate, float salary, Date hireDate) { super(name, birthDate); fEmploymentMixin = new Employment(salary, hireDate); }

public float getSalary() { return fEmploymentMixin.getSalary(); }

public Date getHireDate() { return fEmploymentMixin.getHireDate(); }}

18 Simulated multiple inheritanceSandro Pedrazzini

Overriding

• Consideriamo di dover estendere o modificare il comportamento di una classe da cui ereditiamo

• Person (eredità diretta): semplice overriding

• Employment (delegation): internal class + semplice overriding

19 Simulated multiple inheritanceSandro Pedrazzini

Overriding di Person (1)

• Consideriamo di voler garantire l’immutabilità di Employee

• Per far questo dobbiamo modificare il metodo getBirthDate()

• Quello nuovo deve restituirci non il riferimento all’oggetto Date, bensì un nuovo oggetto Date (clone)

20 Simulated multiple inheritanceSandro Pedrazzini

Overriding di Person (2)

public class Employee extends Person implements IPerson, IEmployment { private IEmployment fEmploymentMixin;

public Employee(String name, Date birthDate, float salary, Date hireDate) { super(name, birthDate);

fEmploymentMixin = new Employment(salary, hireDate); }

public float getSalary() { return fEmploymentMixin.getSalary(); }

public Date getHireDate() { return fEmploymentMixin.getHireDate(); }

@Override public Date getBirthDate() { return (Date) super.getBirthDate().clone(); }}

21 Simulated multiple inheritanceSandro Pedrazzini

Overriding di Employment (1)

• Sempre considerando di voler garantire l’immutabilità di Employee, dobbiamo modificare anche il metodo getHireDate()

• Quello nuovo deve restituirci non il riferimento all’oggetto Date, bensì un nuovo oggetto Date (clone)

• getHireDate() è un metodo dell’oggetto delegato

22 Simulated multiple inheritanceSandro Pedrazzini

Overriding di Employment (2)

• Procedimento:

– Creiamo una classe interna EmploymentMixin che erediti da Employment e riscriva il metodo getHireDate()

– Utilizziamo un riferimento ad un oggetto di EmploymentMixin all’interno della classe Employee

23 Simulated multiple inheritanceSandro Pedrazzini

Overriding di Employment (2)

• Classe interna che estende Employment

private static class EmploymentMixin extends Employment {

public EmploymentMixin(float salary, Date hireDate) { super(salary, hireDate); }

@Override public Date getHireDate() { return (Date) super.getHireDate().clone(); } }

24 Simulated multiple inheritanceSandro Pedrazzini

Overriding di Employment (3)

public class Employee extends Person implements IPerson, IEmployment{ private IEmployment fEmploymentMixin;

public Employee(String name, Date birthDate, float salary, Date hireDate) { super(name, birthDate);

fEmploymentMixin = new EmploymentMixin(salary, hireDate); }

...

private static class EmploymentMixin extends Employment { ... }}

25 Simulated multiple inheritanceSandro Pedrazzini

Overriding di Employment (4)

IPersonPerson

Employee

IEmployment

EmploymentMixin

Employment

Recommended