Programmazione orientata agli Oggetti. Classi Le classi sono uno strumento per costruire strutture dati che contengano non solo dati ma anche il codice.

Slides:



Advertisements
Presentazioni simili
Informatica Recupero debito quarto anno Terzo incontro.
Advertisements

Programmazione object oriented in C++
Java base IV: Java e la programmazione O.O.
Fondamenti di Informatica 2 Ingegneria Informatica Docente: Giovanni Macchia a.a
Esercitazione del 9 marzo 2007 Ereditarieta’. Richiami Definire sottoclassi (ereditarieta’) Overriding Specificatori di accesso (private, protected) Principio.
Corso di Algoritmi e Strutture Dati con Laboratorio Richiami di Java – parte II.
Introduzione all’Ereditarietà Pietro Palladino. Richiami UML Classe: descrizione di un insieme di oggetti software con caratteristiche simili Definisce.
Introduzione alle Classi e agli Oggetti in Java 1.
Table View. Problemi ricorrenti Una situazione ricorrente è quella in cui il controller potrebbe avere un’altezza superiore a quella dello schermo. In.
Fondamenti di Informatica - D. Talia - UNICAL 1 Fondamenti di Informatica FONDAMENTI DI INFORMATICA Domenico Talia
CORSO elementare su DATABASE Applicativo utilizzato OpenOffice 3.0.
1 Elementi DI INFORMATICA Università degli Studi di Cagliari Corso di Laurea in Ingegneria Elettronica Linguaggio C A.A. 2011/2012
Fondamenti di Informatica A - Massimo Bertozzi LE FUNZIONI.
Programmazione in Java Parte I: Fondamenti Lezione 1 Dott. Marco Faella.
Programmazione in Java Parte II Lezione 5 Dott. Marco Faella.
.  I tipi di dati non primitivi sono gli array, le struct e le union.  Gli array sono degli aggregati di variabili dello stesso tipo.  La dichiarazione.
Basi di dati - Fondamenti
Ereditarietà Uno dei principi della programmazione orientata agli oggetti (OOP) è il riuso Le classi dovrebbero essere progettate come componenti riutilizzabili.
© 2007 SEI-Società Editrice Internazionale, Apogeo
Alcune note, dalla rete, sui Sistemi cellulari
Tecnologia OO.
Java World Introduzione.
ODMG.
Rielaborato da Atzeni et al., Basi di dati, Mc-Graw Hill
Java: concetti e costrutti base
Introduzione al linguaggio C
Elementi di Informatica
Esercizi.
Universita’ di Milano Bicocca Corso di Basi di dati 1 in eLearning C
Il Binding Nicolò Sordoni.
I PERMESSI IN LINUX.
Programmazione a oggetti
I vincoli di integrità Alcuni aspetti della realtà NON possono essere modellati solamente con entità, attributi e relazioni, per esempio i vincoli di integrità.
Programmazione a oggetti
UML Creato da: Enrico Tarantino Alessandro Vilucchi Roberta Barcella.
Tipo di dato: array Un array è un tipo di dato usato per memorizzare una collezione di variabili dello stesso tipo. Per memorizzare una collezione di 7.
Programmazione ad Oggetti per la Fisica
Corso Java Introduzione.
Vettori dinamici Definiremo la classe vector.
Gli oggetti: concetti avanzati
Corso di Laurea Ingegneria Informatica Fondamenti di Informatica
FONDAMENTI DI INFORMATICA II Ingegneria Gestionale a. a
OBJECT ORIENTED DATABASE
Access.
Basi di dati - Fondamenti
Programmare.
Package Pacchetti e ereditarietà 29/12/2018 package.
Esercitazioni di C++ 31 dicembre 2018 Claudio Rocchini IGMI.
Oggetti Java.
Copia di oggetti il costruttore di copia ha le stesse particolarità della signature di un costruttore ordinario; il primo parametro è una reference ad.
Il passaggio dei parametri Metodi statici Il riferimento this
Ricorsione 16/01/2019 package.
© 2007 SEI-Società Editrice Internazionale, Apogeo
Definizione di linguaggio di programmazione
APPUNTI SUL LINGUAGGIO C
Corso di Laurea Ingegneria Informatica Fondamenti di Informatica
Corso di Laurea Ingegneria Informatica Fondamenti di Informatica
OpenLayers Client di mappe “non solo” WMS
La struttura dei primi programma in C
APPUNTI SUL LINGUAGGIO C Allocazione dinamica della memoria
APPUNTI SUL LINGUAGGIO C
Strategie di progetto Si possono utilizzare le strategie tipiche dello sviluppo di un processo di ingegnerizzazione (es. ingegneria del software). Strategie.
Interfacce in Java Superare il meccanismo dell’ereditarietà singola
Unità 1 Programmi base.
Corso Java Lezione 1 5/12/2019.
Java Introduzione.
UML Diagramma statico di una classe
Array e Stringhe Linguaggio C.
Ese 1 (del 31 Marzo 2004).
Transcript della presentazione:

