Sei sulla pagina 1di 58

Implementazione di classi

Lezione IX

Scopo della lezione


Laboratorio di Programmazione

Imparare a costruire delle classi a partire da esempi

IX-B.2

Gerarchia di figure estesa


Shape
<<interface>>

Laboratorio di Programmazione

+calculateArea +calculatePerimeter +draw

Comparable
+compareTo(o:Object): int

Rectangle
+calculateArea +calculatePerimeter +getHeight

Circle
+calculateArea +calculatePerimeter

Square
+calculateArea +calculatePerimeter

Questa la gerarchia delle classi usata come esempio. Abbiamo tre classi concrete, una classe astratta (Shape) e uninterfaccia (Comparable). Nel seguito entreremo nel merito di come queste classi debbano essere scritte allo scopo di imparare a scriverne altre

IX-B.3

Attenzione!
Laboratorio di Programmazione

Nel seguito costruiremo, a partire da zero, le classi di questa gerarchia E importante quindi rimuovere dal vostro computer degli eventuali riferimenti al file .jar utilizzato nella lezione precedente

IX-B.4

Classi in Java
Esempio di definizione di classe
Laboratorio di Programmazione public class Rectangle extends Shape { }

In generale:
[ClassModifiers] class ClassName [extends ParentName] [implements InterfaceList]

extends definisce le regole di ereditariet implements definisce le interfacce da implementare ClassModifiers indicano le modalit di accesso o le caratteristiche della classe
IX-B.5

Classi in Java
Laboratorio di Programmazione

Considerare alcuni dei programmi scritti fino ad ora, e paragonare la definizione delle classi con il modello mostrato nella slide precedente

IX-B.6

Contenuto delle classi


Laboratorio di Programmazione

Allinterno della coppia di parentesi graffe che segue la definizione di una classe si possono definire
Delle variabili di istanza (o attributi, o campi) che caratterizzano lo stato di unistanza della classe Dei metodi (o funzioni) che caratterizzano le azioni che si possono effettuare sulle istanze della classe
IX-B.7

Variabili di istanza
Laboratorio di Programmazione

Le variabili di istanza si definiscono nello stesso modo delle variabili che fino ad ora abbiamo definito e utilizzato allinterno del metodo main Lunica differenza sta nel fatto che queste variabili sono definite allinterno della classe ma NON allinterno di un metodo
IX-B.8

Variabili di istanza
Esempi
Laboratorio di Programmazione private double height = 0.0; private double width = 0.0;

In generale:
[FieldModifiers] TypeId VariableId [Initializer]

Le variabili di istanza hanno visibilit a livello di classe, quindi possono essere usate ovunque allinterno della classe
IX-B.9

Variabili di istanza
Laboratorio di Programmazione

Allinterno di una classe possibile fare riferimento a una variabile di istanza scrivendo il nome dellistanza seguito da un punto e dal nome della variabile:
Rectangle r = new Rectangle(10, 4); System.out.println(r.height)

IX-B.10

Variabili distanza
Gli attributi possono essere
Laboratorio di Programmazione

public, a indicare che possibile accedere alle variabili di istanza anche dallesterno della classe private, a indicare che possibile accedere alle variabili di istanza solo dallinterno della classe protected, a indicare che possibile accedere alle variabili di istanza solo dallinterno della classe e delle sottoclassi
IX-B.11

Metodi
Laboratorio di Programmazione

I metodi si definiscono nello stesso modo che abbiamo utilizzato per definire il metodo main Allinterno di una classe tipicamente sono definiti pi metodi

IX-B.12

Definizione di metodi
Esempio
Laboratorio di Programmazione public double calculateArea() { return height*width;}

In generale:
[MethodModifiers] ResultType MethodId ([FormalParametersList])
public static void main public double calculateArea public int compareTo public void draw (String args[]) () (Object o) ()
IX-B.13

Costruttore
Laboratorio di Programmazione

Ogni classe implementa un metodo particolare, detto costruttore e avente lo stesso nome della classe, che specifica come creare una nuova istanza della classe Questo metodo viene implicitamente chiamato quando si utilizza la parola chiave new
IX-B.14

