Copy Link
Add to Bookmark
Report

Introduzione alla Programmazione Orientata agli Oggetti

DrWatson's profile picture
Published in 
guide hacker
 · 30 May 2019

 

Java nasce alla Sun nel 1991. Inizialmente viene usato per programmare
elettrodomestici per poi inserirsi con facilita' nel web nel 1993.
Particolarita' del java:
- Interpretato (e' quindi indipendente dalla piattaforma)
- Orientato agli oggetti
- Supporta il multithreding
- Gestione automatica della Garbage Collection
- Funzionalita' avanzate per la gestione delle eccezioni.

Detto questo possiamo cominciare con il tutorial.
Innanzitutto bisogna capire come funziona la programmazione orientata agli
oggetti(OOP). Nel linguaggio C, come del resto nel pascal, nel basic, nel
fortran e compagnia, usiamo un approccio funzionale o procedurale nel senso che
il nostro programma veniva eseguito dal suo punto di inizio fino alla sua fine
istruzione dopo istruzione in modo lineare, richiamando, durante l'esecuzione,
qualche funzione o procedura. Nell'approccio OO dobbiamo cambiare il modo di
vedere la struttura del nostro programma, ma soprattutto dobbiamo cambiare il
modo di approccio alla risoluzione del problema. Inizialmente l'OOP risulta di
difficile comprensione per chi ha sempre programmato nel "vecchio stile" ma poi,
una volta capito il meccanismo aumenterete la velocita' di risoluzione dei
problemi e di scrittura del codice, il quale risultera' anche molto piu'
leggibile e facile da aggiornare.

I linguaggi OO si caratterizzano per l'aver introdotto alcuni
concetti di astrazione assai potenti, rispetto a quelli disponibili prima. In
particolare sono stati introdotti i concetti di OGGETTO e di CLASSE che
cercherò di spiegare sotto (i due concetti sono talvolta fra loro confusi, io
mi atterrò al significato che mi sembra più utile alla comprensione).

Una CLASSE, nella terminologia dei linguaggi OO, Ú sostanzialmente la
definizione di una struttura di dati, ovvero di un insieme di variabili fra
loro strettamente collegate, e delle operazioni che su tali dati possono essere
svolte (dette METODI). I metodi corrispondono sostanzialmente ai
sottoprogrammi della terminologia classica. Ogni classe ha un particolare
metodo detto "costruttore" che ha lo scopo di creare un "oggetto" di quella
classe.
Le classi sono racchiuse in PACKAGE.

Un OGGETTO Ú un particolare elemento di una classe che viene creato all'interno
di un programma per essere poi utilizzato mediante i metodi che la classe
definisce. Si dice anche che un oggetto Ú una istanza di una classe.

Faccio un esempio pratico:
Implementiamo una classe di nome Cane

class Cane {
...
}

in questa classe noi possiamo definire degli attributi propri di questa classe,
ad esempio:

class Cane {
boolean coda=true; // il java permette di assegnare un valore al momento della
// dichiarazione.
int altezza;
String nome; //ATTENZIONE! String e' un oggetto non un tipo...
}

e cosi abbiamo definito degli attributi per la classe cane.
Ora definiamo anche dei metodi, cioe' le azioni che puo compiere il cane...

class Cane {
boolean coda = true;
int altezza;
String nome;

public void cammina (int metri) {
System.out.println (nome + " ha camminato per " + metri + "metri.");
}

public void abbaia ( int nvolte) {
for (int i=0; i < nvolte; i++) {
System.out.println ( "bau!");
}
}

//Impostiamo due metodi per settare gli attributi altezza e nome
public void setNome(String nome) { ... }
public void setAltezza(int altezza) { ... }

}
NOTA=Per ora non posso spiegarvi il perche dell'istruzione System.out.println
ma prendetela per buona. Serve per scrivere a video e dare un comando
newLine; System.out.print () stessa cosa ma senza newLine.

quindi ora il nostro cane, o meglio l'idea del nostro cane puo abbaiare e
camminare... ma ora rendiamo reale l'idea di cane che abbiamo andremo quindi a
fare una ISTANZA della CLASSE Cane per creare un OGGETTO:

Cane cane1 = new Cane () ;

con questo comando abbiamo istanziato un oggetto... l'oggetto cane1, il quale
avra' degli attributi: l'altezza, un nome... e potra' compiere delle azioni,
camminare abbaiare...
allora diamo un nome e un' altezza al nostro cane:

cane1.setNome ("Skipper") ;
cane1.setAltezza ( 70 );

ora creiamo un altro cane:

Cane cane2 = new Cane () ;
cane2.setNome ("Pluto") ;
cane2.setAltezza ( 45 ) ;

A questo punto avremo due oggetti instanziati dalla medesima classe. I due
oggetti possono compiere le stesse azioni (Metodi) e hanno gli stessi attributi
ma rimango cmq due oggetti ben distinti, con metodi e variabili allocate in
locazioni di memoria differenti.
All'istruzione:
cane1.cammina (7) ;

sullo schermo vedremo:
Skipper ha camminato per 7 metri.

oppure:

cane2.abbaia (3) ;

sullo schermo...:

bau!
bau!
bau!


***************************Ereditarietà ********************************
Uno dei concetti chiave della programmazione ad oggetti Ú l'ereditarietà : in
sostanza, ogni oggetto può fare da "padre" ad un altro, che erediterà i dati e
le funzioni del genitore. Il grado di parentela teorico tra gli oggetti Ú
pressoché infinito: all'interno di un'applicazione si possono generare "alberi
genealogici"
profondi e ramificati a piacere. Attraverso questa proprietà degli
oggetti, Ú possibile specializzare per affinamenti successivi un determinato
oggetto (modalità "top-down", dal generico al particolare).
Ma vediamo come si applica questo nuovo concetto all'esempio precedente.
Supponiamo di avere un'applicazione che gestisce un database di cani.
Potremo avere alla base della nostra famiglia di oggetti un generico
oggetto Cane, fornito di alcune caratteristiche presenti in ogni
razza, quali numzampe, altezza, colore eccetera, e
alcune azioni "di base", come corri, abbaia, mordi e così via. A
questo punto possiamo cominciare a "specializzare" la nostra gerarchia,
definendo per esempio una sottoclasse CaneDaCaccia, una
CaneDaCompagnia e un'altra CaneDaGuardia. Ognuna di queste classi
erediterà i metodi e i dati definiti nella classe Cane, con
la possibilità di ridefinire alcuni metodi, o aggiungerne di nuovi, della
classe padre.

class Cane { ... }
class CaneDaCaccia extends Cane { ... } // EXTENDS e' la parola chiave per

//l'ereditarieta', estendere appunto
// la nostra classe base.
class Spinone extends CaneDaCaccia { ... }


In Java e' prevista solo l'eredita' singola, ovvero si puo' estendere solamente
una classe, quindi la classe Spinone puo' avere come sopraclasse diretta solo
CaneDaCaccia, non posso quindi scrivere:

class Spinone extends CaneDaCaccia, CaneDaCompagnia { ... }

L'eredita' multipla complica il linguaggio, in quanto bisogna fornire numerose
regole per la risoluzione dei conflitti. Basta dare un'occhiata alle complesse
regole del C++ per l'implementazione dell'ereditarieta' multipla. Tuttavia ci
sono dei problemi che non possono essere risolti senza ereditarieta' multipla,
e piu' in la' vedremo che in java possiamo aggirare questa sua limitazione
mediante le interfacce (INTERFACE) (non c'entrano niente quelle utente)


****************************Overloading*************************
Supponiamo che la classe padre Cane definisca un generico
metodo mordi. Gli oggetti di tipo CaneDaGuardia avranno sicuramente
un metodo mordi differente da quelli di tipo CaneDaCompagnia. La classe
Cane, in una buona organizzazione gerarchica di classi, dovrebbe essere
definita come astratta, nel senso che fornisce un modello alle classi che
ereditano da essa, senza però dare una reale implementazione del codice,
demandata appunto ai figli. Essi dovranno quindi ridefinire (o definire) i
metodi del padre che intenderanno modificare. Questo meccanismo Ú disponibile a
qualsiasi livello della gerarchia. E' da notare che comunque ridefiniamo i
singoli metodi di una classe ereditata, il comportamento "esterno" della classe
sarà in ogni caso lo stesso: ci sarà sempre un metodo mordi, abbaia e
corri, sebbene ogni classe fornisca la propria versione specializzata.

Un'altra forma altrettanto interessante di overloading permette di definire
diversi comportamenti di un singolo metodo all'interno della stessa classe.
Sarà sufficiente definire lo stesso metodo con lo stesso nome ma con una lista
di parametri differente: quando andremo a richiamare un metodo con un
particolare parametro, sarà compito del compilatore andare a vedere quale
metodo utilizzare.
Prendiamo sempre il metodo mordi, sempre nella nostra classe Cane. A seconda
della parte del corpo che si vorrà far mordere al nostro cane, si dovranno
eseguire operazioni differenti: mordere una palla Ú diverso dal mordere una
persona. Attraverso l'overloading, potremo definire due diversi metodi:
(supponendo di aver precedentemente definito due tipi, Persona e palla)

mordi(Palla p) //come parametro da passare a il tipo Palla
mordi(Persona p) //come sopra ma con tipo Persona

A seconda del tipo di parametro che noi gli passiamo verra eseguito il metodo
mordi appropriato.


***************************Incapsulamento***************************
Al programmatore Ú consentito controllare il modo in cui i dati e i metodi di un
oggetto possono essere acceduti dall'esterno. Vi Ú infatti la possibilità di
definire alcuni dei membri di un oggetto (sia dati che funzioni) come
inaccessibili al di fuori di esso ("data hiding" o "information hiding").
Chiameremo questi membri privati. In generale, un metodo o un dato privato sarÃ
accessibile solo all'interno della classe che ne contiene la definizione.
L'incapsulamento lo trattero' piu' in la' con esempi pratici.
-- -- -- -- -- -- -- -- -- --
Per mandare in esecuzione il nostro codice dobbiamo realizzare un metodo Main
all'interno della nostra classe principale, proprio come la funzione void main()
del C:

public class GestioneCanile {
public static void main(String[ ] args) {
/*instanziamo un oggetto cane: */
Cane cane1 = new Cane();
/*richiamiamo un metodo dell'oggetto cane1:
cane1.abbaia();
......
}
}

quando andiamo a salvare il nome del file DEVE essere uguale al nome della
classe (comprese le maiuscole e minuscole), risultera' quindi:
GestioneCanile.java
una volta effettuata la "compilazione" diventera'
GestioneCanile.class
lo stesso vale per la classe Cane.
avremo quindi due file:
GestioneCanile.class
Cane.class
quello da mandare in esecuzione e' quello che contiene il metodo main, con il
comando " java GestioneCanile ".

...un po' di SINTASSI

COMMENTI:
// e /* ... */ come in C

/** ... */ sta ad indicare la documentazione della classe
SELEZIONE
-- if / else --
BNF: <Selezione>::=if(<EsprLogica>) <Istruzione> [else <Istruzione>]
ex:
if ( x > 0 )
System.out.println ( " x e' positivo ");
else
System.out.println ( " x e' negativo ");

per eseguire piu' istruzioni racchiuderle in { .... } come in C...

-- switch --
BNF: <>::= switch ( <Espr> ) {
case <val1> : [ <Sequenza> ] [break;]
case <val2> : [ <Sequenza> ] [break;]
. . .
case <valn> : [ <Sequenza> ] [break;]
[ default : [ <Sequenza> ] [break;] ]
}
ex:
switch (c) {
case 'a' :
System.out.println("vocale");
break; // per uscire dallo switch
case 'b' :
System.out.println("consonante");
break;
}
invece di scrivere tutto l'alfabeto possiamo scrivere:
ex:
switch (c) {
case 'a': // non essendoci ne' l'istruzione ne' il
case 'e': // break i casi delle vocali sono trattati
case 'i': // tutti allo stesso modo.
case 'o':
case 'u':
System.out.println("vocale");
break;
default: System.out.println("consonante");
break;
}

ITERAZIONE
-- while --
BNF: <>::= while ( <EsprLogica> ) <Istruzione>
ex:
while (i <= 10 ) {
System.out.println(i);
i=i+1; // posso abbreviare con i++
}

-- do / while --
BNF <>::= do <Istruzione> while ( <EsprLogica>)
ex:
do {
c=System.in.read();
} while ((c != 'n') && (c != 's'));

nota: per una migliore leggibilita' usare sempre le parentesi graffe
per racchiudere il corpo del ciclo del do in modo da
distinguerlo dal while.

-- for --
BNF <>::= for (<Istruzione>; <EsprLogica>; <Istruzione>) <Istruzione>
ex:
for ( i=1; i <=10; i++)
System.out.println(i);

ALTRE ISTRUZIONI
-- break --
Causa l'immediata uscita dall'istruzione corrente (vedi switch)

-- continue --
Causa l'immediata uscita dall'iterazione corrispondente, ma non dal ciclo, che
riprende dall'iterazione succesiva.
ex:
for ( i = 1; i <= 10; i++ ) {
if ( i==5 )
continue;
System.out.println(i);
}
System.out.println ( " Fuori dal ciclo " );

questo codice stampa i numeri da 1 a 4 e da 6 a 10 e il messaggio "fuori dal
ciclo"
.

TIPI
I tipi che abbiamo a disposizione in java sono
boolean 1 bit
char 16 bit (Standard Unicode2.0)
byte 8 bit
short 16 bit
int 32 bit
long 64 bit
float 32 bit
double 64 bit

COSTANTI
Per definire costanti in java usiamo il modificatore FINAL
ex:
final string MESSAGGIO = " ciao! ";

ARRAY
definizione di array:
int [ ] a;
La variabile a e' dichiarata come un array di interi
Poi con la seguente istruzione creo, alloco in memoria, un oggetto a composto
da 20 interi:
a = new int [ 20 ];
Posso sintetizzare il tutto in un'unica istruzione:
int a [ ] = new int [ 20 ];
Come in tutti gli altri linguaggi di programmazione gli indici degli array
partono da 0, quindi scrivendo a [ 2 ] accedero' al terzo elemento contenuto
nell'array.

^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Come editor io uso jgrasp della Auburn Engineering, e' free e open e supporta il
java, C / C++, Ada2, VHDL.
Colora il codice, indenta automaticamente ed inoltre cosa che reputo molto utile
genera il CSD affianco al codice (e' una specie di diagramma a blocchi).
Funziona su qualsiasi sistema.

Per compilare i programmi dovete scaricarvi il JDK dal sito della sun.
Al suo interno trovate ampia documentazione riguardo all'installazione e
configurazione sui diversi sistemi (E' cmq facilissima, basta settare un Path)

I programmi scritti in java per girare necessitano del JavaRuntimeEnviroment
(JRE) che fa da intermediario tra la macchina ed il bytecode del vostro
programma (la cosiddetta macchina virtuale java JVM, soluzione adottata anche
dalla MS per C#, molto piu' simile al java di quanto non lo sia il java al C++).
Ecco perche i programmi scritti in java girano su qualsiasi sistema. In pratica
voi scrivete il codice e lo salvate: ciccio.java
poi lo compilate:
ciccio.class
ed avete cosi ottenuto il bytecode di ciccio.java, il ciccio.class che NON e' un
eseguibile, questo bytecode deve essere interpretato dalla macchina virtuale
java per poter essere trasformato in codice macchina e renderlo cosi
comprensibile al sistema. Cio' lo fate con il comando java ciccio.class...

e questo e' tutto per ora...

← previous
next →
loading
sending ...
New to Neperos ? Sign Up for free
download Neperos App from Google Play
install Neperos as PWA

Let's discover also

Recent Articles

Recent Comments

Neperos cookies
This website uses cookies to store your preferences and improve the service. Cookies authorization will allow me and / or my partners to process personal data such as browsing behaviour.

By pressing OK you agree to the Terms of Service and acknowledge the Privacy Policy

By pressing REJECT you will be able to continue to use Neperos (like read articles or write comments) but some important cookies will not be set. This may affect certain features and functions of the platform.
OK
REJECT