Programmazione orientata agli Oggetti

Classi Le classi sono uno strumento per costruire strutture dati che contengano non solo dati ma anche il codice per gestirli. Come tutti i costrutti che permettono di definire le strutture dati, una classe definisce un nuovo tipo di dato. I membri di una classe sono dati (esattamente come i membri di un record), chiamati attributi, e metodi, ovvero procedure, che operano su un oggetto. Dal punto di vista matematico, una classe definisce un insieme in modo intensivo, ovvero definendone le caratteristiche invece che elencandone gli elementi. Se l'accesso agli attributi è ristretto ai soli membri della classe, le caratteristiche dell'insieme possono includere vincoli sui possibili valori che la tupla degli attributi può o non può assumere, e anche sulle possibili transizioni tra questi stati. Una classe può dichiarare riservate una parte delle sue proprietà e/o dei suoi metodi, e riservarne l'uso a sé stesso e/o a particolari tipi di oggetti a lui correlati.

Oggetto Un oggetto è una istanza di una classe. Un oggetto occupa memoria, la sua classe definisce come sono organizzati i dati in questa memoria. 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. Il paradigma OOP suggerisce un principio noto come information hiding che indica che si debba accedere agli attributi dell'istanza solo tramite metodi invocati su quello stesso oggetto. Sintatticamente, i metodi di una classe vengono invocati "su" un particolare oggetto, e ricevono come parametro implicito l'oggetto su cui sono stati invocati. Questo parametro normalmente può essere referenziato esplicitamente; per esempio, a tale scopo in C++, inJava, e in C# si usa la parola chiave this, mentre in Smalltalk, in Objective-C, Python e in Ruby si usa la parola-chiave self.C++JavaC#SmalltalkObjective-CPythonRuby Gli oggetti effettivamente creati sono membri dell'insieme definito dalla loro classe. Molti linguaggi forniscono un supporto per l'inizializzazione automatica di un oggetto, con uno o più speciali metodi detti costruttori.

L'incapsulamento L'incapsulamento è la proprietà per cui un oggetto contiene ("incapsula") al suo interno gli attributi (dati) e i metodi (procedure) che accedono ai dati stessi. Lo scopo principale dell'incapsulamento è appunto dare accesso ai dati incapsulati solo attraverso i metodi definiti, nell'interfaccia, come accessibili dall'esterno. Gestito in maniera intelligente, l'incapsulamento permette di vedere l'oggetto come una black-box, cioè una scatola nera di cui, attraverso l'Interfaccia sappiamo cosa fa e come interagisce con l'esterno ma non come lo fa. I vantaggi principali portati dall'incapsulamento sono: robustezza, indipendenza e l'estrema riusabilità degli oggetti creati...

Ereditarietà L'OOP prevede un meccanismo molto importante, l'ereditarietà, che permette di derivare nuove classi a partire da classi già definite. L'ereditarietà permette di aggiungere membri ad una classe, e di modificare il comportamento dei metodi, in modo da adattarli alla nuova struttura della classe. Da una stessa classe è possibile costruire diverse classi derivate. Da una classe derivata è possibile derivarne un'altra con lo stesso meccanismo. Sintatticamente, una classe può essere definita come derivata da un'altra classe esistente. In molti linguaggi la classe derivata, o sottoclasse, eredita tutti i metodi e gli attributi della classe "genitrice", e può aggiungere membri alla classe, sia attributi che metodi, e/o ridefinire il codice di alcuni metodi. L'ereditarietà può essere usata come meccanismo per gestire l'evoluzione ed il riuso del software: il codice disponibile definisce delle classi, se sono necessarie modifiche, vengono definite delle sottoclassi che adattano la classe esistente alle nuove esigenze.

