Ho aggiunto al codice una classe astratta Meccanico e una classe derivata ApprendistaMeccanico.
Non badiamo a ciò che riguarda i cuochi, per il momento.
#include "iostream" using namespace std; class Cuoco{ public: void Pollo(){ cout << "Cucino il pollo col rosmarino" << endl; getchar(); } virtual void Pasta(char * condimento)=0; }; class Apprendista: public Cuoco{ public: void Pasta(char * condimento){ cout << "Io cucino la pasta nella pentola a pressione con " << condimento << endl; getchar(); } void Pasta(char * condimento, char * condimento2){ cout << "Io cucino la pasta nella pentola a pressione con " << condimento << " e con " << condimento2 << endl; getchar(); } void Pollo(){ cout << "Io cucino il pollo con l'origano" << endl; getchar(); } }; class Apprendista2: public Cuoco{ public: void Pasta(char * condimento){ cout << "Io cucino la pasta con " << condimento << endl; getchar(); } void Pasta(char * condimento, char * condimento2){ cout << "Io cucino la pasta con " << condimento << " e con " << condimento2 << endl; getchar(); } }; class Meccanico{ public: void UsaIlCric(){ cout << "io uso il cric per sollevare l'auto" << endl; getchar(); } virtual void riparaMotore()=0; virtual void riparaCambio()=0; virtual void riparaFreni()=0; }; class ApprendistaMeccanico: public Meccanico{ public: void riparaMotore(){ cout << "io riparo il motore dell'auto" << endl; getchar(); } void riparaCambio(){ cout << "io riparo il cambio dell'auto" << endl; getchar(); } void riparaFreni(){ cout << "io riparo i freni dell'auto" << endl; getchar(); } }; void CucinaPasta(Cuoco * n, char * condimento){ n->Pasta(condimento); } void CucinaPollo(Cuoco *n){ n->Pollo(); } void RiparaIFreniDellAutomobile(ApprendistaMeccanico * n){ n->riparaFreni(); } void main(){ ApprendistaMeccanico * Alfonso= new ApprendistaMeccanico(); RiparaIFreniDellAutomobile(Alfonso); }
io riparo i freni dell'auto
Ora, però, anche un apprendista cuoco (o meglio una classe di apprendisti cuochi...) ha la capacità di riparare i freni dell'auto.
Dunque la funzione RiparaIFreniDellAutomobile potrebbe includere anche lui, anche se non è un apprendista meccanico.
Però il tipo del parametro è apprendista meccanico.
Visto che la stessa funzione è condivisa da tipi differenti, possiamo creare un'interfaccia, implementata sia da Apprendista2 sia da ApprendistaMeccanico, e dare in pasto alla funzione RiparaIFreniDellAutomobile un parametro del tipo di questa interfaccia piuttosto che del tipo di una classe ApprendistaMeccanico.
In C++ le interfacce non esistono, ma dato che esiste l'ereditarietà multipla si può fare così...
#include "iostream" using namespace std; class Cuoco{ public: void Pollo(){ cout << "Cucino il pollo col rosmarino" << endl; getchar(); } virtual void Pasta(char * condimento)=0; }; class RiparatoreFreni{ public: virtual void riparaFreni()=0; }; class Apprendista: public Cuoco{ public: void Pasta(char * condimento){ cout << "Io cucino la pasta nella pentola a pressione con " << condimento << endl; getchar(); } void Pasta(char * condimento, char * condimento2){ cout << "Io cucino la pasta nella pentola a pressione con " << condimento << " e con " << condimento2 << endl; getchar(); } void Pollo(){ cout << "Io cucino il pollo con l'origano" << endl; getchar(); } }; class Apprendista2: public Cuoco, public RiparatoreFreni{ public: void Pasta(char * condimento){ cout << "Io cucino la pasta con " << condimento << endl; getchar(); } void Pasta(char * condimento, char * condimento2){ cout << "Io cucino la pasta con " << condimento << " e con " << condimento2 << endl; getchar(); } void riparaFreni(){ cout << "io so riparare i freni dell'auto anche se sono un apprendista cuoco" << endl; getchar(); } }; class Meccanico{ public: void UsaIlCric(){ cout << "io uso il cric per sollevare l'auto" << endl; getchar(); } virtual void riparaMotore()=0; virtual void riparaCambio()=0; virtual void riparaFreni()=0; }; class ApprendistaMeccanico: public Meccanico, public RiparatoreFreni{ public: void riparaMotore(){ cout << "io riparo il motore dell'auto" << endl; getchar(); } void riparaCambio(){ cout << "io riparo il cambio dell'auto" << endl; getchar(); } void riparaFreni(){ cout << "io riparo i freni dell'auto" << endl; getchar(); } }; void CucinaPasta(Cuoco * n, char * condimento){ n->Pasta(condimento); } void CucinaPollo(Cuoco *n){ n->Pollo(); } void RiparaIFreniDellAutomobile(RiparatoreFreni * n){ n->riparaFreni(); } void main(){ ApprendistaMeccanico * Alfonso= new ApprendistaMeccanico(); Apprendista2 * Armando= new Apprendista2(); RiparaIFreniDellAutomobile(Alfonso); RiparaIFreniDellAutomobile(Armando); }...cioè ho creato una classe astratta RiparatoreFreni, e ho fatto sì che le due classi ApprendistaMeccanico e Apprendista2 ereditassero anche da questa, in modo da poter richiamare poi nella funzione RiparaIFreniDellAuto il tipo di questa classe astratta, cosicché il metodo riparaFreni() venga eseguito da ambedue le istanze di classi che ereditano da questa classe astratta.
In pratica, ho usato un'interfaccia!
Da notare che la classe astratta Meccanico presenta anche un metodo non astratto, quello relativo all'uso del cric, perché questo è assolutamente uguale per qualsiasi classe di apprendista meccanico, anche se poi i metodi di riparazione motore, cambio e freni se lo implementano ogni classe per conto suo.
Nessun commento:
Posta un commento