Tra le varie tappe internazionali, il “RAD Studio XE2 World Tour” ha toccato anche l'Italia, precisamente Milano il 21 settembre e Roma il giorno successivo.
Le novità introdotte in questa versione del tool di sviluppo sono davvero tante, motivo per cui ho pensato di redigere questo reportage per
elencare quelle che – a livello personale e soggettivo – ritengo le innovazioni più interessanti e degne di nota, e magari sciogliere qualche dubbio a coloro che non hanno potuto partecipare, raccontando gli avvenimenti della giornata di presentazione.
Android App Development, Creare la nostra prima appNicola Corti
Intervento al Linux Day 2014@Pisa, organizzato da parte del GULP. L'intervento introduce allo sviluppo su piattaforma Android, mostrando i vari strumenti e gli accorgimenti da seguire per programmare sulla nota piattaforma del robottino verde.
Tra le varie tappe internazionali, il “RAD Studio XE2 World Tour” ha toccato anche l'Italia, precisamente Milano il 21 settembre e Roma il giorno successivo.
Le novità introdotte in questa versione del tool di sviluppo sono davvero tante, motivo per cui ho pensato di redigere questo reportage per
elencare quelle che – a livello personale e soggettivo – ritengo le innovazioni più interessanti e degne di nota, e magari sciogliere qualche dubbio a coloro che non hanno potuto partecipare, raccontando gli avvenimenti della giornata di presentazione.
Android App Development, Creare la nostra prima appNicola Corti
Intervento al Linux Day 2014@Pisa, organizzato da parte del GULP. L'intervento introduce allo sviluppo su piattaforma Android, mostrando i vari strumenti e gli accorgimenti da seguire per programmare sulla nota piattaforma del robottino verde.
ProjectLibre - Manuale in Italiano dell'alternativa OpenSource a Microsoft Pr...ROSARIO RIZZO, 2000+
ProjectLibre è un software OpenSource per la pianificazione e gestione dei progetti di qualsiasi tipo.
Può essere usato da chiunque perché facile da imparare e questo manuale ne accelera l’apprendimento.
ProjectLibre mette a disposizione un numero notevole di funzionalità che si trovano tipicamente in software più complessi e costosi (centinaia o migliaia di euro per computer).
Il manuale contiene 145 immagini e 110 pagine con un linguaggio discorsivo e comprensibile per i neofiti della schedulazione e per i più esperti.
Vengono descritte tutte le funzionalità utili alla stesura di un piano di progetto:
Inizializzazione
Pianificazione
Risorse
Calendari
Budget Risorse e Costi
Baseline,….
Tracking di progetto
Analisi Varianze
Reports
Un approccio Frameworkless per sviluppare la tua Single Page Applicationextrategy
Il talk racconta l'esperienza del Frameworkless Movement dal punto di vista dello sviluppatore UI. Partendo dalle basi 'cosa sono i framework e perché li utilizziamo? quali insidie nascondono?' saranno illustrati gli strumenti utili a scegliere consapevolmente il miglior framework per il nostro contesto, come ad esempio i Design System, valutando anche l'opzione "no-framework".
una scuola moderna non può appoggiare la didattica sul software proprietario, quando col software libero si può avere disponibile una mole enorme di programmi per tutte le discipline. E cun vantaggio enorme è fdato che questi programmi possono funzionare anche su computer un po' datati.
ProjectLibre - Manuale in Italiano dell'alternativa OpenSource a Microsoft Pr...ROSARIO RIZZO, 2000+
ProjectLibre è un software OpenSource per la pianificazione e gestione dei progetti di qualsiasi tipo.
Può essere usato da chiunque perché facile da imparare e questo manuale ne accelera l’apprendimento.
ProjectLibre mette a disposizione un numero notevole di funzionalità che si trovano tipicamente in software più complessi e costosi (centinaia o migliaia di euro per computer).
Il manuale contiene 145 immagini e 110 pagine con un linguaggio discorsivo e comprensibile per i neofiti della schedulazione e per i più esperti.
Vengono descritte tutte le funzionalità utili alla stesura di un piano di progetto:
Inizializzazione
Pianificazione
Risorse
Calendari
Budget Risorse e Costi
Baseline,….
Tracking di progetto
Analisi Varianze
Reports
Un approccio Frameworkless per sviluppare la tua Single Page Applicationextrategy
Il talk racconta l'esperienza del Frameworkless Movement dal punto di vista dello sviluppatore UI. Partendo dalle basi 'cosa sono i framework e perché li utilizziamo? quali insidie nascondono?' saranno illustrati gli strumenti utili a scegliere consapevolmente il miglior framework per il nostro contesto, come ad esempio i Design System, valutando anche l'opzione "no-framework".
una scuola moderna non può appoggiare la didattica sul software proprietario, quando col software libero si può avere disponibile una mole enorme di programmi per tutte le discipline. E cun vantaggio enorme è fdato che questi programmi possono funzionare anche su computer un po' datati.
2. Introduzione alla programmazione
orientata agli oggetti
Di Massimiliano Brolli
Premessa...................................................................................................3
Prerequisiti ................................................................................................3
La Storia....................................................................................................5
Grandi vantaggi..........................................................................................8
I concetti base ...........................................................................................9
Le Classi ............................................................................................... 10
Gli attributi o variabili di classe ............................................................. 12
I metodi.............................................................................................13
Il concetto di Oggetto............................................................................. 14
Incapsulamento ..................................................................................... 16
L’Ereditarietà......................................................................................... 18
Il Polimorfismo ......................................................................................20
Le interfacce.......................................................................................20
Le classi astratte................................................................................. 24
L’overriding ........................................................................................26
L’overloads.........................................................................................28
3. Premessa
La programmazione orientata agli oggetti (OOP, Object Oriented Programming) è
un paradigma di programmazione, che prevede la definizione di oggetti software
che interagiscono gli uni con gli altri attraverso lo scambio di messaggi.
Un linguaggio di programmazione è definito ad oggetti quando permette di
implementare i seguenti tre meccanismi:
1. Incapsulamento : prevede di raggruppare in un'unica entità (la classe)
la definizione delle strutture dati e delle procedure che operano su di
esse.
Le classi definiscono per l'appunto degli "oggetti" software dotati di
attributi (variabili di classe, proprietà e strutture) e metodi (procedure)
che operano sui dati dell'oggetto stesso.
2. Ereditarietà : permette essenzialmente di definire delle classi a partire
da altre già definite.
3. Polimorfismo : Il Polimorfismo permette al programmatore di creare
operazioni diverse con lo stesso nome che semplifica complessi modelli
di classe, e lo rende più comprensibile e gestibile.
La programmazione orientata agli oggetti può essere anche vista come un
supporto alla modellazione software degli oggetti del mondo reale o del modello
astratto. Inoltre, l'organizzazione del codice sotto forma di classi fornisce un
supporto più naturale al riuso del codice.
Prerequisiti
Per procedere alla lettura di questo documento occorre aver letto le seguenti
dispense :
• Introduzione agli algoritmi.
• La scelta tra Microsoft.NET & Java
• Predisposizione Virtual Machine di base
• Predisposizione Virtual Machine per l'ambiente di sviluppo Java
• Introduzione alla scrittura del codice JAVA
• Scrivere applicazioni JAVA con Eclipse
Oppure
• Introduzione agli algoritmi.
• La scelta tra Microsoft.NET & Java
• Predisposizione Virtual Machine di base
• Predisposizione Virtual Machine per l'ambiente di sviluppo Microsoft .NET
• Introduzione alla scrittura del codice .NET
• Scrivere applicazioni .NET con Visual Studio
4. Nota Bene : Tale dispensa non si lega ad un determinato linguaggio di
programmazione, gli esempi riportati sono scritti in diversi linguaggio proprio per
dimostrare che il concetto di Object Oriented non è legato ad una sola
implementazione.
5. La Storia
Il termine Object (Oggetto) e il termine Oriented (Orientato verso qualcosa) nel
senso moderno della programmazione vede la luce al MIT (Massachusetts
Institute of Technology) tra il 1950 e il 1960.
Il primo linguaggio di programmazione orientato agli oggetti fu il Simula 67
sviluppato nel 1967 in seguito ad una profonda rivisitazione del linguaggio
Simula I.
Simula introduce il concetto di classi e di istanza di oggetto così come le
sottoclassi, i metodi così come oggi le conosciamo e influenzò molto i successivi
linguaggi di programmazione orientati agli oggetti tra i quali Smalltalk e C++.
Dopo Simula 67 venne sviluppato negli anni settanta Smalltalk (dalla Xerox)
inizialmente in sordina vide il suo successo dopo la pubblicazione nell’agosto del
1981 di un lungo articolo sulla rivista Byte Magazine.
Di seguito una schermata di Smalltalk.
Proprio in quel periodo i Mainframe dominavano il mondo e si cominciava a
passare dalle schede perforate ai linguaggi di programmazione strutturati come
ad esempio il Cobol in maniera lenta e graduale.
Di seguito una immagine di un Datacenter con supporti a nastro e una schermata
6. del TSO, ambiente di sviluppo per Cobol/Cobol2.
Verso la fine degli anni 70 Lisp comincia a farsi notare, linguaggio che prende a
vantaggio quanto di buono fatto su Smalltalk e ne estende le funzionalità come
ad esempio l’introduzione dell’ereditarietà multipla tanto da arrivare al Common
Lisp Object System e allo standard ANSI Common Lisp.
Ci furono anche dei tentativi di produrre Hardware con capacità orientate alla
compilazione di programmi OO quali APX Intel 432 e la Linn intelligente Rekursiv
che però fallirono miseramente.
Molti anni dovranno passare prima di utilizzare in maniera industriale un
linguaggio orientato agli oggetti anche tenendo in considerazione le alte capacità
computazionali richieste alle CPU dell’epoca per applicare le rigide regole OO.
Negli anni ottanta sono state create estensioni orientate ad oggetti del linguaggio
C (C++, Objective C, e altri), e di altri linguaggi (Object Pascal) fino ad arrivare
agli anni 90 dove divenne il paradigma dominante di tutti i linguaggi di
programmazione come C++, Java, Delphi, Python, C#, Microsoft .NET, Perl, PHP
(a partire dalla versione 5).
Essa rappresenta una delle idee più interessanti introdotte ultimamente nel
campo della programmazione, in grado di risolvere i problemi di complessità e
ingovernabilità che si presentavano nei progetti di grandi dimensioni.
A differenza della programmazione “control-flow” o programmazione strutturata,
(per intenderci, quella classica di C, Pascal, Cobol), in cui un programma viene
inteso come una sequenza di azioni, nell’OOP un programma è considerato come
un insieme di oggetti o di programmi che lavorano assieme in un modo
prestabilito allo scopo di perseguire un determinato obiettivo.
Un esempio molto bello sono i mattoncini della Lego.
7. In effetti per costruire un castello ne occorrono moltissimi, di tanti colori e di
diversa forma e tutti quanti saranno importanti in egual modo e avranno un
compito prestabilito.
Un programma di grandi dimensione è come un castello Lego, composto da una
moltitudine di classi le quali collaborano tra di loro scambiandosi messaggi e
risolvendo i nostri algoritmi.
Quindi una classe possiamo definirla come un piccolo programma.
E’ un elemento autonomo, dotato di proprie qualità e di un proprio
comportamento preciso che può essere richiamato da una qualsiasi altra classe.
Ovviamente tutte queste classi per interfacciarsi dovranno per forza di cose
sapere in che maniera dialogare tra loro per raggiungere tutti insieme un
determinato obbiettivo.
8. Grandi vantaggi
Molti sono i vantaggi che si possono avere passando dalla programmazione
strutturata ad una programmazione Object oriented.
Però per ottenere il massimo dall’OOP occorre progettare in maniera adeguata gli
oggetti che si vogliono utilizzare, avendo molta cura nel rispettare le poche ma
importanti regole che vedremo nel dettaglio più in avanti.
Di fatto i vantaggi sono :
• Forte manutenibilità : Le modifiche sui dati sono normalmente limitate
all'ambito omogeneo della classe, poiché i dati sono accessibili solo alle
operazioni interne alle classi
• Riusabile : visto che la modularità è elevata, grazie all’ereditarietà e al
polimorfismo (che vedremo più avanti) è possibile riutilizzare parti di codice
precedentemente scritte o intere classi in altri contesti.
In effetti esistono anche degli svantaggi i quali se non conosciuti portano a
vanificare completamente i vantaggi che abbiamo appreso sopra e sono :
• Progettazione accurata : Un progetto OOP richiede maggiore attenzione
nella progettazione. Strutturare le classi in modo fortemente manutenibile
è un lavoro di analisi molto complesso che però è compito di chi progetta il
software e non di chi lo sviluppa.
Inoltre spesso si incontrano programmatori che si complicano la vita perché non
sono a conoscenza delle basi della programmazione orientata agli oggetti.
Chi di voi suona sa che il solfeggio, l’armonia, il contrappunto sono la base della
musica. Queste regole sono valide sia se si suona il pianoforte e sia se si suona
uno strumento a fiato.
Tutto questo per dirvi che l’OOP è la base unica di tutti i linguaggi di
programmazione. Conoscendo approfonditamente l’OOP si può passare da Java a
.NET o da .NET a C++ in maniera molto indolore in quanto tutti questi ambienti
si basano sulla stessa metodologia.
Conoscere l’Object Oriented è la base per divenire buoni programmatori Java o
.NET.
9. I concetti base
Di seguito andremo a dettagliare i concetti base della programmazione Object
Oriented.
Questo documento non mostrerà come l’OOP viene implementato su un dato
linguaggio di programmazione ma si limiterà a descrivere il funzionamento in
maniera astratta dalla sua reale implementazione.
Infatti tali concetti esulano completamente dalla tecnologia adoperata, mentre è
la tecnologia stessa che deve essere conforme alla programmazione ad oggetti.
10. Le Classi
Iniziamo questo paragrafo definendo che una classe è un piccolo programma.
Di fatto l’insieme di più classi costituiscono l’insieme elaborativo del nostro
programma come precedentemente abbiamo visto per i mattoncini Lego.
La classe è composta da Strutture dati e codice che le gestisce.
Un esempio di una classe Java
public class Impiegato {
private String nome;
private String cognome;
private int annoNascita;
private int stipendio;
private String posizione;
final int stipendioMax;
final int stipendioMin;
public Impiegato (String nome, String cognome,
int annoNascita, String posizione)
{
stipendioMin = 750;
stipendioMax = 2000;
this.nome = nome;
this.cognome = cognome;
this.annoNascita = annoNascita;
stipendio = stipendioMin;
this.posizione = posizione;
}
public void mostraNome(){
System.out.println(nome + " " + cognome);
}
public int calcolaStipendio (){
return stipendio;
}
public void aumentaStipendio (int incremento){
variaStipendio (incremento);
}
public void riduciStipendio (int riduzione){
variaStipendio (riduzione*(-1));
}
private void variaStipendio (int variazione){
if (stipendio + variazione > stipendioMin)
stipendio = stipendio + variazione;
else
stipendio = stipendioMin;
if (stipendio > stipendioMax)
stipendio = stipendioMax;
}
}
Un esempio di una classe VB.NET.
Per farlo funzionare è possibile creare una Console Application nella quale
incollare il Module1 e la classe Impiegato.
'Modulo della console application che lancierà la classe Impiegato
Module Module1
Sub Main()
Dim impiegato As New Impiegato("Massimiliano", "Brolli", "1973", "Quadro")
impiegato.StampaValori()
11. System.Console.WriteLine("Età : " & impiegato.CalcolaEta(2011))
Threading.Thread.Sleep(10000)
End Sub
End Module
'Classe impiegato da creare tramite Add->New Item->Class
Public Class Impiegato
Private nome As String
Private cognome As String
Private annoNascita As Integer
Private stipendio As Integer
Private posizione As String
Private stipendioMax As Integer = 2000
Private stipendioMin As Integer = 1000
Public Sub New(ByVal nome As String,
ByVal cognome As String,
ByVal annoNascita As Integer,
ByVal posizione As String)
stipendioMin = 750
stipendioMax = 2000
Me.nome = nome
Me.cognome = cognome
Me.annoNascita = annoNascita
stipendio = stipendioMin
Me.posizione = posizione
End Sub
Private Sub VariaStipendio(ByVal Variazione As Integer)
If (stipendio + Variazione > stipendioMin) Then
stipendio = stipendio + Variazione
Else
stipendio = stipendioMin
End If
If (stipendio > stipendioMax) Then
stipendio = stipendioMax
End If
End Sub
Public Sub StampaValori()
System.Console.WriteLine("Nome inserito : " & nome)
System.Console.WriteLine("Cognome inserito : " & cognome)
System.Console.WriteLine("Anno di nascita : " & annoNascita)
System.Console.WriteLine("Stipendio : " & stipendio)
System.Console.WriteLine("Posizione : " & posizione)
System.Console.WriteLine("Stipendio Massimo : " & stipendioMax)
System.Console.WriteLine("Stipendio Minimo : " & stipendioMin)
End Sub
Public Sub MostraNome()
System.Console.Write(nome + " " + cognome)
End Sub
Public Function CalcolaStipendio() As Integer
Return stipendio
End Function
Public Function CalcolaEta(ByVal annoCorrente As Integer) As Integer
Dim eta As Integer = annoCorrente - annoNascita
If ((eta >= 16) And (eta <= 90)) Then
Return eta
Else
Return 0
End If
End Function
Public Sub AumentaStipendio(ByVal incremento As Integer)
VariaStipendio(incremento)
End Sub
Public Sub RiduciStipendio(ByVal riduzione As Integer)
VariaStipendio(riduzione * (-1))
End Sub
End Class
12. I membri di una classe infatti sono:
• Gli attributi : le strutture dati che la costituiscono come variabili di classi,
proprietà, strutture.
• I Metodi : procedure o codice che ne descrive il comportamento.
Gli attributi o variabili di classe
Gli attributi (o variabili di classe) descrivono le strutture dei dati di cui una classe
è composta. Di fatto sono delle variabili visibili da tutti i metodi e proprietà della
classe stessa nelle quali verranno memorizzate informazioni utili al suo ciclo di
vita.
In C#
public class Famiglia {
public String nome;
static String cognome;
public int annoNascita;
}
In VB.NET
Public Class Employee
Private _name As String
Protected _surname As String
Shared _group As String
End Class
In Java
package utilityClass;
public class Employee{
private String name;
private String surname;
static String group;
}
Ogni linguaggio di programmazione implementa delle direttive di inizializzazione
dello scope delle variabili. Per scope si intende la visibilità delle variabili o meglio
dire come queste saranno visibili dalle loro istanze.
Tralasciando il concetto di private, protected/protect, public che avremo già visto
nelle lezioni specializzate all’apprensione della sintassi dei linguaggi di
programmazione, mi vorrei soffermare sull’uso della direttiva static in Java o
Shared in .NET.
13. La direttiva Shared permette di marchiare una variabile di classe in modo
condiviso.
Ad esempio in una classe Famiglia sarà presente la variabile pubblica nome, la
variabile pubblica annoDiNascita e la variabile static/Shared cognome.
Per static (in Java) o Shared (in VB.NET) si intende che la variabile cognome
verrà allocata una sola volta per tutte le istanze della classe Famiglia e quindi
risulterà condivisa.
Infatti mentre per ogni istanza potremo modificare il valore di nome e
annoDiNascita, modificando la variabile cognome tale modifica sarà vista su
tutte le istanze che ne fanno uso.
I metodi
Come abbiamo detto in precedenza, i metodi racchiudono il funzionamento
specifico di una data classe e al loro interno come visto nell’esempio precedente
è presente il codice applicativo.
La prima riga di un metodo viene definita Firma
public void aumentaStipendio (int incremento){
variaStipendio (incremento);
}
La firma o segnatura (dall'inglese signature) di un metodo è costituita da un
insieme di informazioni che ne identificano univocamente il metodo fra quelli
della sua classe di appartenenza.
Tali informazioni includono generalmente il nome del metodo, il numero e il tipo
dei suoi parametri e il tipo del suo valore restituito, sebbene nella terminologia
tecnica dei diversi linguaggi l'espressione firma assuma talvolta un significato più
specifico, includendo informazioni aggiuntive o non includendo alcune di quelle
citate (per esempio il tipo del valore restituito oppure i parametri di ingresso).
Come per gli attributi, è possibile marchiare con static/Shared i metodi delle
classi. Questo permetterà di utilizzare tali metodi senza andare ad istanziare tale
classe. Ovviamente però se in una data classe è presente un metodo di tipo
static/Shared, tutti gli altri dovranno essere esposti nella stessa maniera.
14. Il concetto di Oggetto
Un oggetto è una istanza di una classe.
Oggetto o istanza in Object Oriented sono sinonimi.
Una istanza è la realizzazione della classe nella memoria dell’elaboratore, daquel
momento dopo che tale classe sia stata istanziata sarà eseguibile.
La definizione di una classe è presente all’interno di un file di testo nel quale
vengono definiti come i dati saranno organizzati in memoria e sono una serie di
istruzioni a noi comprensibili che però non lo sono per un elaboratore che
riconosce ed elabora solo istruzioni in codice macchina.
Per rendere eseguibile una classe occorre creare una istanza che possa essere
eseguita.
Una istanza occupa memoria, la classe no, la occupa solo sul file System.
Per creare una istanza occorre specificare la clausola new.
Dim sw As New StreamWriter("c:test.txt")
Dim sw As StreamWriter
sw = New StreamWriter("c:test.txt")
Nell’esempio precedente in VB.NET viene dichiarata l’istanza sw e tramite la
clausola New viene allocata in memoria.
Eseguita tale istruzione l’istanza sw sarà disponibile, pertanto sarà utilizzabile dal
nostro programma.
Ogni oggetto possiede tutti gli attributi definiti nella classe, ed essi hanno un
valore, che può mutare durante l'esecuzione del programma come quello di
qualsiasi variabile.
Di seguito vengono mostrati gli attributi di una classe, tali attributi hanno una
loro visibilità all’interno e all’esterno della classe e devono essere accessibili solo
attraverso dei metodi.
Una classe in Java
public class Impiegato {
private String nome;
private String cognome;
private int annoNascita;
private int stipendio;
private String posizione;
final int stipendioMax;
final int stipendioMin;
15. }
Molti linguaggi forniscono un supporto per l'inizializzazione automatica di un
oggetto, con uno o più speciali metodi detti costruttori.
Inizialmente si fa fatica a capire queste sottili differenze e spesso si confondono i
termini. Sicuramente il tempo ne faciliterà l’uso oltre allo studio intensivo e la
pratica su questi argomenti.
16. Incapsulamento
L'incapsulamento (o information hiding) permette di limitare l’utilizzo di una
classe solo per quelle parti di codice strettamente necessarie che permetteranno
la risoluzione dell’algoritmo.
Molti metodi e variabili sono d’importanza locale per la classe e non dovranno
essere visibili e modificabili dall’utilizzatore pena il corretto funzionamento di
essa se modificati e pena la corretta comprensione della classe.
Questo meccanismo viene permesso utilizzando la classe attraverso la sua
interfaccia o modificare le variabili locali solo tramite dalle proprietà di classe e
utilizzando in maniera sapiente lo scope delle variabili.
Gestito in maniera intelligente, l'incapsulamento permette di vedere l'oggetto
come una black-box, cioè una scatola nera di cui, attraverso ad esempio una
interfaccia, è noto cosa fa e come interagisce con l'esterno ma non come lo fa.
I vantaggi principali portati dall'incapsulamento sono :
• Robustezza
• Indipendenza
• Riusabilità
• Facilità di utilizzo delle classi
Di seguito un esempio in Java
package useIncapsulation;
public interface Report {
public abstract void Inizialize(String Title, String Text);
public abstract void Generate();
}
package useIncapsulation;
public class ReportVerticalConsole
implements Report{
private String[] Array;
private String Title;
private String Text;
@Override
public void Generate() {
BuildVerticalArray();
for(int i=0; i<Array.length; i++)
System.out.println(Array[i]);
}
@Override
public void Inizialize(String Title, String Text) {
17. this.Title = Title;
this.Text = Text;
}
private void BuildVerticalArray(){
Array = Text.split(",");
}
}
package useIncapsulation;
public class Incapsulation {
public static void main(String[] args) {
Report report = new ReportVerticalConsole();
report.Inizialize("Report numero uno", "12,23,43,23,54,64,44");
report.Generate();
}
}
Da notare che nel metodo Main verrà creato l’ogetto di tipo
ReportVerticalConsole di tipo Report, interfaccia di ReportVerticalConsole
dove in tale interfaccia saranno definiti solo i metodi Inizialize e Generate.
Tutto il resto del funzionamento di ReportVerticalConsole sarà incapsulato al
suo interno e quindi conosciuto (il concetto della black Box) come ad esempio il
funzionamento della Routine BuildVerticalArray().
18. L’Ereditarietà
L'OOP prevede un meccanismo molto importante chiamato l'ereditarietà.
L’ereditarietà permette di estendere nuove classi a partire da classi già definite.
Permette inoltre di aggiungere nuovi membri ad una classe, e di modificare il
comportamento dei metodi, in modo da adattarli alla nuova esigenza senza dover
riscrivere il codice della classe padre.
• Da una stessa classe è possibile costruire diverse classi derivate.
• Da una classe derivata è possibile derivarne una ulteriore con lo stesso
meccanismo.
La classe derivata, o sottoclasse, eredita tutti i metodi e gli attributi della classe
"genitrice", e può aggiungere nuovi membri alla classe, sia attributi che metodi,
e/o ridefinire il codice di alcuni metodi attraverso l’ausilio del Polimorfismo che
vedremo nel capitolo successivo.
Di seguito un semplice esempio scritto in VB.NET
'Modulo Main della Console Application
Module Module1
Sub Main()
Dim annoCorrente As New AnnoCorrente("2011", "10", "11")
annoCorrente.PrintValue()
System.Console.WriteLine("-------------------------------------------------")
Dim annoCorrenteComplesso As New AnnoCorrenteComplesso("2011", "10", "11")
annoCorrenteComplesso.PrintValue()
Threading.Thread.Sleep(10000)
End Sub
End Module
'Classe AnnoCorrente
Public Class AnnoCorrente
Private _anno As String
Private _mese As String
Private _giorno As String
Public ReadOnly Property anno() As String
Get
Return _anno
End Get
End Property
Public ReadOnly Property mese() As String
Get
Return _mese
End Get
End Property
Public ReadOnly Property giorno() As String
Get
Return _giorno
End Get
End Property
Public Sub New(ByVal anno As String, _
ByVal mese As String, _
ByVal giorno As String)
_anno = anno
19. _mese = mese
_giorno = giorno
End Sub
Public Sub PrintValue()
System.Console.WriteLine(_giorno & "/" & _mese & "/" & _anno)
End Sub
End Class
'Classe AnnoCorrenteComplesso che eredita dalla classe AnnoCorrente
Public Class AnnoCorrenteComplesso
Inherits AnnoCorrente
Public Sub New(ByVal anno As String, _
ByVal mese As String, _
ByVal giorno As String)
'sono costretto da invocare il costruttore della classe ereditata
MyBase.new(anno, mese, giorno)
End Sub
Public Function CurrentDate() As String
Return System.DateTime.Now.Date
End Function
Public Sub PrintValue()
System.Console.WriteLine("Giorno : " & MyBase.giorno)
System.Console.WriteLine("Mese : " & MyBase.mese)
System.Console.WriteLine("Anno : " & MyBase.anno)
End Sub
End Class
E un semplice esempio scritto in Java
package example;
public class ExtendsClass {
private int valueA;
private int valueB;
public int getValueA() {
return valueA;
}
public int getValueB() {
return valueB;
}
public ExtendsClass(int valueA, int valueB){
this.valueA = valueA;
this.valueB = valueB;
}
}
package example;
public class UseExtendsClass extends ExtendsClass{
public UseExtendsClass(int valueA, int valueB) {
//sono costretto ad invocare il costruttore della classe ereditata
super(valueA, valueB);
}
}
Noteremo in entrambi gli esempi che se la classe padre ha un costruttore il quale
deve essere eseguito saremo costretti nella classe figlia a dover definire in essa
un costruttore e di conseguenza lanciare il costruttore della classe padre
passandogli gli argomenti necessarie per il suo instanziamento.
20. Il Polimorfismo
Per polimorfismo (capacità di essere diversi) si intende quella possibilità che le
classi hanno di implementare in modo differente i metodi e le proprietà che le
descrivono.
Il vantaggio principale del polimorfismo è che si può fare uso di oggetti che
espongono una stessa interfaccia, ma implementazioni assolutamente diverse.
L'interfaccia definisce un contratto generale che sottoclassi diverse possono
soddisfare in modi diversi ma tutte conformi alla specifica comune stabilita
dall’interfaccia stessa (metodi e proprietà definiti in essa).
In virtù di questa possibilità, si può utilizzare le stesse firme esposte
dall’interfaccia personalizzandone o modificandone anche radicalmente il
comportamento.
Il polimorfismo viene permesso grazie ai concetti di Interfaccia, Overloading
dei metodi o l’Overriding delle classi.
Le interfacce
L’interfaccia è una classe che definisce le strutture dati e i metodi da
implementare ma non ne descrive il comportamento (il codice).
Di fatto una interfaccia serve quando differenti classi devono essere
standardizzate o meglio dire disporre di funzionalità comuni.
L’interfaccia non è istanziabile come una comune classe e quindi non può essere
caricata in memoria ma fornisce direttive alle classi che la utilizzano su cosa
dovranno implementare al loro interno.
Le interfacce spesso rappresentano il componente di livello più alto di
un'applicazione. Esse possono essere usate per migliorare l'estensibilità e la
riusabilità di un programma object oriented.
Nell’esempio sotto riportato scritto in VB.NET viene creata l’interfaccia IVeicle
nella quale sono presenti 3 proprietà e un metodo.
La classe Car che implementa l’interfaccia IVeicle è costretta ad implementare
al suo interno quanto descritto dall’interfaccia.
21. 'Main della Console Application
Module Module1
Sub Main()
Dim car As New Car(2000, 120, 130)
car.GetInfo()
Dim airplane As New Airplane(2000, 120, 130, 110)
airplane.GetInfo()
Threading.Thread.Sleep(10000)
End Sub
End Module
'Interfaccia IVeicle dalla quale implementeranno le successive due classi
Public Interface IVeicle
ReadOnly Property GetVelocity As Integer
ReadOnly Property GetWeight As Integer
ReadOnly Property GetDisplacement As Integer
Sub GetInfo()
End Interface
'Classe Car che implementa IVeicle
Public Class Car
Implements IVeicle
Private Displacement As Integer
Private Velocity As Integer
Private Weight As Integer
Public Sub New(ByVal Displacement As Integer, _
ByVal Velocity As Integer, _
ByVal Weight As Integer)
Me.Displacement = Displacement
Me.Weight = Weight
Me.Velocity = Velocity
End Sub
Public ReadOnly Property GetDisplacement As Integer Implements IVeicle.GetDisplacement
Get
Return Displacement
End Get
End Property
Public ReadOnly Property GetVelocity As Integer Implements IVeicle.GetVelocity
Get
Return velocity
End Get
End Property
Public ReadOnly Property GetWeight As Integer Implements IVeicle.GetWeight
Get
Return Weight
End Get
End Property
Public Sub GetInfo() Implements IVeicle.GetInfo
System.Console.Write("La tipologia del veicolo è : [Automobile]" & vbCrLf)
System.Console.Write("La velocità del veicolo è : " & GetVelocity & vbCrLf)
System.Console.Write("Il peso del veicolo è : " & GetWeight & vbCrLf)
System.Console.Write("La cilindrata del veicolo è : " & GetDisplacement & vbCrLf)
End Sub
End Class
'Classe Airplane che implementa IVeicle
Public Class Airplane
Implements IVeicle
Private Displacement As Integer
Private Velocity As Integer
Private Weight As Integer
Private wingspan As Integer
Public Sub New(ByVal Displacement As Integer, _
ByVal Velocity As Integer, _
22. ByVal Weight As Integer, _
ByVal wingspan As Integer)
Me.Displacement = Displacement
Me.Weight = Weight
Me.Velocity = Velocity
Me.wingspan = wingspan
End Sub
Public ReadOnly Property GetDisplacement As Integer Implements IVeicle.GetDisplacement
Get
Return Displacement
End Get
End Property
Public ReadOnly Property GetWingspan As Integer
Get
Return wingspan
End Get
End Property
Public ReadOnly Property GetVelocity As Integer Implements IVeicle.GetVelocity
Get
Return Velocity
End Get
End Property
Public ReadOnly Property GetWeight As Integer Implements IVeicle.GetWeight
Get
Return Weight
End Get
End Property
Public Sub GetInfo() Implements IVeicle.GetInfo
System.Console.Write("La tipologia del veicolo è : [Areoplano]" & vbCrLf)
System.Console.Write("La velocità del veicolo è : " & GetVelocity & vbCrLf)
System.Console.Write("Il peso del veicolo è : " & GetWeight & vbCrLf)
System.Console.Write("La cilindrata del veicolo è : " & GetDisplacement & vbCrLf)
System.Console.Write("L'apertura alare del veicolo è : " & GetWingspan & vbCrLf)
End Sub
End Class
Ciò non toglie che se volessimo creare la classe Elicopter anche questa potrà
implementare l’interfaccia IVeicle.
Infatti il concetto astratto di Veicolo e univoco e quindi i metodi presenti
all’interno dell’interfaccia IVeicle potranno descrivere e accomunare le due classi
Elicottero e Car e Airplane.
Ora un esempio in Java
package interfaceCars;
public interface ICars {
public void Body();
public void Velocity(String value);
public void Fuel(int value);
}
Il perché utilizzare le interfacce diventa chiaro quando abbiamo classi diverse che
però svolgono simili funzioni.
Pensiamo ad esempio ai driver che permettono alle nostre applicazioni di
connettersi ai database.
Ogni driver(sviluppato da persone differenti) permette di eseguire le stesse
23. funzioni, ma su database diversi (es. SQL Server ed Oracle).
Se ognuna di queste due classi implementasse la connessione al DB con metodi
differenti, ad esempio la prima con il metodo Open e l’altra con il metodo
Connection, il programmatore sarebbe costretto ad imparare il funzionamento
di entrambe.
Creando l’interfaccia System.Data.IDbConnection standardizzeremo le
strutture dati principali. Ora se tutti i driver dei diversi produttori
implementassero tale interfaccia sarebbero costretti a scrivere i metodi Open,
Close, BeginTrasaction, ecc…
Di conseguenza tutti i driver disporranno di strutture dati omogenee ma con
codice al loro interno differente e quindi il programmatore conosciuto il
funzionamento dell’interfaccia, potrà tranquillamente trascurare il
comportamento di ogni singola classe.
Per concludere, esistono alcuni linguaggi di programmazione che permettono
l’uso di interfacce multiple come ad esempio Java. Di fatto questa funzionalità
non è molto utilizzata ma può essere utili in speciali condizioni dove l’uso delle
interfacce si fa molto intensivo.
24. Le classi astratte
La classe astratta è una interfaccia che oltre a fornire firme sulle strutture dati da
implementare contiene al suo interno del proprio codice.
Nell’esempio successivo scritto in C# abbiamo la classe astratta ClassAbstract
nella quale viene definito il metodo Add e viene implementato il metodo
ReturnValue.
A differenza dell’interfaccia (dato che la classe astratta al suo interno è presente
del codice) deve essere ereditata e non implementata.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
ClassUsingAbstract a = new ClassUsingAbstract();
a.Add(12, 23);
System.Console.Write(a.GetResult());
}
}
public abstract class ClassAbstract
{
public abstract void Add(int a, int b);
public string ReturnValue(int value)
{
return "Il valore è : " + value;
}
}
class ClassUsingAbstract : ClassAbstract
{
int sum;
public override void Add(int a, int b)
{
sum = a + b;
}
public string GetResult()
{
return ReturnValue(sum);
}
}
}
E un esempio in VB.NET
Module Module1
Sub Main()
Dim dog As New Dog
dog.print("Il cane")
25. Dim fish As New Fish
fish.print("Il pesce")
Threading.Thread.Sleep(10000)
End Sub
End Module
'Classe astratta Animals
Public MustInherit Class Animals
Public MustOverride Function Mangia() As String
Public MustOverride Function Vive() As String
Public Sub print(ByVal TipoAnimale As String)
System.Console.WriteLine(TipoAnimale & " Mangia : " & Mangia())
System.Console.WriteLine(TipoAnimale & " Vive : " & Vive())
End Sub
End Class
Public Class Dog
Inherits Animals
Public Overrides Function Mangia() As String
Return "La carne"
End Function
Public Overrides Function Vive() As String
Return "sulla terra"
End Function
End Class
Public Class Fish
Inherits Animals
Public Overrides Function Mangia() As String
Return "Il plancton"
End Function
Public Overrides Function Vive() As String
Return "nel mare"
End Function
End Class
Un esempio in Java
package animals;
public abstract class Animals {
public abstract String Cammina();
public abstract String Mangia();
public abstract String Vive();
}
La classe Astratta è meno autoritativa rispetto all’interfaccia che descrive solo le
strutture dati.
Le classi astratte vengono in forte aiuto quando occorre definire degli standard
ma specializzarne anche un comportamento.
E’ molto importante capire la differenza tra classe astratta e Interfaccia e spesso
(in particolare agli inizi) occorre chiedersi se sia più giusto utilizzare una o l’altra.
26. L’overriding
Per Overriding (sovrascrittura in italiano) si intende la capacità di ridefinire un
metodo presente nella classe ereditata.
il metodo originale (presente nella classe padre) e quello che lo ridefinisce
(presente nella classe figlia) devono avere necessariamente la stessa firma e
quindi lo stesso nome, lo stesso tipo di ritorno e la stessa lista di parametri di
ingresso, di fatto la firma deve essere identica.
Sarà il compilatore in fase di run-time a determinare quali dei due dovrà essere
eseguito.
Nell’esempio sotto riportato scritto in VB.NET, la classe Cars e Airplane
ereditano entrambe dalla classe Veicle la quale mette a loro disposizione una
serie di proprietà comuni
Public Class Veicle
Private Velocity As Integer
Private Weight As Integer
Private Displacement As Integer
Public Sub New(ByVal Velocity As Integer, _
ByVal Weight As Integer, _
ByVal Displacement As Integer)
Me.Velocity = Velocity
Me.Weight = Weight
Me.Displacement = Displacement
End Sub
Public ReadOnly Property getVelocity() As Integer
Get
Return Velocity
End Get
End Property
Public ReadOnly Property getWeight() As Integer
Get
Return Weight
End Get
End Property
Public ReadOnly Property getDisplacement() As Integer
Get
Return Displacement
End Get
End Property
Public Overridable Sub GetInfo()
System.Console.Write("La velocità del veicolo è : " & getVelocity & vbCrLf)
System.Console.Write("Il peso del veicolo è : " & getWeight & vbCrLf)
System.Console.Write("La cilindrata del veicolo è : " & getDisplacement & vbCrLf)
End Sub
End Class
Public Class Cars
Inherits Veicle
Public Sub New()
MyBase.new(160, 1300, 1200)
End Sub
End Class
27. Public Class Airplane
Inherits Veicle
'Definisco in più l'ampiezza alare in quanto propria della classe Aeroplano
Private Wingspan As Integer
Public ReadOnly Property getWingspan() As Integer
Get
Return Wingspan
End Get
End Property
Public Sub New(ByVal Wingspan As Integer)
MyBase.New(350, 4000, 8000)
Me.Wingspan = Wingspan
End Sub
'Ridefinisco tramite il polimorfismo il metodo GetInfo
Public Overrides Sub GetInfo()
System.Console.Write("L'aperura alare è : " & getWingspan & vbCrLf)
System.Console.Write("La velocità del veicolo è : " & getVelocity & vbCrLf)
System.Console.Write("Il peso del veicolo è : " & getWeight & vbCrLf)
System.Console.Write("La cilindrata del veicolo è : " & getDisplacement & vbCrLf)
End Sub
End Class
‘Modulo per la creazione degli oggetti delle classi su Console Application .NET
Module Module1
Sub Main()
Dim A1 As New Cars()
A1.GetInfo()
Dim A2 As New Airplane(64)
A2.GetInfo()
End Sub
End Module
Nel caso però della classe Airplane, occorre definire oltre che alle proprietà
comuni implementate in Veicle la proprietà Wingspan la quale viene inserita
all’interno di Airplane.
Inoltre, visto che il metodo GetInfo di Veicle non riporta anche la
visualizzazione della proprietà Wingspan, il metodo viene sovrascritto nella
classe Airplane ma rimane immutato il suo funzionamento all’interno della
classe padre Veicle.
28. L’overloads
Per Overloads (sovraccarico in italiano) si intende la capacità di poter descrivere
metodi con lo stesso nome ma con firma differente all’interno della stessa classe.
Un esempio di Overload viene riportato di seguito con il linguaggio C#.
Noteremo che l’unica cosa che viene mantenuta è il nome del metodo, ma i
parametri di input devono per forza essere differenti da metodo a metodo.
Un esempio in C#
class ExampleOverload
{
public void sum(int a, int b) {
}
public int sum(int a, int b, int c){
return a + b + c;
}
public String sum(int a, int c){
return System.Convert.ToString(a + c);
}
}
Un esempio in VB.NET
Public Class OverloadClass
Public Sub PrintValue(ByVal Nome As String)
System.Console.WriteLine("Nome : " & Nome)
End Sub
Public Sub PrintValue(ByVal Nome As String, ByVal Cognome As String)
System.Console.WriteLine("Nome : " & Nome)
System.Console.WriteLine("Cognome : " & Cognome)
End Sub
Public Function PrintValue() As String
Return "Massimiliano Brolli"
End Function
End Class
Non è possibile avere due metodi con stessi parametri di input ma con diverso
parametro di output per intenderci in C# uno void e l’altro int.
A garantire il corretto funzionamento dell’Overload sarà il compilatore che
determinerà quale dei metodi verrà invocato sulla base del numero e del tipo dei
parametri inviati.