Sottotipazione Se un oggetto di una sottoclasse può essere utilizzato al posto di un'istanza della superclasse, il tipo della classe derivata è detto sottotipo. Questo richiede che tutti i metodi della superclasse siano presenti nella sottoclasse, e che le signature siano compatibili. Di conseguenza, una sottoclasse che voglia definire un sottotipo può ridefinire i metodi della superclasse, ma non può eliminarli sintatticamente né modificare le loro signature. In numerosi linguaggi, invece, una sottoclasse può decidere di eliminare o cambiare le proprietà di accesso ad un metodo, il che fa sì che l'operazione di subclassing non sia corrispondente a quella di subtyping.

Esempio di Ereditarietà: I mammiferi

Classi in java

Classi e Oggetti Java Esclusi i tipi primitivi (boolean, char, byte, short, int, long, float, double), in Java esistono solo: CLASSI – componenti software che possono avere i loro dati e le loro funzioni – vengono usate come “struttura” per costruire oggetti OGGETTI – entità dinamiche costruite al momento del bisogno secondo la definizione di una classe che ne descrive le proprietà

Nota Gli Oggetti sono elementi distinti di una classe che condividono delle caratteristiche. Ogni Metodo è un insieme di istruzioni che una classe o un oggetto rendono disponibili ad altre classi e/o oggetti, affinché possa essere eseguito su richiesta. Non occorre preoccuparsi della distruzione degli oggetti: Java ha un garbage collector.

Definire una classe in java equivale al creare un nuovo tipo di dato (una nuova classe di oggetti)

Attributi ▪Gli attributi di una classe definiscono la struttura dello stato degli oggetti che vi appartengono ▪Ogni attributo è definito usando la stessa sintassi usata per la definizione delle variabili locali ▪Convenzioni: scrivere gli attributi in minuscolo (tecnologia e non Tecnologia) ▪Sintassi: ogni attributo è definito usando la stessa sintassi usata per la definizione delle variabili locali

Attributo

Metodi

Ricapitoliamo.... Nella classe vengono dichiarati: ▪i costruttori, che determinano le modalità di creazione degli oggetti; ▪le variabili o attributi di istanza, che costituiscono lo stato degli oggetti; ▪i metodi di istanza, che realizzano le funzionalità degli oggetti.

Quando Creiamo un oggetto con il costruttore e l'operatore new "cosa succede ?" La creazione di un oggetto è un processo costituito dalle seguenti fasi: Allocare lo spazio di memoria necessario a contenere l'oggetto Inizializzare le variabili di istanza dell'oggetto Per contenere un oggetto la quantità di memoria necessaria è determinata soltanto dalla dichiarazione della classe (precisamente, dal numero e dal tipo delle variabili di istanza) Lo spazio necessario viene allocato in una zona di memoria chiamato heap.

Operatore New L’operatore new è alla base del linguaggio Java. Mediante esso viene creata una nuova istanza di un oggetto appartenente ad una determinata classe e, conseguentemente, viene allocata automaticamente la memoria necessaria nell’heap per conservare tale istanza. L’operatore new, per eseguire la creazione di un oggetto, invoca il costruttore della classe che si desidera istanziare.

Cosa abbiamo fatto fino ad ora

