Last Updated on 2 anni | Published: 16/04/2024
Classi Semplici
Le classi sono il fondamento della programmazione ad oggetti OOP (Object Oriented Programming), infatti attraverso queste si possono creare oggetti che automaticamente ereditano attributi (variabili/oggetti) e metodi (azioni) della classe stessa. Quindi una applicazione JavaSE potrebbe essere composta da più classi oltre alla classe Test oppure Home e dal solo metodo main(). Vediamo quindi la struttura di una classe semplice che potrebbe essere aggiunta al nostro progetto:
La classe Generica, che è pubblica per tutte le altre classi del progetto, è nel package sistema (Fig-1-2) ed è ovvio che il progetto stesso include anche una classe di Test con il relativo metodo main(). Passiamo quindi ad esaminare l’ implementazione della classe Generica:
Metodi di tipo Void
Come possiamo notare nella classe Generica essa può contenere più metodi con modificatore di accesso public, in questo caso sono entrambi metodi void che non hanno un tipo, a differenza di altri che sono tipati e restituiscono risultati da essi stessi elaborati.
I void eseguono le istruzioni del blocco quando vengono invocati ed in particolare il metodo salutoPersonale(nome), basa il suo algoritmo su un parametro di tipo stringa che gli verrà passato (nome) il cui valore non interessa durante l’ implementazione in quanto ci si concentra escusivamente sul tipo e nome parametro.
Osserviamo di seguito l’ implementazione della Classe Test e quindi dell’ unico metodo che è il main(), affinchè sia possibile utilizzare i metodi della classe Generica
Attraverso l’ istanza della classe Generica (riga 9 – Test) è possibile utilizzare i metodi della classe stessa (riga 15 e 21), possiamo anche notare la presenza di un import (riga 2 – Test) utilizzato per importare la classe Generica dal suo package di origine, infatti le classi istanziate vengono sempre importate, se non risiedono nello stesso package della classe chiamante.
L’ istanza genera un oggetto (generica), quindi l’ oggetto è la concretizzazione di una classe.
Il metodo void (riga-21 salutoPersonale(nome)) può avere parametri di diverso tipo e numero, anche superiore ad uno. A questo punto possiamo introdurre la firma di un metodo che è composta dal nome, dal numero e tipi di parametri presenti nelle parentesi (String nome, int valore) piuttosto che Integer, boolean e tutti gli altri che andrebbero bene ugualmente.
Quindi si possono implementare metodi di qualsiasi tipo (void oppure tipizzati come vedremo in seguito) con gli stessi nomi ma con parametri nelle parentesi diversi l’ uno dall’ altro in numero e tipo. Osserviamo alcuni esempi di firme
I metodi salutoPersonale() sono metodi che dimostrano anche una implementazione del polimorfismo. Questi ricorrono più volte con lo stesso nome ma elenchi di parametri diversi, quindi si può affermare che si ha un sovraccarico di parametri e quindi un overload. Questo viene inteso come polimorfismo per metodi.
Metodi Tipati e la Keyword return
Un metodo di tipo o più genericamente tipato è riconoscibile innanzitutto perche al posto del void vi è un tipo che può essere primitivo oppure classe. L’ implementazione del metodo tipato vi obbliga ad utilizzare la parola riservata return attraverso la quale il metodo stesso può restituire variabili ed oggetti che altrimenti risulterebbero locali del metodo e non condivisibili con altri metodi del progetto. Vediamo l’ esempio seguente che implementa anche una ulteriore classe
Alla riga 24 viene invocato il metodo somma(n1,n2,n3) che restituisce la somma dei tre parametri alla variabile locale int somma.
Alla riga 25 il metodo println() , invece di assegnare il risultato ad una variabile, stampa su console il valore di ritorno del metodo stesso.
Alla riga 29 l’ array di interi restituito dal metodo dammiArray() viene assegnato ad int[] valori, calcolando successivamente la sua lunghezza per poi stampare il contenuto in console righe 31-34
Quindi i metodi tipati restituiscono variabili primitive oppure oggetti dello stesso tipo dichiarato dal metodo stesso, in definitiva restituirà un boolean se è di tipo boolean, restituirà un intero se è di tipo int e nel nostro caso restituisce un array primitivo di interi. In seguito verranno implementati anche metodi che restituiscono oppure accettano parametri di tipo oggetto.
Riferimento a Variabili vs Oggetti
Come è stato osservato negli articoli precedenti in Java la OOP si basa sulla creazione di oggetti a partire da classi.
Il riferimento a una variabile è un’alias per una posizione specifica nella memoria che contiene un valore. Ad esempio, se si dichiara una variabile int x = 10, allora x è un riferimento alla posizione di memoria che contiene il valore 10.
Il riferimento a un oggetto, d’altra parte, è un riferimento a un’istanza di una classe. Ad esempio, se si dichiara un oggetto MyClass obj = new MyClass(), allora obj è un riferimento all’istanza della classe MyClass.
In altre parole, i riferimenti a variabili puntano a valori specifici, mentre i riferimenti a oggetti puntano a istanze di classi. Questo significa che se si passa un riferimento a un oggetto a un altro metodo, entrambi i metodi stanno lavorando con la stessa istanza della classe e qualsiasi modifica apportata all’oggetto verrà applicata all’istanza originale. In contrasto, se si passa un valore contenuto in una variabile a un metodo, questo metodo sta lavorando con una copia del valore e qualsiasi modifica effettuata sul valore non influirà sulla variabile originale.
Attributi di Classe
La classe quindi è formata da un insieme di metodi che sono azioni e possibili attributi di classe, quest’ ultimi possono essere tipi primitivi, wrapper oppure oggetti. Analizziamo adesso una progetto che oltre alla classe principale possiede anche una classe con metodi ed attributi:
Gli attributi della ClasseA sono variabili stringa ed un oggetto di tipo Scanner (riga 6-7) e possono essere utilizzati da tutti i metodi della classe stessa.
Quindi se prendiamo come riferimento l’ oggetto Scanner (in), siccome occorre utilizzarlo in più metodi si può dichiarare di classe.
Da tener presente invece che tutte le variabili e gli oggetti dichiarati nei metodi sono riconosciute soltanto dal metodo stesso e non dagli altri presenti nella stessa classe, di conseguenza sono variabili locali.
La classe di Test implementa il metodo main() affinchè un oggetto possa utilizzare i metodi ed attributi della ClasseA
Metodo Costruttore di Default
Le classi quindi sono costrutti che implementano attributi e metodi, come ad esempio la ClasseA. Inoltre tutte le classi sono dotate anche di un metodo costruttore di default il cui nome è identico a quello della classe ma senza tipo mentre lo scopo è quello di creare l’ istanza in memoria.
Tale metodo non è visibile ma presente in tutte le classi ed è assegnato di default dal compilatore Java.
Ad ogni modo se il programmatore vuole utilizzare il compilatore di default, anche solo per osservarne il funzionamento, Eclipse offre la possibilità, attraverso i suoi menu, di inserirlo automaticamente:
- Posizionandoci con il mouse all’ interno del blocco della classe cliccare il destro e selezionare il seguente menu
Se come decritto sopra lo scopo del costruttore è creare un ‘istanza in memoria della classe, vediamo cosa accade istanziando la ClasseA se in essa vi è il costruttore di default:
Si ottiene che ad ogni istanza della ClasseA, in console verrà visualizzato il messaggio implementato nel metodo costruttore, quindi il programmatore deciderà se è opportuno programmarlo oppure no.
Nel prossimo articolo verrà spiegato il concetto di modificatore di accesso e del rulo che ricopre nell’ implementazione di classi JavaBean oltre che utilizzare il metodo costruttore con parametri per una creazione immediata di oggetti e ……….
