La presentazione è in caricamento. Aspetta per favore

La presentazione è in caricamento. Aspetta per favore

Package Pacchetti e ereditarietà 29/12/2018 package.

Presentazioni simili


Presentazione sul tema: "Package Pacchetti e ereditarietà 29/12/2018 package."— Transcript della presentazione:

1 Package Pacchetti e ereditarietà 29/12/2018 package

2 Organizzazione di programmi
Un programma Java è costituito da una raccolta di classi. Ogni classe pubblica deve essere definita in un file sorgente il cui nome è dato dal nome della classe e la cui estensione è .java Esempio: public class Rectangle{ } Il sorgente deve avere il nome Rectangle.java E’ possibile inserire in un unico sorgente più classi, purché solo una sia public. Il nome del file dovrà corrispondere alla classe public. 29/12/2018 package

3 Istruzione package Programmi di grosse dimensioni vengono normalmente strutturati in pacchetti. Un pacchetto (package) è un insieme di classi correlate. Per creare un pacchetto, bisogna inserire nel pacchetto almeno una classe o un’interfaccia. L’istruzione package, inserita come prima istruzione nel file sorgente, consente di specificare il pacchetto a cui una classe/interfaccia appartiene. Ogni classe di cui non viene specificato il pacchetto di appartenenza viene messa in un pacchetto di default che è un pacchetto anonimo. I pacchetti anonimi dovrebbero essere utilizzati solo per applicazioni piccole o temporanee. 29/12/2018 package

4 Istruzione package Esempio: voglio inserire le classi Rectangle e Circle in un pacchetto denominato graphics. Rectangle.java package graphics; public class Rectangle{ } Circle.java public class Circle{ graphics Il nome completo delle due classi è: graphics.Rectangle graphics.Circle Molti ambienti Java mappano i nomi dei package sui pathname del file system. Il nome dei file è: graphics\Rectangle.java graphics\Circle.java 29/12/2018 package

5 Nomi di pacchetti e directory
Per creare un pacchetto, i file sorgenti delle classi appartenenti al pacchetto vanno messi in una directory il cui nome coincide con quello del pacchetto. Il nome delle directory e quello del pacchetto sono separati da . package graphics; public class Rectangle{ } package graphics; public class Circle{ } graphics Rectangle.java Circle.java 29/12/2018 package

6 Nomi di pacchetti e directory
aaa package aaa.bbb.graphics; public class Rectangle{ } bbb graphics Rectangle.java Il nome completo della classe è aaa.bbb.graphics.Rectangle Il nome del file è aaa\bbb\graphics\Rectangle.java 29/12/2018 package

7 Convenzioni per i nomi di pacchetti e di classi
La convenzione di chiamare ogni classe con il nome completo del package consente l’uso di classi con lo stesso nome purché appartengano a package diversi. Questo evita il problema di classi omonime, purché i package abbiano nomi diversi. Per convenzione, i produttori di software usano dare ai propri package nomi che derivano dai loro domini internet (che per definizione sono univoci). Il nome del package inizia con il nome del dominio invertito e con il nome di più alto livello tutto maiuscolo: dominio: vision.unipv.it package: utilities.internet nome completo del package: IT.unipv.vision.utilities.internet directory: IT\unipv\vision\utilities\internet 29/12/2018 package

8 Usare i package Solo i membri public di un package possono essere accessibili dall’esterno del package nel quale sono definiti. Per riferirsi ad una classe appartenente ad un package è possibile: riferirsi ad essa con il nome completo; importare la classe; importare l’intero package. Esempio: aaa.bbb.graphics.Rectangle r = new aaa.bbb.graphics.Rectangle(); import aaa.bbb.graphics.Rectangle; import aaa.bbb.graphics.*; Note: java.lang.* è sempre importato implicitamente Non è necessario fare uso del nome completo del package quando il nome di una classe viene usato all’interno dello stesso package. 29/12/2018 package

9 Pacchetti standard java.lang classi base del linguaggio java.io
Object, Thread, Throwable, System, String, Math, wrapper classes, …) java.io classi di I/O FileInputStream, FileOutputStream java.util classi di utilità Date, Random, … java.net classi di supporto alle applicazioni di rete (socket, URL, …) java.applet classe Applet, … java.awt Abstract Windowing Toolkit 29/12/2018 package

10 CLASSPATH Per indicare al class loader da quale directory partire per la mappatura può essere usata la variabile di ambiente CLASSPATH Definizione: CLASSPATH definisce una lista ordinata di directory o file ZIP nei quali cercare le classi. Esempio (Unix): setenv CLASSPATH /classi : /usr/MyApp/classi : . 29/12/2018 package

