Skill Factory
Tutte le categorie
Introduzione alla logica degli oggetti - Lezione 5
Gino Visciano |
Skill Factory - 24/11/2018 14:02:07 | in Tutorials
Nelle lezioni precedenti abbiamo parlato di Polimorfismo dei metodi, definendo l'Overload lezione 3 e l'Override lezione 4, in questa lezione parleremo di Polimorfismo degli oggetti.
Iniziamo intanto a dire che due oggetti si dicono Polimorfi se sono simili. Gli oggetti diventano simili quando si verifica uno dei seguenti casi:
1) una classe eredita un'altra classe;
2) più classi implementano la stessa interfaccia.
Nell'esempio seguente, le classi Persona, Dipendente, Manager e Dirigente, sono simili perché si ereditano tra loro:
La classe Persona è la più generica, mentre la classe Dirigente è la più specializzata.
Nell'esempio seguente, le classi Rettangolo, Triangolo e Cerchio sono simili perché implementano la stessa interfaccia:
In C++ l'ereditarietà è multipla, quindi le interfacce non esistono, al loro posto si usano le classi astratte, il polimorfismo basto sulle intefacce esiste solo in linguaggi di programmazione come Java e C#, dove l'ereditarietà è singola e le interfacce si usano per superare questo limite.
Quando gli oggetti sono simili, diventano possibili operazioni di questo tipo:
Persona *dirigente=new Dirigente();
oppure
IFiguraGeometrica *triangolo=new Triangolo();
Nel primo esempio abbiamo istanziato un oggetto di tipo Dirigente, ma la variabile (puntatore) che contiene l'indirizzo dell'oggetto creato è di tipo Persona, un tipo molto più generico.
Nel secondo esempio abbiamo istanziato un oggetto di tipo Triangolo, ma la variabile (puntatore) che contiene l'indirizzo dell'oggetto creato è di tipo IFiguraGeometrica, che corrisponde ad una interfaccia oppure una classe astratta.
Questa proprietà degli oggetti simili è molto utile quando volete passare allo stesso metodo oggetti simili;
COME PASSARE OGGETTI SIMILI AD UN METODO
Il Polimorfismo degli oggetti permette di passare oggetti simili allo stesso metodo, per evitare di creare un metodo per ogni tipo di oggetto da gestire.
Immaginate di voler stampare gli attributi di più oggetti di tipo diverso: Dipendente, Manager e Dirigente.
Senza il polimorfismo dovremmo creare tre metodi diversi:
stampaDipendente(Dipendente dipendente);
stampaManager(Manager manager);
stampaDirigente(Dirigente dirigente);
Invece, sfruttando il polimorfismo, possiamo creare un unico metodo a cui passiamo tutti e tre i tipi di oggetti simili, basta indicare come argomento il tipo più generico, che in questo caso è il Dipendente:
stampa(Dipendente dipendente);
questa sarebbe una semplificazione importante per chi deve stampare, perché dovrebbe ricordare il nome di un solo metodo anzicché tre nomi diversi.
Naturalmente il metodo stampa dovrà essere implementato in modo che riconosca quali sono i tipi di oggetti passati come argomenti e stamaprli in modo corretto.
L'esempio seguente mostra come creare il metodo getInformazioni con C++:
#include <string>
#include <iostream>
#include <sstream>
#include <typeinfo>
using namespace std;
class Persona {
private:
string classe;
string nome;
string cognome;
int eta;
public:
void setNome(string nome){
this->nome=nome;
};
void setCognome(string cognome){
this->cognome=cognome;
};
void setEta(int eta){
this->eta=eta;
};
string getNome(){
return nome;
}
string getCognome(){
return cognome;
}
int getEta(){
return eta;
}
// getClasse() restituisce il tipo di classe dell'oggetto corrente
string getClasse(){
return this->classe;
}
/******
setClasse() imposta l'attributo classe uguale al tipo di classe corrente, usando la funzione typeid(*this).name().
*this è il puntatore che identifica l'oggetto corrente, setClasse() deve essere virtuale perchè se viene
ereditato ,quando è invocato dalla classe derivata, deve comportarsi come se appartenesse ad essa, altrimenti
il tipo restituito da setClasse() è sempre quello della classe più generica in cui è stato implementato.
******/
virtual void setClasse(){
this->classe=typeid(*this).name();
}
Persona(){
setClasse();
};
Persona(string nome, string cognome, int eta){
this->nome=nome;
this->cognome=cognome;
this->eta=eta;
setClasse();
}
};
// La classe Dipendente eredita la classe Persona e diventano simili
class Dipendente : public Persona {
private:
string ruolo;
double stipendio;
public:
void setRuolo(string ruolo){
this->ruolo=ruolo;
};
string getRuolo(){
return ruolo;
}
void setStipendio(double stipendio){
this->stipendio=stipendio;
};
double getStipendio(){
return stipendio;
}
Dipendente(){
setClasse(); // Ereditato dalla classe Persona, assegna all'attributo classe il tipo Dipendente
};
Dipendente(string nome, string cognome, int eta, string ruolo, double stipendio):Persona(nome, cognome, eta){
this->ruolo=ruolo;
this->stipendio=stipendio;
setClasse(); // Ereditato dalla classe Persona, assegna all'attributo classe il tipo Dipendente
}
};
// La classe Manager eredita la classe Dipendente e diventano simili, quindi per la proprietà transitiva Manager e simile anche a Persona
class Manager : public Dipendente {
private:
string areaResponsabilita;
public:
void setAreaResponsabilita(string areaResponsabilita){
this->areaResponsabilita=areaResponsabilita;
};
string getAreaResponsabilita(){
return areaResponsabilita;
}
Manager(){
setClasse();
};
Manager(string nome, string cognome, int eta, string ruolo, double stipendio, string areaResponsabilita):
Dipendente(nome, cognome, eta, ruolo, stipendio){
this->areaResponsabilita=areaResponsabilita;
setClasse();
}
};
// La classe Dirigente eredita la classe Manager e diventano simili, quindi per la proprietà transitiva Dirigente e simile anche a Dipendente e Persona
class Dirigente : public Manager {
private:
string livelloFunzionale;
public:
void setLivelloFunzionale(string livelloFunzionale){
this->livelloFunzionale=livelloFunzionale;
};
string getLivelloFunzionale(){
return livelloFunzionale;
}
Dirigente(){
setClasse(); // Ereditato dalla classe Persona, assegna all'attributo classe il tipo Manager
};
Dirigente(string nome, string cognome, int eta, string ruolo, double stipendio, string areaResponsabilita,string livelloFunzionale):
Manager(nome, cognome, eta, ruolo, stipendio,areaResponsabilita){
this->livelloFunzionale=livelloFunzionale;
setClasse(); // Ereditato dalla classe Persona, assegna all'attributo classe il tipo Manager
}
};
class GestisciDipendenti {
public:
// Il Metodo getInformazioni può ricevere come argomento oggetti di tipo Dipendente oppure oggetti simili di tipo Manager o Dirigente
string getInformazioni(Dipendente *dipendente){
string infoPersona="";
stringstream sEta;
stringstream sStipendio;
string strEta,strStipendio;
sEta << dipendente->getEta();
sStipendio << dipendente->getStipendio();
strEta=sEta.str();
strStipendio=sStipendio.str();
// Se il puntatore *dipendente è di tipo Dirigente esegue uno static_cast a Dirigente e assegna all'attributo infoPersona le informazioni del Dirigente
if(dipendente->getClasse()==typeid(Dirigente).name()){
Dirigente *dirigente;
dirigente=static_cast<Dirigente *>(dipendente);
infoPersona = dirigente->getNome()+","+dirigente->getCognome()+","+strEta+","+dirigente->getRuolo()+","+strStipendio+","+
dirigente->getAreaResponsabilita()+","+dirigente->getLivelloFunzionale();
// Se il puntatore *dipendente è di tipo Manager esegue uno static_cast a Manager e assegna all'attributo infoPersona le informazioni del Manager
} else if(dipendente->getClasse()==typeid(Manager).name()){
Manager *manager;
manager=static_cast<Manager *>(dipendente);
infoPersona = manager->getNome()+","+manager->getCognome()+","+strEta+","+manager->getRuolo()+","+strStipendio+","+
manager->getAreaResponsabilita();
// Se il puntatore *dipendente è di tipo Dipendente assegna all'attributo infoPersona le informazioni del Dipendente
} else{
infoPersona = dipendente->getNome()+","+dipendente->getCognome()+","+strEta+","+dipendente->getRuolo()+","+strStipendio;
}
return infoPersona;
}
};
int main(){
// Istanzio oggetto di tipo Dipendente
Dipendente *dipendente=new Dipendente("Marco","Rossi",30,"Programmatore",100.58);
// Istanzio oggetto di tipo Manager
Manager *manager=new Manager("Franco","Verdi",50,"Direttore Generale",200.58,"CED");
// Istanzio oggetto di tipo Dirigente
Dirigente *dirigente=new Dirigente("Carlo","Bianchi",50,"Direttore Generale",200.58,"CED","F3");
// Istanzio oggetto di tipo GestisciDipendenti che contiene il metodo getInformazioni
GestisciDipendenti *gd=new GestisciDipendenti();
// Dato che gli oggetti di tipo Dipendente, Manger e Dirigente sono Polimorfi (simili), possono essere passati al metodo getInformazioni impostando come
// argomento del metodo il tipo più generico dei tre, il Dipendente: getInformazioni(Dipendente *dipendente)
cout << "1) Dipendente" <<endl;
cout << gd->getInformazioni(dipendente) << endl;
cout << "2) Manager" <<endl;
cout << gd->getInformazioni(manager) << endl;
cout << "3) Dirigente" << endl;
cout << gd->getInformazioni(dirigente) << endl;
}
COME CREARE OGGETTI SIMILI ATTRAVERSO L'UTILIZZO D'INTERFACCE O CLASSI ASTRATTE
Le interfacce e le classi astratte sono strutture di programmazione simili, perché entrambe contengono metodi astratti (non impelmentati) e non possono istanziare oggetti.
Le differenze principali tra loro sono due:
1) le classi astratte possono contenere anche metodi già implementati, come le normali classi, le interfacce no, a meno che non state usando Java 8 che permette d'implementare nelle interfacce anche metodi statici o di default;
2) le classi astratte si ereditano, mentre le interfacce s'implementano.
L'uso delle interfacce in alcuni linguaggi di programmazione ad oggetti come Java e C#, è necessario per superare il limite dell'ereditarietà è singola, che non permette di ereditare più classi contemporaneamente, mentre non è necessario in linguaggi di programmazione ad oggetti dove l'ereditarietà è multipla, come in C++.
In realtà le classi astratte sono pattern (soluzioni applicative), che permettono di creare metodi che usano il risultato di altri metodi, detti astratti, la cui logica (comportamento) verrà implementata in futuro in una classe derivata.
Oggetti che ereditano la stessa classe astratta oppure implementano la stessa interfaccia diventano polimorfi, cioè simili.
Immaginate di voler creare un'applicazione specializzata per calcolare il perimetro e l'area delle seguenti figure geometriche:
Le quattro figure geometriche sono simili perché hanno in comune le seguenti caratteristiche:
1) corrispondono tutte ad un tipo di figura geometrica;
2) hanno tutte due coordinate x ed y che identificano la posizione in un piano bidimensionale;
3) hanno tutte un colore;
4) hanno tutte un perimetro ed un'area, che vengono calcolati diversamente per ogni tipo di figura geometrica, quindi devono essere implementati nelle classi di riferimento.
Tutte queste caratteristiche comuni possono essere raggruppate in una classe astratta come mostra il Diagramma di Classe seguente:
Successivamente la classe astratta FiguraGeometrica può essere ereditata dalle classi derivate Quadrato, Rettangolo, Triangolo e Cerchio che diventano simili tra loro.
In queste classi dovranno essere implementati i metodi astratti perimetro ed area, come mostra il Diagramma di Classe seguente:
L'esempio seguente mostra come creare l'applicazione Geometria con C++, la classe FiguraGeometrica è una classe astratta che utilizza il metodo getInformazioni per restituire il perimetro e l'area delle figure geometriche istanziate.
Il metodo getInformazioni può usare i metodi perimetro ed area anche se non sono stati implementati perché sono astratti. Quando i due metodi verranno implementati nelle classi di riferimento forniranno il perimetro e l'area della figura geometrica corrente.
In C++ i metodi astrattti si dichiarano nel modo seguente:
virtual double perimetro()=0;
virtual double area()=0;
/*****************************
Applicazione Geometria.cpp
****************************/
#include <string>
#include <iostream>
#include <sstream>
#include <math.h>
using namespace std;
// Classe che permette di definire la posizione nel piano delle figure geometriche in base alle coordinate x ed y
class Point {
private:
int x,y;
public:
Point(int x, int y){
this->x=x;
this->y=y;
}
getX(){
return x;}
getY(){
return y;}
};
// Classe astratta che raggruppa la informazioni comuni a tutte le figure geometriche
class FiguraGeometrica {
private:
string tipoFigura;
Point *posizione;
string colore;
public:
string getTipoFigura(){
return tipoFigura;
}
Point * getPosizione(){
return posizione;
}
void setPosizione(Point *posizione){
this->posizione=posizione;}
string getColore(){
return colore;}
void setColore(string colore){
this->colore=colore;
}
string getInformazioni(){
stringstream sperimetro;
stringstream sarea;
stringstream sx;
stringstream sy;
sperimetro << perimetro(); // Utilizzo metodo astratto che verrà implementato successivamente nelle classi derivate
sarea << area(); // Utilizzo metodo astratto che verrà implementato successivamente nelle classi derivate
sx << posizione->getX();
sy << posizione->getY();
return tipoFigura+", posizione:"+sx.str()+", "+sy.str()+", "+colore+", perimetro:"+sperimetro.str()+", area:"+sarea.str();
}
virtual double perimetro()=0; // Metodo astratto
virtual double area()=0; // Metodo astratto
FiguraGeometrica(string tipoFigura,Point *posizione,string colore){
this->tipoFigura=tipoFigura;
this->posizione=posizione;
this->colore=colore;
}
};
// La classe Quadrato eredita la classe astratta FiguraGeometrica e diventa simile a tutte le altre classi che erediteranno questa classe.
class Quadrato: public FiguraGeometrica {
private:
double lato;
public:
double getLato(){
return lato;
}
void setLato(double lato){
this->lato=lato;
}
// Sovrascrittura del metodo perimetro richiamato dal metodo getInformazioni ereditato dalla classe FiguraGeometrica per ottenere il preimetro del Quadrato
double perimetro(){
return lato*4;}
// Sovrascrittura del metodo area richiamato dal metodo getInformazioni ereditato dalla classe FiguraGeometrica per ottenere l'area del Quadrato
double area(){
return pow(lato,2); // pow = potenza(base,esponete)
}
Quadrato(double lato,Point *posizione,string colore):FiguraGeometrica("Quadrato", posizione, colore){
this->lato=lato;
}
};
// La classe Rettangolo eredita la classe astratta FiguraGeometrica e diventa simile a tutte le altre classi che erediteranno questa classe.
class Rettangolo: public FiguraGeometrica {
private:
double latoMinore;
double latoMaggiore;
public:
double getLatoMinore(){
return latoMinore;
}
void setLatoMinire(double latoMinore){
this->latoMinore=latoMinore;
}
double getLatoMaggiore(){
return latoMaggiore;
}
void setLatoMaggiore(double latoMaggiore){
this->latoMaggiore=latoMaggiore;
}
// Sovrascrittura del metodo perimetro richiamato dal metodo getInformazioni ereditato dalla classe FiguraGeometrica per ottenere il preimetro del Rettangolo
double perimetro(){
return (latoMinore+latoMaggiore)*2;}
// Sovrascrittura del metodo area richiamato dal metodo getInformazioni ereditato dalla classe FiguraGeometrica per ottenere l'area del Rettangolo
double area(){
return latoMinore*latoMaggiore;
}
Rettangolo(double latoMinore,double latoMaggiore, Point *posizione,string colore):FiguraGeometrica("Rettangolo", posizione, colore){
this->latoMinore=latoMinore;
this->latoMaggiore=latoMaggiore;
}
};
// La classe Triangolo eredita la classe astratta FiguraGeometrica e diventa simile a tutte le altre classi che erediteranno questa classe.
class Triangolo: public FiguraGeometrica {
private:
double latoPrimo;
double latoSecondo;
double latoTerzo;
public:
double getLatoPrimo(){
return latoPrimo;
}
void setLatoPrimo(double latoPrimo){
this->latoPrimo=latoPrimo;
}
double getLatoSecondo(){
return latoSecondo;
}
void setLatoSecondo(double latoSecondo){
this->latoSecondo=latoSecondo;
}
double getLatoTerzo(){
return latoTerzo;
}
void setLatoTerzo(double latoTerzo){
this->latoTerzo=latoTerzo;
}
// Sovrascrittura del metodo perimetro richiamato dal metodo getInformazioni ereditato dalla classe FiguraGeometrica per ottenere il preimetro del Triangolo
double perimetro(){
return latoPrimo+latoSecondo+latoTerzo;
}
// Sovrascrittura del metodo area richiamato dal metodo getInformazioni ereditato dalla classe FiguraGeometrica per ottenere l'area del Triangolo
double area(){
// Formula di Erone
double semiPerimetro=perimetro()/2;
return sqrt(semiPerimetro*(semiPerimetro-latoPrimo)*(semiPerimetro-latoSecondo)*(semiPerimetro-latoTerzo));
}
Triangolo(double latoPrimo,double latoSecondo,double latoTerzo, Point *posizione,string colore):FiguraGeometrica("Triangolo", posizione, colore){
this->latoPrimo=latoPrimo;
this->latoSecondo=latoSecondo;
this->latoTerzo=latoTerzo;
}
};
// La classe Cerchio eredita la classe astratta FiguraGeometrica e diventa simile a tutte le altre classi che erediteranno questa classe.
class Cerchio: public FiguraGeometrica {
private:
double raggio;
public:
double getRaggio(){
return raggio;
}
void setRaggio(double raggio){
this->raggio=raggio;
}
// Sovrascrittura del metodo perimetro richiamato dal metodo getInformazioni ereditato dalla classe FiguraGeometrica per ottenere il preimetro del Cerchio
double perimetro(){
return raggio*M_PI*2;} // M_PI = PI GRECO
// Sovrascrittura del metodo area richiamato dal metodo getInformazioni ereditato dalla classe FiguraGeometrica per ottenere l'area del Cerchio
double area(){
return pow(raggio,2)*M_PI; // M_PI = PI GRECO, pow = potenza(base,esponete)
}
Cerchio(double raggio,Point *posizione,string colore):FiguraGeometrica("Cerchio", posizione, colore){
this->raggio=raggio;
}
};
int main() {
// Posizione Quadrato
Point *pointQuadrato=new Point(10,20);
// Quadrato(lato, posizione, colore)
Quadrato *quadrato=new Quadrato(25,pointQuadrato,"verde");
// Posizione Rettangolo
Point *pointRettangolo=new Point(60,80);
// Rettangolo(latoMinore, latoMaggiore, posizione, colore)
Rettangolo *rettangolo=new Rettangolo(25,40,pointRettangolo,"Blu");
// Posizione Trianangolo
Point *pointTriangolo=new Point(100,150);
// Triangolo(latoPrimo, latoSecondo, latoTerzo, posizione, colore)
Triangolo *triangolo=new Triangolo(40,30,20,pointTriangolo,"Rosso");
// Posizione Cerchio
Point *pointCerchio=new Point(100,150);
// Cerchio(lraggio, posizione, colore)
Cerchio *cerchio=new Cerchio(40,pointCerchio,"Grigio");
cout << quadrato->getInformazioni() << endl;
cout << rettangolo->getInformazioni() << endl;
cout << triangolo->getInformazioni() << endl;
cout << cerchio->getInformazioni() << endl;
}
Nella prossima lezione parleremo di Collection.
<< Lezione precedente Lezione successiva >>
Clicca qui per scaricare i laboratori di questa lezione (Per eseguire i laboratori installate Code Block sul vostro computer)
Renato Elia - Scuola e Tecnologia per formare gli studenti e favorire lo sviluppo del Territorio
Gino Visciano |
Skill Factory - 20/11/2018 00:00:01 | in Orientamento scolastico
La ricetta dell'ITI Renato Elia di Castellammare di Stabia, per favorire lo sviluppo del Territorio, è quella di formare gli studenti attraverso l'Alternanza Scuola Lavoro e l'utilizzo pratico delle Nuove Tecnologie.
A dirlo la professoressa Giovanna Giordano, Dirigente dell'Istituto, durante l'evento "Verso il futuro per il successo formativo degli studenti".
All'evento è intervenuto anche il Sindaco di Castellammare di Stabia, Dott. Gaetano Cimmino, che dopo un breve salutato, ha assistito alla presentazione dei progetti realizzati dagli studenti durante le ore di Alternanza Scuola Lavoro.
Musica, Domotica, Videogames, Robotica, Industria 4.0, ed Artigianato 4.0, sono gli ingredienti che hanno reso la manifestazione veramente molto interessante, in particolare abbiamo apprezzato gli interventi musicali del gruppo di studenti "Unity", diretti dal professor Mario Blasio che, con il suo entusiasmo, ha dimostrato con quanto impegno gli insegnati dell'Elia seguono i propri studenti.
All'evento eravamo presenti anche noi, per raccontare la nostra esperienza di Alternanza presso la scuola, è stata l'occasione per rivedere nuovamente i progetti che hanno vinto la prima edizione dell'evento Python Ideas e salutare gli studenti dell'Elia che hanno reso possibile questa fantastica esperienza.
(clicca qui per vedere le foto dell'evento Python Ideas)
T U T O R I A L S S U G G E R I T I
- Laboratori di Logica di Programmazione in C
- Introduzione alla logica degli oggetti
- Impariamo a programmare con JavaScript
- APP Mania
- Excel delle Meraviglie
- Ricominciamo ... dal Linguaggio SQL
- Come sviluppare un Sito con Wordpress
La Skill Factory, anche nel 2018, si conferma tra le scuole di "Specializzazione Digitale ed Orientamento al lavoro" di maggiore successo
Gino Visciano |
Skill Factory - 01/11/2018 16:18:48 | in Formazione e lavoro
Dopo un anno di duro lavoro, nonostante la concorrenza di competitor, sponsorizzati da grandi brand stranieri, i risultati ci danno ragione, anche nel 2018 la Skill Factory si conferma tra la scuole di "Specializzazione Digitale ed Orientamento al lavoro" di maggiore successo.
Questo traguardo ci incoraggia a fare ancora meglio l'anno prossimo, arricchendo la nostra offerta formativa con i nuovi profili professionali più richiesti dalle aziende, lo scopo è quello di dare maggiori opportunità di trovare un lavoro ai giovani che decidono di partecipare alle nostre Skill Factory.
Il nostro successo è confermato dai numeri che abbiamo raggiunto nel 2018:
1) in collaborazione con le scuole superiori, abbiamo formato ed orientato al lavoro oltre 500 studenti;
2) alle nostre Skill Factory hanno partecipato oltre 400 giovani laureati e diplomati disoccupati, il 30%, circa 120 ragazzi, hanno trovato lavoro presso un nostro Job Partner;
3) complessivamente abbiamo erogato circa 8000 ore di formazione, di cui il 25% online, attraverso la piattaforma Skillbook;
4) attraverso Skillbook abbiamo gestito oltre 80 aule virtuali con almeno 15 allievi;
5) i nostri tutorials, pubblicati su Skillbook, hanno ricevuto oltre 100.000 visualizazioni;
6) le nostre offerte di lavoro, pubblicate su Skillbook, hanno ricevuto oltre 25.000 visualizazioni.
Seguiteci su Skillbook per conoscere quali saranno le Skill Factory in partenza nel primo trimestre del 2019, per socprire in anteprima quali saranno i nuovi Profili Professionli disponibili.
Introduzione alla logica degli oggetti - Lezione 4
Gino Visciano |
Skill Factory - 05/10/2018 22:44:13 | in Tutorials
In questa lezione parliamo di Ereditarietà, che insieme all'incapsulamento ed il polimorfismo, è uno dei più importanti paradigmi dell'Object Oriented.
CHE COS'E' L'EREDITARIETA'
L'ereditarietà è una tecnica di riuso del codice che permette di specializzare una classe già esistente, per crearne una nuova.
La nuova classe si chiama classe derivata, mentre la classe ereditata si chiama classe superiore, come mostra il diagramma UML seguente:
L'ereditarietà si dice singola se la classe derivata può ereditare una sola classe, mentre si dice multipla se la classe derivata può ereditare più classi contemporaneamente. Ad esempio il linguaggio C++ permette anche l'ereditarietà è multipla, mentre Java e C# permettono solo l'ereditarietà singola, il diagramma UML seguente mostra un esempio di ereditarietà è multipla:
Un classe Persona che contiene gli attributi seguenti: id, nome, cognome, dataDiNascita, luogoDiNascita e sesso, può essere specializzata in una classe Dipendente che, oltre agli altributi della classe Persona contiene anche gli attributi seguenti: stipendio e ruolo, come mostra il diagramma UML seguente:
Con la classe Dipendete adesso si possono istanziare oggetti che oltre a contenere il ruolo e lo stipendio, contengono anche id, nome, cognome, dataDiNascita, luogoDiNascita e sesso, come mostra il diagramma UML seguente:
Di seguito implementiamo l'esempio appena visto con il linguaggio c++.
Prima di tutto creiamo una classe Data per gestire oggetti di tipo data, servirà in seguito per assegnare la data di nascita alla persona:
Adesso creiamo la classe Persona, che specializzaremo successivamente in Dipendente:
Infine creaiamo la classe Dipendente, che eredita la classe superiore Persona:
GESTIONE DEI COSTRUTTORI PARAMETRIZZATI
Se la classe superiore ha un costruttore parametrizzato, usato per inizializzare gli attributi, la classe derivata lo deve eseguire altrimenti non può funzionare correttamente.
Il diagramma UML seguente, mostra in che modo il costruttore della classe derivata esegue il costruttore parametrizzato della classe superiore:
Vediamo lo stesso esempio scritto in linguaggio C++:
class Persona {
private:
string sesso;
public:
int id;
string nome;
string cognome;
Data *dataDiNascita;
string luogoDiNascita;
void setMaschio(){
this->sesso="maschio";
}
void setFemmina(){
this->sesso="femmina";
}
string getSesso(){
if(sesso=="") sesso="maschio";
return this->sesso;
}
Persona(){
this->dataDiNascita=new Data();
}
Persona(int id,string nome,string cognome, Data *dataDiNascita,string luogoDiNascita, string sesso){
if(sesso=="maschio")setMaschio();
else setFemmina();
this->dataDiNascita=new Data();
this->id=id;
this->nome=nome;
this->cognome=cognome;
this->dataDiNascita=dataDiNascita;
this->luogoDiNascita=luogoDiNascita;
}
};
class Dipendente : public Persona {
public:
double stipendio;
string ruolo;
Dipendente(){}
Dipendente(int id, string nome,string cognome, Data *dataDiNascita,string luogoDiNascita, string sesso, double stipendio, string ruolo):Persona(nome, cognome, dataDiNascita, luogoDiNascita, sesso){
this->stipendio=stipendio;
this->ruolo=ruolo;}
}
};
OVERRIDE (SOVRASCRITTURA) DI METODI EREDITATI DALLA CLASSE SUPERIORE
L'override è la tecnica che permette di sovrascrivere un metodo ereditato da una classe superiore per modificarne il comportamento all'interno della classe derivata. L'override, insieme all'overload può essere definito plimorfismo dei metodi.
Immaginiate di avere nella classe Persona il metodo getInformazioni() che restituisce i valori di tutti gli attributi della classe separti da una virgola. Se la classe Persona viene ereditata dalla classe Dipendente, questo metodo dovrà essere necessariamete sovrascritto altrimenti nell'elenco di attributi restituito mancherà lo stipendio ed il ruolo del Dipendente.
In C++ un metodo della della classe superiore per essere sovrascritto nella classe derivata, deve essere virtuale, come mostra l'esempio seguente:
class Persona {
private:
string sesso;
public:
int id;
string nome;
string cognome;
Data dataDiNascita;
string luogoDiNascita;
void setMaschio(){
this->sesso="maschio";
}
void setFemmina(){
this->sesso="femmina";
}
string getSesso(){
if(sesso=="") sesso="maschio";
return this->sesso;
}
// Metodo virtuale che verrà sovrascritto nella classe Dipendente
virtual string getInformazioni(){
return nome + ", "+cognome+", "+dataDiNascita.getData()+", "+luogoDiNascita+", "+sesso;
}
Persona(){
this->dataDiNascita=new Data();
}
Persona(int id,string nome,string cognome, Data *dataDiNascita,string luogoDiNascita, string sesso){
if(sesso=="maschio")setMaschio();
else setFemmina();
this->dataDiNascita=new Data();
this->id=id;
this->nome=nome;
this->cognome=cognome;
this->dataDiNascita=dataDiNascita;
this->luogoDiNascita=luogoDiNascita;
}
};
class Dipendente : public Persona {
public:
double stipendio;
string ruolo;
// Sovrascrittura del Metodo getInformazioni ereditato dalla classe Persona
string getInformazioni(){
// Conversione double in stringa
stringstream strStipendio;
strStipendio << this->stipendio;
return nome + ", "+cognome+", "+dataDiNascita.getData()+", "+luogoDiNascita+", "+getSesso()+", "+strStipendio.str()+", "+ruolo;
}
Dipendente(){}
Dipendente(int id,string nome,string cognome, Data *dataDiNascita,string luogoDiNascita, string sesso, double stipendio, string ruolo):
Persona(id, nome, cognome, dataDiNascita, luogoDiNascita, sesso){
this->stipendio=stipendio;
this->ruolo=ruolo;}
};
INCAPSULAMENTO DEGLI ATTRIBUTI E DEI METODI DI UNA CLASSE IN CASO DI EREDITARIETA'
Nell'esempio precedente, quando viene sovrascritto il metodo getInformazioni() della classe Dipendente, l'attributo sesso è stato sostituito dal metodo getSesso().
Questa operazione è necessaria perché l'attributo sesso della classe Persona è privato. Gli elementi privati di una classe sono visibili solo ai metodi della stessa classe, mentre non sono visibili in alcun caso ai metodi di altre classi.
In questo caso, sovrascrivendo il metodo getInformazioni() nella classe Dipendente, diventa un metodo esterno alla classe superiore e non può più vedere l'attributo sesso.
Il metodo getInformazioni() della classe Dipendente, per leggere il valore dell'attributo sesso, lo può fare solo attraverso il metodo getSesso() della classe Persona perchè è pubblico, come mostra l'immagine seguente:
Per poter usare direttamente l'attributo sesso nel metodo getInformazioni() della classe Dipendente, bisogna impostarlo protected, come mostra l'immagine seguente:
Per chiarire meglio il ruolo dei modificatori di accesso approfondiamo insieme il diagramma UML seguente:
Osservando il diagramma si capisce che una classe derivata che eredita una classe superiore, può usare attraverso un metodo, senza istanziare, tutti i suoi elementi pubblici e protetti.
Infatti il metodo metodotSeconda() della classe Seconda vede:
attributoPublic;
attributoProtected;
metodoPrimoA();
metodoPrimoC().
Mentre non vede l'attributoPrivate perché è privato. Se fosse necessario accedere a questo attributo lo potrebbe fare solo attraverso l'uso dei metodi:
metodoPrimoA();
metodoPrimoC().
Invece una classe utilizzatrice, per usare attraverso un suo metodo, gli elementi di un'altra classe, le deve prima istanziare e attraverso l'oggetto creato può vedere solo gli elementi pubblici della classe istanziata.
Infatti il metodo metodotTerza() della classe Terza, attraverso l'oggetto s vede:
s->attributoPublic;
s->metodoPrimoA();
s->metodoSeconda().
Mentre non vede:
attributoPrivate
attributoProtected;
metodoPrimoC().
Se fosse necessario accedere agli attributi oppure ai metodi non visibili lo potrebbe fare solo attraverso l'uso dei metodi:
s->metodoPrimoA();
s->metodoSeconda().
Per rendere efficace questo argomento, vi suggerisco di implementare con il linguaggio C++ le classi Prima, Seconda e Terza ed analizzarne attentamente il comportamento.
EREDITARIETA' MULTIPLA
Il linguaggio C++ permette di ereditare più classi contemporaneamente in questo caso si parla di ereditarietà multipla, vediamo un esempio:
Immaginate di avere una classe Persona a cui volete aggiungere le informazioni dell'indirizzo ed i riferimenti principali. In questo caso la classe Persona potrebbe ereditare una classe Indirizzo ed una classe Riferimenti, come mostra il diagramma UML seguente:
class Indirizzo{
public:
string via;
string cap;
string citta;
string provincia;
Indirizzo(){}
};
class Riferimenti{
public:
string telefonoCasa;
string telefonoUfficio;
string cellulare;
string email;
string social_1;
string social_2;
string social_3;
Riferimenti(){}
};
class Persona : public Indirizzo, public Riferimenti{
private:
string sesso;
public:
int id;
string nome;
string cognome;
Data *dataDiNascita;
string luogoDiNascita;
void setMaschio(){
this->sesso="maschio";
}
void setFemmina(){
this->sesso="femmina";
}
string getSesso(){
if(sesso=="") sesso="maschio";
return this->sesso;
}
Persona(){
this->dataDiNascita=new Data();
}
Persona(int id,string nome,string cognome, Data *dataDiNascita,string luogoDiNascita, string sesso,
string via, string cap, string citta, string provincia, string telefonoCasa, string telefonoUfficio,
string email,string facebook, string linkedin, string skillbook){
if(sesso=="maschio")setMaschio();
else setFemmina();
this->dataDiNascita=new Data();
this->id=id;
this->nome=nome;
this->cognome=cognome;
this->dataDiNascita=dataDiNascita;
this->luogoDiNascita=luogoDiNascita;
this->via=via;
this->cap=cap;
this->citta=citta;
this->provincia=provincia;
this->telefonoCasa=telefonoCasa;
this->telefonoUfficio=telefonoUfficio;
this->email=email;
this->social_1=facebook;
this->social_2=linkedin;
this->social_3=skillbook;
}
};
Nella prossima lezione parleremo di Polimorfismo degli oggetti.
<< Lezione precedente Lezione successiva >>
Clicca qui per scaricare i laboratori di questa lezione (Per eseguire i laboratori installate Code Block sul vostro computer)
Laboratori di Logica di Programmazione in C
Parte ad ottobre il corso di "Office Specialist", organizzato dalla Skill Factory nell'ambito del programma di alfabetizzazione digitale per diplomati e laureati in cerca di lavoro.
Gino Visciano |
Skill Factory - 30/09/2018 10:07:19 | in Formazione e lavoro
Per favorire l'inserimento aziendale di giovani diplomati o laureati che hanno completato gli studi e sono in cerca di lavoro, ad ottobre, presso la Skill Factory di Napoli, partirà il corso di "Office Specialist".
Il corso sarà il primo di diversi corsi che verranno organizzati tra il 2018 e 2019, nell'ambito del programma di alfabetizzazione digitale promosso dalla Skill Factory, rivolto ai giovani diplomati e laureati disoccupati che sono alla ricerca di una prima occupazione.
Il corso sarà gratuito, perché verrà finanziato dal Forma.Temp, il fondo per la formazione ed il sostegno al reddito dei lavoratori in somministrazione finanziato dal contributo versato dalle Agenzie per il lavoro.
I partecipanti non acquisiranno solo le conoscenze e le abilità che servono per utilizzare i principali prodotti usati per l'automazione dell'ufficio, come Word, Excel, Power Point, Publisher, Outlook, etc., ma apprenderanno anche le seguenti competenze trasversali indispensabili per entrare nel mondo del lavoro, :
- Informatica Generale
- Gestione ed organizzazione Aziendale;
- Project Management;
- Comunicazione Efficace;
- Team Working;
- Marketing Tradizionale;
- Marketing Digitale;
- Sicurezza e Privacy;
- Diritti dei lavoratori.
Il corso avrà una durata di 240 ore e verrà erogato da docenti esperti sia di formazione, sia di gestione ed organizzazione aziendale, l'obiettivo sarà quello di far vivere ai discenti un' esperienza di scuola/azienda simulata, indispensabile per la loro crescita professionale.
Il mio ruolo in questa esperienza sarà duplice, perché oltre ad avere la responsabilità progettuale e didattica del corso, parteciperò anche come docente per contribuire anche con la mia esperienza alla crescità professionale dei giovani coinvolti.
A fine corso tutti i partecipanti che avranno completato il percorso di formazione riceveranno un Attestato di partecipazione rilasciato dal Forma.Temp.
Inoltre, attraverso la piattaforma Skillbook, in qualunque momento i partecipanti potranno visualizzare le competenze acquisite durante il corso ed il livello di apprendimento raggiunto.
Di seguito alcune informazioni utili per partecipare al corso di "Office Specialist":
1) Se già siete registrati alla piattaforma ww.skillbook.it, cliccate sul link seguente per prenotare il corso di "Office Specialist": clicca qui per prenotare
2) Per registrarsi sulla piattaforma ww.skillbook.it, cliccate sul link seguente: clicca qui per registrarti su skillbook
3) Per inviare la propria candidatura senza essere registrati a inviate il vostro curriculum vitae a selezione@skillfactory.it