Classe Rectangle
Laboratorio di Programmazione
public class Rectangle { private double height; private double width; // variabili d'istanza

public Rectangle(double h, double w) { // costruttore height = h; width = w; Il costruttore non ha un } tipo di ritorno esplicito // costruttore di Rectangle public double getHeight() {return height;} public double getWidth() {return width;} public void setHeight(double h) {height = h;} public void setWidth(double w) {width = w;} public void draw(){ System.out.println("I'm a Rectangle! My sides are:" +height+","+width); }
IX-B.15

Classe Rectangle
Laboratorio di Programmazione
public double calculateArea() { return height * width; } // calculateArea public double calculatePerimeter() { return 2 * (height+width); } height e width sono variabili private eppure le posso usare }// classe Rectangle

IX-B.16

Esercizio
Laboratorio di Programmazione

Implementare la classe Rectangle e verificare che venga compilata correttamente Verificare il corretto funzionamento di Rectangle creando una classe TestRectangle contenente solo un metodo main che istanzia Rectangle e prova ad accedere alle sue variabili di istanza e ai suoi metodi
IX-B.17

Esercizio
Laboratorio di Programmazione

Verificare che cosa succede quando si tenta di accedere a variabili di istanza o metodi private Come sarebbe possibile modificare il codice di Rectangle per permettere laccesso alle variabili di istanza private? Come potete verificare che quando viene utilizzata new viene chiamato il costruttore?
IX-B.18

Classe Rectangle (alternativa)


Laboratorio di Programmazione
public class Rectangle { private double height; // variabili d'istanza private double area; cambio rappr. interna, ma public Rectangle(double h, double w) { // costruttore height = h; area = h*w; mantengo linterfaccia. } // costruttore di Rectangle public double getHeight() {return height;} public double getWidth() {return area/height;} public void setHeight(double h) { area /= height; height = h; area *= height; }
IX-B.19

Classe Rectangle (alternativa)


Laboratorio di Programmazione
public void setWidth(double w) { area = height*w; } public void draw(){ System.out.println("I'm a Rectangle! My sides are: +height+","+this.getWidth()); } public double calculateArea() { return area; } // calculateArea public double calculatePerimeter() { return 2 * (height+this.getWidth()); } this rappresenta l'oggetto su cui il metodo stato invocato. } // classe Rectangle
IX-B.20

Esercizio
Laboratorio di Programmazione

Implementare questa nuova versione della classe Rectangle e verificare che si comporta esattamente come la classe precedentemente implementata

IX-B.21

Accesso pubblico/privato
Laboratorio di Programmazione

Le variabili di istanza solitamente sono dichiarate private. Questo le rende inaccessibili dagli altri oggetti Dei metodi pubblici forniranno un limitato e controllato accesso agli attributi privati (es. getWidth() e setWidth())

IX-B.22

Accesso pubblico/privato
Laboratorio di Programmazione

I metodi pubblici di un oggetto costituiscono la sua interfaccia, cio quella parte accessibile agli altri oggetti. Non vanno confusi con le interface

IX-B.23

Accesso pubblico/privato
Laboratorio di Programmazione

Nota: luso di attributi pubblici pu condurre ad uno stato inconsistente


Consideriamo la seconda implementazione di Rectangle con area e height definiti come attributi pubblici quindi si pu scrivere r.heigth=25; ma senza aggiornare di conseguenza larea, avremo che il metodo area() ritorner un valore inconsistente ci non capita usando setHeight()
IX-B.24

Esercizio
Laboratorio di Programmazione

Rendere public le variabili di istanza dellultima versione di Rectangle e verificare che modificandole in modo indiscriminato si verifica la situazione descritta nella slide precedente

IX-B.25

Progettazione dei metodi


Laboratorio di Programmazione

I metodi pubblici svolgono il ruolo di interfaccia della classe


se un metodo pensato per passare informazioni ad un altro oggetto, allora DEVE essere dichiarato pubblico

IX-B.26

Progettazione dei metodi


Laboratorio di Programmazione

I metodi definiti in una classe hanno visibilit a livello di classe; Indipendentemente dai diritti di accesso possono essere usati ovunque allinterno della classe I metodi che non ritornano dei valori devono essere dichiarati con tipo di ritorno void
IX-B.27

Parametri attuali e formali


Laboratorio di Programmazione

I parametri attuali rappresentano i valori passati ai metodi al momento dellinvocazione


Rectangle r1 = new Rectangle(3.0, 7.0); r1.setHeight(3*r1.getWidth());

I parametri attuali sono tipicamente espressioni che coinvolgono variabili, costanti ed altre espressioni

IX-B.28

Parametri attuali e formali


Laboratorio di Programmazione

Il tipo, il numero e lordine dei parametri attuali deve corrispondere al tipo, numero e ordine dei parametri formali usati nella definizione del metodo invocato
r1.setHeight(ciao) Errore: setHeight richiede un argomento di tipo double!

IX-B.29

Regole di accesso
Laboratorio di Programmazione

I package contengono classi che contengono metodi Gli accessi sono determinati dallelemento pi esterno a quello pi interno. Se non specificato alcun valore di accesso, viene utilizzato il valore di default
IX-B.30

Regole di accesso
Tipo di entit Dichiarazione N/A public default Membro (variabile o metodo) di una classe accessibile public protected private default Regole di accesso determinato dal sistema possibile se il package che la contiene accessibile possibile solo entro il package che la contiene Accessibile a tutti gli altri oggetti Accessibile alle classi nel package Accessibile solo entro la classe Accessibile solo entro il package
IX-B.31

Laboratorio di Programmazione

package classe

Flusso di esecuzione
Laboratorio di Programmazione

La chiamata di un metodo trasferisce il flusso di controllo alla prima istruzione del metodo chiamato Listruzione return o la fine del corpo del metodo invocato ritorna il controllo allistruzione del metodo chiamante che segue la chiamata stessa

IX-B.32

Flusso di esecuzione
Laboratorio di Programmazione

method1()
method2(); nextstatement;

method2()
statement1;

return;

IX-B.33

Progettazione OO: principi


Laboratorio di Programmazione

Incapsulazione: la classe Rectangle incapsula uno stato e le azioni che manipolano tale stato Information hiding: lo stato delle istanze di Rectangle privato

IX-B.34

Progettazione OO: principi


Laboratorio di Programmazione

Interfaccia: i metodi pubblici getHeight(), setHeight(), ... e calculatePerimeter() limitano le possibilit di utilizzo delle istanze di Rectangle Estendibilit: le funzionalit di Rectangle possono essere facilmente estese (vedi classe Square)
IX-B.35

Classe Square
Laboratorio di Programmazione
public class Square extends Rectangle { public Square (double side) { super(side, side); // costruttore del padre } riferisce la classe padre e permette di invocarne i metodi public void draw(){ metodo di Rectangle ridefinito System.out.println("I'm a Square! My side is: +getHeight()); } invocazione di un metodo ereditato } // Square

IX-B.36

Classe Square
Laboratorio di Programmazione

Square estende le funzionalt di Rectangle. Tutti i metodi e gli attributi definiti ed implementati in Rectangle, se non ridefiniti, sono ereditati tali e quali dalla classe Square Quando un metodo con lo stesso prototipo presente sia nella classe figlia che nella classe padre, il metodo della classe figlia ridefinisce quello del padre
IX-B.37

Esercizio
Laboratorio di Programmazione

Implementare la classe Square e verificare la sua correttezza tramite una nuova classe TestSquare Verificare che la classe pu accedere alle variabili di istanza public e protected della classe madre (eventualmente creandone di nuove), ma non a quelle private
IX-B.38

Esercizio
Laboratorio di Programmazione

Verificare che la classe Square pu accedere ai metodi public e protected della classe madre e che pu ridefinirli

IX-B.39

Costruttori
Laboratorio di Programmazione

I costruttori sono particolari metodi utilizzati per creare oggetti istanza di una classe
non sono ereditati dalle sottoclassi sono usati per inizializzare le variabili di istanza non ritornano un valore

IX-B.40

Esempio
Laboratorio di Programmazione
/** costruisce un quadrato a partire dalla lunghezza del suo lato. @param side la lunghezza del lato del quadrato. */ public Square (double side) { super(side, side); // costruttore del padre }

super una keyword speciale che identifica la classe padre e permette di invocarne i metodi (in questo caso il costruttore)
IX-B.41

Costruttori di default
Laboratorio di Programmazione

Se non viene definito alcun costruttore, Java fornisce un costruttore di default Se la classe pubblica, il costruttore di default pubblico: invocare il costruttore di default
Rectangle r = new Rectangle();

equivale ad invocare un costruttore definito come


public Rectangle() {}
IX-B.42

Classe Circle
public class Circle extends Shape { private double radius; // variabili d'istanza public Circle(double r) { // costruttore radius = r; } public void draw(){ System.out.println("I'm a Circle! My radius is: " +radius); } public double calculateArea() { return Math.PI*radius*radius; } // calculateArea public double calculatePerimeter() { return 2*Math.PI*radius; } }
IX-B.43

Laboratorio di Programmazione

Regole di visibilit
Laboratorio di Programmazione

La visibilit di un identificatore specifica dove quellidentificatore pu essere usato allinterno del programma
visibilit locale: la visibilit di un parametro limitata al metodo in cui dichiarato visibilit di classe: una variabile di istanza pu essere usata ovunque allinterno della classe

IX-B.44

Regole di visibilit
Laboratorio di Programmazione

Disegnare rettangoli attorno ai moduli del programma un buon modo per visualizzare le regole di visibilit

IX-B.45

Regole di visibilit
Laboratorio di Programmazione
public class Circle extends Shape { Visibilit // Dati di Classe private double ray; // variabili d'istanza // Costruttore public Circle(double r) { // costruttore ray = r; } // costruttore // Metodi public double calculateArea() { Visibilit double raySquare = ray*ray; Locale // var. a visibilit locale return Math.PI*raySquare; } // calculateArea } // Classe Circle

IX-B.46

Esercizio
Laboratorio di Programmazione

Implementare la classe Circle Dopo essere sicuri che la vostra implementazione esattamente uguale a quella descritta nella slide precedente, cercate di capire perch il compilatore emette errore, e solo dopo leggete la slide successiva

IX-B.47

Soluzione
Laboratorio di Programmazione

Lerrore dovuto al fatto che Circle una sottoclasse di Shape, una classe astratta che non abbiamo ancora definito

IX-B.48

Classe astratta: Shape


Laboratorio di Programmazione
public abstract class Shape { public abstract double calculateArea(); public abstract double calculatePerimeter(); public abstract void draw(); abstract introduce un metodo senza corpo }

IX-B.49

Esercizio
Laboratorio di Programmazione

Dopo avere implementato la classe Shape verificare che possibile compilare la classe Circle Modificare tutte le classi introdotte (se necessario) in modo che estendano direttamente o indirettamente Shape

IX-B.50

Interface
Laboratorio di Programmazione

Uninterfaccia contiene solo metodi astratti che devono essere implementati nella classe che accetta il contratto
public interface Comparable { public int compareTo(Object o); }

IX-B.51

Inteface
Laboratorio di Programmazione

Aggiungendo alla definizione di una classe la parola chiave implements seguita dal nome di uninterfaccia (o pi interfacce separate da virgola), si obbliga il programmatore a implementare i metodi descritti nellinterfaccia

IX-B.52

Interface
Laboratorio di Programmazione

Limplementazione deve avere la stessa segnatura presente nellinterfaccia


public int compareTo(Object o) { Shape s = (Shape)o; if (calculateArea() < s.calculateArea()) return -1; else if (calculateArea() > s.calculateArea()) return 1; else return 0; }

IX-B.53

Esercizio
Laboratorio di Programmazione

Modificare Shape in modo che implementi linterfaccia comparable nel modo descritto nella slide precedente Confrontate la soluzione che avete trovate con quella proposta nella slide seguente Provate a testare il metodo compareTo introducendo una classe di test
IX-B.54

Classe astratta: Shape


Laboratorio di Programmazione
public abstract class Shape implements Comparable { public abstract double calculateArea(); public abstract double calculatePerimeter(); public abstract void draw(); abstract introduce un metodo senza corpo contratto stipulato con Comparable public int compareTo(Object o) { Shape s = (Shape)o; il cast serve per accedere ai metodi di Shape non definiti in Object if (calculateArea() < s.calculateArea()) return -1; else if (calculateArea() > s.calculateArea()) return 1; else return 0; } }

IX-B.55

Esercizio
Laboratorio di Programmazione

Scrivere la classe Triangle che estende la classe Shape. La classe descrive i triangoli ed avr come attributi le lunghezza dei tre lati. Il mteodo main deve solamente verificare il corretto funzionamento delle operazioni di cui dotata la classe (ergo, istanziazione ed almeno uninvocazione per ogni metodo implementato o ereditato). SEGUE
IX-B.56

Esercizio
Laboratorio di Programmazione

Suggerimento: per ottenere larea di un triangolo in funzione della misura dei suoi lati, utilizzare la formula di Erone

IX-B.57

Esercizio
Laboratorio di Programmazione

Nota: i pi intraprendenti possono considerare l'idea di derivare dei triangoli RETTANGOLI direttamente da Rectangle. Fate attenzione che in questo caso il triangolo andrebbe rappesentato in termini di base e altezza, quindi i tre lati vanno ricavati da queste informazioni per poter calcolare il perimetro (tenuto conto del teorema di Pitagora).

IX-B.58

Potrebbero piacerti anche