11 Visibilità Classi e interfacce
sono visibili all’interno del package in cui sono dichiarate; sono visibili all’esterno del package solo se dichiarate public: public class a { … public interface b { … Membri (campi e metodi) sono visibili quando: la loro classe è visibile e il loro modificatore li rende visibili 29/12/2018 package

12 Visibilità di campi e metodi
Modificatore Visibilità private solo nella classe in cui è definito nessuno (default) solo nelle classi del package protected classi nel package e sottoclassi public tutte le classi più visibile NB: I membri di una interfaccia sono sempre pubblici 29/12/2018 package

13 esempio package pac class a {... class b { package pac; private int i;
private void m( ) {…} int j; void n( ) {…} public int k; public p( ){…} protected int i; protected void m( ){…} package pac; class c {... visibile class e extends d {... class d extends b {... class d extends b {... 29/12/2018 package

14 Progettare la Visibilità
Quando progettiamo una classe dobbiamo pensare a due tipi di utenti: quelli che utilizzeranno la classe per realizzare delle applicazioni quelli che estenderanno la classe per realizzare sottoclassi I primi useranno i membri public; i secondi anche i membri protected Le interfacce public e protected vanno progettate con cura 29/12/2018 package

15 DUE TIPI DI UTENTI ESTENDE USA class a { private int i;
private void m( ) {…} int j; void n( ) {…} public int k; public p( ){…} protected int i; protected void m( ){…} ESTENDE USA package pac interfaccia interfaccia 29/12/2018 package

16 Package: riassunto I package:
permettono di creare gruppi di classi e interfacce fra loro in relazione definiscono uno spazio di nomi locale per classi e interfacce evitando conflitti con classi e interfacce di altri package permettono di avere classi, interfacce e membri (campi e metodi) non visibili all’esterno del package possono essere organizzati gerarchicamente 29/12/2018 package

17 Ereditarietà in Java Una delle caratteristiche distintive del paradigma di programmazione orientato agli oggetti è l’ereditarietà: l’ereditarietà permette di definire nuove classi mediante l’aggiunta e/o la specializzazione di funzionalità ad altre classi, già esistenti oppure appositamente progettate e definite Sono tre i meccanismi di ereditarietà forniti dal linguaggio Java: estensione di classi classi astratte interfacce 29/12/2018 package

18 Ereditarietà L’estensione (o derivazione) di classi è il meccanismo che permette di definire una classe (per istanziare oggetti) a partire da un’altra classe mediante l’aggiunta e/o la specializzazione di funzionalità (operazioni) In Java l’ereditarietà fra classi è singola. La classe “di partenza” è chiamata classe base oppure superclasse La classe che viene definita è chiamata classe estesa o derivata oppure sotto-classe Tutte le operazioni definite dalla classe base sono implicitamente definite anche nella classe estesa la classe estesa può definire nuove operazioni per i propri oggetti la classe estesa può ri-definire operazioni già definite nella classe base Ogni istanza della classe estesa può essere considerata anche una istanza della classe base. 29/12/2018 package

19 Esempio: classe Persona
Si consideri ad esempio la seguente classe Persona (che sarà usata come classe base nella derivazione di un’altra classe) Un oggetto Persona rappresenta una persona l’unica proprietà di una Persona è il suo nome nome è una variabile d’istanza (privata) /** Un oggetto Persona rappresenta una persona. */ class Persona { /** Il nome di questa Persona. */ private String nome; /** Crea una nuova Persona, dato il nome. */ public Persona(String nome) { this.nome = nome; } /** Restituisce il nome di questa Persona. */ public String getNome() { return nome; /** Restituisce una descrizione di questa Persona. */ public String toString() { return "Mi chiamo " + getNome() + "."; 29/12/2018 package

20 Classe Studente Si supponga ora di voler definire la seguente classe Studente un oggetto Studente rappresenta uno studente universitario le proprietà di uno Studente sono il suo nome e il nome dell’università in cui studia è possibile costruire un nuovo Studente che ha un certo nome e studia in una certa università la classe Studente ha un costruttore parametrico rispetto al nome e all’università Si osservi come la classe Studente estenda e specializzi il comportamento della classe Persona la classe Studente serve a modellare degli oggetti che sono “casi particolari” della classe Persona un oggetto Studente sa eseguire tutte le operazioni degli oggetti Persona un oggetto Studente sa eseguire anche delle ulteriori operazioni, che gli oggetti Persona (normalmente) non sanno eseguire È possibile definire la classe Studente come estensione della classe Persona l’estensione di classi riduce il tempo di realizzazione, riutilizzando implicitamente il codice già scritto 29/12/2018 package

21 Classe Studente /** Un oggetto Studente rappresenta uno studente. */
class Studente extends Persona { /** L'università in cui studia questo Studente. */ private String università; /** Crea un nuovo Studente, dati nome e università. */ public Studente(String nome, String università) { super(nome); this.università = università; } /** Restituisce l'università di questo Studente. */ public String getUniversità() { return università; /** Restituisce una descrizione di questo Studente. */ public String toString() { return "Mi chiamo " + getNome() + ". " + "Studio a " + università + "."; 29/12/2018 package

22 Uso delle classi Persona e Studente
Persona mario = new Persona("Mario"); Studente paola = new Studente("Paola", “Pavia"); System.out.println(mario.getNome()); // Mario System.out.println(mario.toString()); // Mi chiamo Mario. System.out.println(paola.getNome()); // Paola System.out.println(paola.getUniversità()); // Pavia System.out.println(paola.toString()); // Mi chiamo Paola. Studio a Pavia. Si noti che l’oggetto Studente sa eseguire l’operazione getNome() anche se questa operazione non è definita esplicitamente nella classe. 29/12/2018 package

23 Estensione delle classi
L’intestazione della classe estesa è class ClasseEstesa extends ClasseBase Metodi la classe estesa può definire dei nuovi metodi rispetto a quelli definiti nella classe base — ad esempio, getUniversità() la classe estesa definisce implicitamente tutti i metodi (pubblici) definiti nella classe base la classe estesa può ri-definire i metodi della classe base se ne vuole modificare la definizione (overriding o sovrascrittura) — ad esempio, toString() se la classe estesa non ri-definisce un metodo della classe base, allora vuol dire che ne conferma implicitamente la definizione — ad esempio, getNome() 29/12/2018 package

24 Ereditarietà Variabili
la classe estesa possiede implicitamente tutte le variabili della classe base le variabili dichiarate nella classe base contribuiscono allo stato degli oggetti della classe estesa la dichiarazione delle variabili d’istanza della classe base non deve essere ripetuta nella classe estesa la classe estesa può accedere alle variabili pubbliche della classe base, ma non può accedere alle sue variabili private Costruttori i costruttori della classe estesa devono: invocare (come prima istruzione del costruttore) un costruttore della classe base (usando la parola chiave super) per inizializzare le variabili dichiarate nella classe base inizializzare le variabili dichiarate nella classe estesa 29/12/2018 package

25 Polimorfismo L’aspetto fondamentale dell’estensione di classi (e dell’ereditarietà in generale) è il polimorfismo: per polimorfismo si intende la possibilità di assegnare il riferimento a un oggetto della classe estesa a una variabile il cui tipo è la classe base a tale oggetto è possibile richiedere solo il comportamento dichiarato dalla classe base tuttavia, il comportamento dell’oggetto viene scelto sulla base del tipo effettivo dell’oggetto (late binding), e non sul tipo della variabile. Ad esempio: Persona paola = new Studente("Paola", “Pavia"); System.out.println(paola.toString()); // Mi chiamo Paola. Studio a Pavia. // e non: Mi chiamo Paola. System.out.println(paola.getUniversità()); // NO, ERRORE (IN COMPILAZIONE)! Nella classe base il metodo // getUniversità() non è definito 29/12/2018 package

26 Polimorfismo e parametri
Similmente, nell’invocazione di un metodo che ha un parametro formale del tipo della classe base, è possibile usare come parametro attuale il riferimento a una istanza della classe estesa Esempio: definizione del metodo public static void stampa(Persona p) { System.out.println(p.toString()); } invocazione del metodo stampa( new Studente("Marco", “Pavia") ); // Mi chiamo Marco. Studio a Pavia. 29/12/2018 package

27 L’operatore instanceof
È possibile verificare se un oggetto è istanza di una certa classe (base e/o estesa) usando l’operatore relazionale instanceof (restituisce un valore boolean) il primo operando di instanceof è il riferimento a un oggetto il secondo operando di instanceof è il nome di una classe instanceof verifica se l’oggetto è istanza della classe (o di una sua sotto-classe) Ad esempio Persona mario = new Persona("Mario"); Studente paola = new Studente("Paola", "Roma Tre"); System.out.println(mario instanceof Persona); // true System.out.println(mario instanceof Studente); // false System.out.println(paola instanceof Persona); // true System.out.println(paola instanceof Studente); // true 29/12/2018 package

28 Polimorfismo Si consideri nuovamente il caso di una variabile del tipo della classe base che memorizza il riferimento a un oggetto: se si è sicuri che la variabile memorizza il riferimento a un oggetto istanza della classe estesa, allora è possibile effettuare una conversione esplicita (cast) del riferimento, per ottenere un riferimento del tipo della classe estesa la conversione permette di utilizzare il comportamento specifico della classe estesa la conversione esplicita genera una eccezione se l’oggetto referenziato non ha il tipo della classe a cui si converte Ad esempio Persona johnP; // john come Persona Studente johnS; // john come Studente johnP = new Studente("John", "Stanford"); johnS = (Studente) johnP; // ok System.out.println(johnS.getUniversità()); // ok 29/12/2018 package

29 Classi astratte Una classe astratta è una classe implementata in modo parziale una classe astratta è una classe che contiene la dichiarazione di alcuni metodi (metodi astratti), di cui viene specificata l’intestazione (o firma), ma non il corpo una classe astratta non può essere istanziata, appunto perché definita in modo incompleto le classi astratte sono progettate per essere estese da classi che forniscono delle opportune implementazioni per i metodi astratti Le classi astratte sono utili nella definizione di una gerarchia di classi, in cui la super-classe (astratta) viene definita con i seguenti scopi definire il comportamento comune per tutte le classi della gerarchia dichiarare (senza implementare) le funzionalità che devono essere implementate da tutte le classi che la estendono 29/12/2018 package

30 Classi astratte: esempio
Si vogliono definire delle classi i cui oggetti rappresentano delle forme geometriche ad esempio, le classi Quadrato e Cerchio per rappresentare rispettivamente quadrati e cerchi Le caratteristiche delle forme geometriche sono le seguenti i quadrati sono caratterizzati da un lato e da un colore i cerchi sono caratterizzati da un raggio e da un colore i quadrati devono saper calcolare il proprio lato, il proprio colore e la propria area i cerchi devono saper calcolare il proprio raggio, il proprio colore e la propria area Viene definita la classe (astratta) Forma che dichiara e/o definisce le caratteristiche comuni delle classi Quadrato e Cerchio il colore, il metodo per il calcolo del colore, il metodo per il calcolo dell’area 29/12/2018 package

31 La classe astratta Forma
/** Una forma geometrica. */ abstract class Forma { /** Il colore di questa Forma. */ protected String colore; /** Crea una nuova Forma di un certo colore. */ public Forma(String colore) { this.colore = colore; } /** Restituisce il colore di questa Forma. */ public String colore() { return colore; /** Restituisce l'area di questa Forma. */ public abstract double area(); /* ogni forma deve saper calcolare la propria area */ 29/12/2018 package

32 La classe Quadrato /** La forma geometrica quadrato. */
class Quadrato extends Forma { /** Il lato di questo Quadrato. */ protected double lato; /** Crea una nuovo Quadrato. */ public Quadrato(double lato, String colore) { super(colore); this.lato = lato; } /** Restituisce il lato di questo Quadrato. */ public double lato() { return lato; /** Restituisce l'area di questo Quadrato. */ /* implementazione del metodo astratto double area() */ public double area() { return lato*lato; 29/12/2018 package

33 Uso di forme geometriche
Quadrato q; // un quadrato Forma fq; // un altro quadrato q = new Quadrato(5, "bianco"); // lato 5 e colore bianco fq = new Quadrato(10, "rosso"); // lato 10 e colore rosso System.out.println(q.area()); // 25.0 System.out.println(q.colore()); // bianco System.out.println(q.lato()); // 5.0 System.out.println(fq.area()); // 100.0 System.out.println(fq.colore()); // rosso System.out.println(fq.lato()); // NO, errore di compilazione! 29/12/2018 package

34 Classi astratte e polimorfismo
Caratteristiche dell’esempio mostrato la classe Forma è stata dichiarata abstract perché contiene la dichiarazione del metodo astratto area() la classe astratta Forma non può essere istanziata direttamente le classi Quadrato e Cerchio sono concrete perché estendono la classe Forma e ne implementano tutti i metodi astratti le classi Quadrato e Cerchio possono essere istanziate Una variabile di tipo Forma può memorizzare il riferimento a una forma (un quadrato o un cerchio) può essere usata per invocare un metodo definito da Forma, ad esempio, colore() può essere usata per invocare un metodo astratto dichiarato da Forma , ad esempio, area() 29/12/2018 package

35 Interfacce In Java, una interfaccia (interface) è una unità di programmazione che consiste nella dichiarazione di un certo numero di metodi d’istanza e pubblici, che sono implicitamente astratti. Esempio: public interface MiaInterfaccia { int UNA_COSTANTE_INTERA = 100; String UNA_COSTANTE_STRINGA = "ciao"; void metodo1(int a); char metodo2(String s, long l); } i metodi definiti (dichiarati) in una interfaccia sono implicitamente astratti (non essendone fornita l’implementazione) e pubblici non sono ammessi metodi dichiarati come static gli “attributi” di un’interfaccia, invece, sono implicitamente static, final e pubblici il < modificatore di visibilita>, se specificato, deve valere public; se non specificato, è implicitamente package 29/12/2018 package

36 Interfacce In prima approssimazione, una interfaccia è simile a una classe astratta che dichiara solo metodi astratti, senza fornire alcuna implementazione come la definizione di una classe, la dichiarazione di una interfaccia definisce un nuovo tipo riferimento, che può essere usato nella dichiarazione di variabili e di parametri formali Una classe implementa una interfaccia se implementa (definisce) tutti i metodi d’istanza dichiarati dall’interfaccia public interface Comparable{ public int compareTo(Object obj); } public class myClass implements Comparable { public int compareTo(Object obj) { 29/12/2018 package

37 Ereditarietà multipla
Una classe può implementare più di una interfaccia interface Driveable { interface Rentable { void startEngine(); void startRental(); void stopEngine(); void endRental(); float accelerate(float acc); int book(Date start, Date end); boolean turn(Direction dir); } } class AvisCar implements Driveable, Rentable { void startEngine() { … } void startRental() { … } 29/12/2018 package

38 Interfacce Un’interfaccia rappresenta un contratto:
la classe che si impegna ad implementarla si impegna a mettere a disposizione certe funzionalità (i metodi dichiarati nell’interfaccia) Una classe può implementare più di una interfaccia. Le interfacce possono ereditare da altre interfacce, anche da più di una contemporaneamente (eredità multipla) Le interfacce non servono solo per “simulare” l’ereditarietà multipla: definiscono un contratto in forma puramente astratta 29/12/2018 package

39 Esempio - l’interfaccia Comparable
La seguente interfaccia Comparable (definita nel package java.lang) definisce un tipo per oggetti “confrontabili”, ovvero oggetti su cui è definito un ordinamento parziale, a cui è possibile chiedere di confrontarsi con altri oggetti dello stesso tipo: public interface Comparable { /** Confronta questo oggetto con obj per determinare * in che relazione d'ordine sono. * Restituisce: * - zero, se questo oggetto e obj sono uguali * - un valore negativo, se questo oggetto è minore di obj * - un valore positivo, se questo oggetto è maggiore di obj. */ public int compareTo(Object obj); } ad esempio, le classi String e Integer implementano questa interfaccia 29/12/2018 package

40 Ordinamento di un array di oggetti confrontabili
public static void sort(Comparable[] dati) { if (dati[i].compareTo(dati[i-1])<0) { } Grazie al polimorfismo, questo metodo può essere utilizzato per ordinare, ad esempio, sia un array di stringhe che un array di oggetti Integer. 29/12/2018 package

41 Ma sono veramente necessarie le interfacce?
Non si potrebbero usare le classi astratte al loro posto ? In realtà, le interfacce sono molto diverse dalle classi astratte: ·     le interfacce ci forniscono una forma di ereditarietà multipla ·     le classi astratte possono (se “lo vogliono”) implementare loro metodi e fissare livelli di accesso sui loro membri, mentre le interfacce possono solo dichiarare costanti pubbliche e metodi pubblici (senza mai fornirne l’implementazione) In genere, se non c’è necessità di eredità multipla si preferisce usare le classi astratte ... possono implementare dei metodi, i quali, essendo ereditati dalle sottoclassi, non devono essere riscritti In genere, comunque, una classe che si prevede sarà utilizzata da molte altre classi dovrebbe essere l’implementazione di una interfaccia ... per il “solito” motivo: una classe può ereditare da una sola classe alla volta ... 29/12/2018 package


Scaricare ppt "Package Pacchetti e ereditarietà 29/12/2018 package."

Presentazioni simili


Annunci Google