Esempio di classe public class Contatore { private int valore; public String tecnologia; public void incrementa (){ valore++; } public void reset() { valore=0; } public int getValore() { return valore=0; } public Contatore() { valore=0; }

Visibilità di metodi e attributi

Modificatori di Accesso. I modificatori sono parole riservate che forniscono al compilatore informazioni sulla natura del codice, dei dati e delle Classi contenuti nei file sorgenti. Fra tutti i modificatori alcuni possono essere raggruppati in una singola categoria che ne specifica il comportamento, essi sono i modificatori di accesso: ▪private ▪protected ▪public In assenza di questi tre, un elemento di programma viene considerato package-local o friend (si dice che assume la visibilità di default).

Private private è il modificatore di accesso più restrittivo. I metodi e gli attributi dichiarati private, non sono visibili né usabili all'esterno della classe che li contiene. Due oggetti della stessa classe però, possono vedere i rispettivi attributi e metodi privati. Tuttavia è possibile accedervi dall'esterno mediante metodi di lettura e modifica dei valori: metodi "get" e "set". La possibilità di usare valori con il modificatore private è un punto importante della programmazione a oggetti. In questo modo i valori private vengono incapsulati, rendendo impossibile il loro richiamo o modifica da parte di altre porzioni di codice, a causa di disattenzione o casualità, o perfino di codice malevolo. Ovvero per leggerli o modificarli occorre implementare e chiamare appositamente i metodi get e set.incapsulati Dunque ove possibile bisogna sempre editare come private gli elementi del programma, è una indicazione forte ma non un obbligo.

Protected Il modificatore protected può essere attribuito solo ai metodi e alle variabili interne alla classe e non può essere applicato alla classe stessa. I metodi e le variabili dichiarate come protected sono visibili da classi dichiarate nello stesso package e da sottoclassi e classi derivate dichiarate ovunque. Si può dire che è leggermente più restrittivo di public.

Default Si applica a tutti gli elementi della classe e ad essa stessa. Il modificatore di default viene assegnato automaticamente dal compilatore solo quando nella scrittura del sorgente si omettono gli altri modificatori. Di default indica che l'elemento è di accesso pubblico ma solo ed esclusivamente al package della classe dove è inserito, diversamente da public e protected dove è visibile anche in package esterni. Si può dire che è leggermente più restrittivo di protected.

Public Il modificatore public può essere attribuito a tutti gli elementi di una classe. public definisce l'elemento del programma come "pubblico" e quindi questo è visibile e modificabile dall'esterno della classe, da qualsiasi package.

Ereditarietà

Principio che consente a una classe di ereditare le variabili e i metodi di un’altra classe Consente di raffinare le caratteristiche di classi di oggetti a partire da classi generali riutilizzo del codice 

Superclasse Sottoclasse

Esempio

A cosa serve l'ereditarietà Permette di riutilizzare il codice delle classi già definite ▪Posso definire un nuovo Pesce senza preoccuparmi di dover ridefinire come respira ▪Le nuove classi aggiungono funzionalità ma sono COMPATIBILI con le vecchie ▪Posso definire un nuovo tipo di Uccello e utilizzarlo come se fosse un Uccello o un Animale e basta ▪Posso non dover/voler conoscere il tipo specifico! principio di sostituibilità

Sintassi

Costruttori e operatore super La classe derivata eredita tutte le variabili e i metodi della classe base La classe derivata NON eredita il costruttore Se la classe base ha un costruttore senza parametri la classe derivata richiama quello Se la classe base NON ha un costruttore senza parametri la classe derivata deve esplicitamente richiamarlo: super

Classe astratta Una classe astratta non può in alcun modo essere istanziata, quindi può essere utilizzata esclusivamente come classe base. Quando estendiamo (o deriviamo) da una classe astratta, la classe derivata deve fornire una implementazione per tutti i metodi astratti dichiarati nella classe genitrice; se così non dovesse essere, anche la sotto-classe deve essere dichiarata come abstract.

Abstract Una classe astratta (abstract) è una classe di cui non possono essere istanziati oggetti Possono essere istanziati oggetti solo delle sue sottoclassi Permette di definire un comportamento generale

MyProcess myProcess = new MyProcess(); // AbstractProcess myProcess = new MyProcess(); // equivalente alla precedente myProcess.process(); public abstract class AbstractProcess { public void process() { init(); baseAction(); stepAfter(); } public void init() { // metodo dichiarato direttamente // all'interno della classe astratta } public abstract void baseAction(); // metodo astratto la cui implementazione // è demandata alla sottoclasse public void stepAfter() { // metodo dichiarato direttamente // all'interno della classe astratta } class MyProcess extends AbstractProcess public void baseAction() { // implementazione del metodo baseAction() } Notiamo che il metodo baseAction() nella classe AbstractProcess è astratto, quindi la sottoclasse che la estende deve effettuarne l’Overidde e darne l’implementazione (altrimenti anch’essa dovrebbe essere dichiarata abstract). A questo punto la chiamata al metodo process():

Interfaccia Molto spesso le interfacce vengono confuse con le classi astratte dato che dal punto di vista logico sono molto simili, ma le interfacce possono essere intese come un'evoluzione delle classi astratte e permettono, di fatto, di simulare l'ereditarietà multipla. Il vantaggio principale di una interfaccia, essendo comunque una classe anche se con proprietà particolari, è quello che oltre ad essere estesa può essere implementata. La differenza tra estendere e implementare è molto grande in quanto una classe può essere eriditata solo ed esclusivamente una volta, mentre una classe può implementare infinite interfacce permettendo così l'ereditarietà multipla.

Vediamo adesso, dal punto di vista del codice, come si dichiara un'interfaccia e come la si implementa. La dichiarazione avviene usando la parola chiave interface in questo modo: public interface Prova { //contenuto } L'implementazione dell'interfaccia è invece possibile utilizzando la parola chiave implements: public class Implementazione implemets Prova { //contenuto }

Interfacce Classi astratte Istanziabileno Fieldssolo static finalsì Costruttorenosì Metodi staticiJava8+sì Dichiarazione metodi (virtual)nosì Implementazione metodijava8+ (con il qualificatore default)sì

Quando utilizzare l’interfaccia e quando la classe astratta? In base a quanto detto, cosa è meglio utilizzare? Ed in quali circostanze? ▪Si usa una classe astratta per condividere codice fra più classi, se più classi hanno in comune metodi e campi o se si vogliono dichiarare metodi comuni che non siano necessariamente campi static e final. ▪Si decide di utilizzare una interfaccia se ci si trova nella situazione in cui alcune classi (assolutamente non legate fra di loro) si trovano a condividere i metodi di una interfaccia, se si vuole specificare il comportamento di un certo tipo di dato (ma non implementarne il comportamento) o se si vuole avere la possibilità di sfruttare la “multiple inheritance”.

Polimorfismo Java

Cosa è esattamente il polimorfismo? Il polimorfismo ci permette di fare riferimento ad un’entità utilizzandone un’altra; il concetto in sè non è semplice da comprendere ma cerchiamo di analizzarlo più nel dettaglio, distinguendo due tipi di polimorfismo: ▪Polimorfismo per metodi ▪Polimorfismo per dati

Overriding (polimorfismo dei metodi)

Final

Casting

Un po' di esercizi

Ripassiamo OVERRIDING : si scrive in una sottoclasse un metodo della superclasse con la stessa segnatura OVERLOADING: è possibile definire metodi con lo stesso nome ma con segnature differenti Cos’è la SEGNATURA? È la «firma» del metodo costituita dal nome del metodo, dal numero dei suoi parametri e dal loro tipo Lo stesso nome di un metodo può essere usato per operazioni diverse, con definizioni diverse che richiedono un diverso tipo o numero di parametri.

Definire una classe Dipendente che ha i seguenti campi: Nome Cognome oreLavorativeMensili retribuzioneOraria Scrivere un metodo che calcola lo stipendio del dipendente nel seguente modo: Stipendio=oreLavorativeMensili * retribuzioneOraria Si definisca anche un particolare tipo di dipendente responsabile di progetto, al cui stipendio del dipendente (vedi sopra) viene aggiunto un bonus: Stipendio=oreLavorativeMensili * retribuzioneOraria + bonus Scrivere un main() che calcoli lo stipendio per una persona Dipendente e per una persona DipendenteResponsabile.

class Animale{ private String nome; public Animale(String s){ nome = s; } public String comeTiChiami() { return nome; } public void parla(){} public void incontra(Animale a){ System.out.println(nome + “: ”); parla(); }

Si costruiscano due classi Topo e Gatto che estendono la classe Animale. In particolare le due classi devono ridefinire il metodo parla():  Il topo deve ridefinire il metodo in modo che esso stampi sullo schermo «Squit»  Il gatto deve ridefinire il metodo in modo che esso stampi sullo schermo «Miao»  Si aggiunga ora nella classe Topo una nuova versione del metodo incontra() che prende come argomento un oggetto di tipo Gatto e stampa: System.out.println(nome + “: ”);  Analogamente per il Gatto si aggiunga una nuova versione del metodo incontra() che prende come argomento un oggetto di tipo Topo e stampa: System.out.println(nome + “: ”); Scrivere un main() per verificarne il funzionamento