PDA

View Full Version : Classi Statiche [Java]


luxorl
16-05-2004, 17:07
Raga, ho confusione..
chi mi aiuta bene a capire perchè una classe potrebbe aver bisogno di essere dichiarata statica? e che differenza c'è dalle altre classi?

Grazie :)

cn73
17-05-2004, 10:09
Classi statiche non vuol dire nulla...smmai sono le variabili o i metodi di una classe ad essere statici. In parole semplici ogni istanza di quella classe condividerà la zona di memoria relativa alla variabile o al metodo statico. Solitamente le variabile statiche sono delle costanti (che ovviamente non devono essere diverse per ogni istanza della classe!).
L'utilità di un metodo statico consiste principalmente nel fatto che non devi istanziare un nuovo oggetto della classe, ma usare l'istanza creata dal compilatore al momento della compilazione. Logicamente il metodo non deve essere legato a nessuna istanza di quella classe.

kingv
17-05-2004, 10:17
Originariamente inviato da cn73
Classi statiche non vuol dire nulla...smmai sono le variabili o i metodi di una classe ad essere statici. In parole semplici ogni istanza di quella classe condividerà la zona di memoria relativa alla variabile o al metodo statico. Solitamente le variabile statiche sono delle costanti (che ovviamente non devono essere diverse per ogni istanza della classe!).
L'utilità di un metodo statico consiste principalmente nel fatto che non devi istanziare un nuovo oggetto della classe, ma usare l'istanza creata dal compilatore al momento della compilazione. Logicamente il metodo non deve essere legato a nessuna istanza di quella classe.


ti sbagli, Java permette di definire inner class statiche.

a livello di design non mi vengono in mente degli utilizzi molto frequenti, se non quello di potere scrivere delle classi di test in situazioni particolari perche' le inner class statiche hanno la possibilità di accedere a membri e metodi privati all'interno della "outer" class che le ospita.

in altre occasioni mi sembrano solo una complicaione a livello di design....

cn73
17-05-2004, 10:39
O yes... Hai perfettamente ragione. Sono poco utilizzate ma permesse. Fra l'altro ne ho scritta una proprio la settima scorsa. Come hai detto tu si tratta comunque di InnerClass, non credo che il nostro amico intendesse quelle. Logicamente il concetto è sempre quello: una innerclass statica fornisce dei valori da considerarsi costanti e condivisi: non si necessita di un oggetto della outer-class per creare un oggetto della inner-class. Inoltre non si può accedere ad un oggetto della outer-class da un oggetto della innerclass statica .

PGI
17-05-2004, 16:48
:D Egregi colleghi (di forum), mi sia consentito dissentire da entrambi (cn73 e kingv), sia sul piano tecnico (sono volati degli "inner-outer" e "static inner" da far drizzare i capelli :D) che nel merito.

Trattiamo di strumenti avanzati dell'OOP in Java: probabilmente tra i pochi che rendono Java un linguaggio tremendamente complesso. Sicuramente è uno di quelli che lo rendono favoloso. Poichè l'argomento è lungo, spinoso e malamente trattato (se non del tutto trascurato) dai manuali su Java, vorrei un piccolo "hei sono ancora vivo e interessato" da parte di luxorl prima di salire in cattedra (sperando che la cattedra regga :D).

Ciao.

luxorl
17-05-2004, 16:58
Ei sono ancora vivo e interessato! :)

cmq è vero, ho sbagliato.. nn dovevo scrivere classi, ma metodi!! :)

kingv
17-05-2004, 17:14
Originariamente inviato da luxorl
Ei sono ancora vivo e interessato! :)

cmq è vero, ho sbagliato.. nn dovevo scrivere classi, ma metodi!! :)



ah un errorino da niente.... :D :D

luxorl
17-05-2004, 17:16
:fiufiu: e vabbè daiiii... :p studio java da pochissimo... :)

PGI
17-05-2004, 19:49
Originariamente inviato da luxorl
Ei sono ancora vivo e interessato! :)

cmq è vero, ho sbagliato.. nn dovevo scrivere classi, ma metodi!! :)

ops, ho schiacciato il tasto sbagliato.

cn73
17-05-2004, 20:02
Originariamente inviato da luxorl
Ei sono ancora vivo e interessato! :)

cmq è vero, ho sbagliato.. nn dovevo scrivere classi, ma metodi!! :)


Io l'avevo capito :D
Cmq caro prof PGI :D sono interessato anche io! Purtoppo ho davvero poco tempo per la teoria, ma presto sopperirò a questa mancanza!

PGI
17-05-2004, 21:44
Originariamente inviato da luxorl
Ei sono ancora vivo e interessato! :)

cmq è vero, ho sbagliato.. nn dovevo scrivere classi, ma metodi!! :)

"classi statiche" e "metodi statici" sono cose diverse, come avrai già capito. Io ti parlo di "classi statiche".

Ma prima risolviamo le questioni "terminologiche".

In java non esistono "inner class statiche" o, meglio, non è questo il termine che definisce l'elemento a cui si riferisce kingv (che certamente conosce sostanza e termini, io colgo solo l'occasione per precisare a chi si avvicini per la prima volta a Java che esistono, come in tutti i linguaggi, dei termini "tecnici" che identificano fenomeni precisi. In via colloquiale poi è tutto un altro discorso, conta il succo, ma sapere non fa mai male :D).

"inner class statica" va letto come classe "nested".

In Java non esiste una relazione inner-outer (vale quanto sopra), perchè non esistono classi "outer".

La relazione "inner-outer" va letta come "nested-top level".

Una classe "nested" è una classe dichiarata all'interno del corpo di un'altra classe. Una classe "top level" è una classe che non sia "nested". Una classe "inner" è una classe "nested" (quindi, dichiarata all'interno del corpo di un'altra classe) non "static". Da qui l'impossibilità del termine "inner static".

La relazione che esiste tra una classe nested-inner e la classe nel cui corpo essa è dichiarata è in realtà definita come relazione tra la classe inner e l'istanza della classe entro cui essa è racchiusa. Questo sottolinea un aspetto importante, vale a dire la dipendenza tra un modello, quello della classe inner, ed un oggetto che lo racchiude (anzichè un altro modello).

Al contrario, la relazione "nested-top level" esprime una dipendenza tra modelli.

Direi di fare a questo punto le presentazioni: ecco una classe top-level con una classe "nested":


public class Automobile {

public static class Motore {
}

}


Motore è una classe "nested".

Come ogni strumento, anche le classi nested sono effettivamente un'"inutile complicazione di design" se usate a sproposito. Diventano indispensabili quando usate propriamente. Che siano indispensabili è dimostrato dall'esistenza di una relazione OO che si affronta raramente, a motivo del fatto che essa entra in gioco seriamente solo per modelli di simulazione estesi.

Poichè studi Java, probabilmente hai già affrontato il concetto di ereditarietà, e come l'ereditarietà possa esprimere la relazione tra tipi "è un".

Nel seguente modello di relazione:


public abstract class Mammifero {
}

public class Cane extends Mammifero {
}


il rapporto che esiste tra Mammifero (modello padre) e Cane (modello figlio) è detto appunto "è un" (is-a), poichè, ogni Cane "è un" Mammifero.

Meno noto, dicevamo, il fatto che esista un secondo tipo di relazione nei modelli orientati agli oggetti: "è parte di" (part-of). Si tratta di un concetto molto comune: tutti gli oggetti composti posseggono una serie di relazioni "è parte di". Un po' più ostico è il passaggio dalla relazione tra oggetti alla relazione tra modelli di oggetti.

Prendi ad esempio i seguenti elementi:

Veicolo Motore
|(is-a) |
Automobile <--- (part of)

si nota una relazione "genitore-figlio" tra Veicolo e Automobile ed una relazione di "parte a tutto" tra Motore e Automobile. In un sistema così semplice non è strano definire la relazione di appartenenza usando il solo campo di classe (che però è una relazione tra un modello ed un oggetto racchiuso, l'inverso di inner-encosing instance, e non tra due modelli):


public class Automobile extends Veicolo {
protected Motore;
}


da leggersi come "un'automobile è un veicolo che possiede un motore".

Tutto bene? Si, finche il sistema resta limitato ad un tipo di veicolo.

Quando la simulazione si allarga le cose si complicano:

Veicolo Motore
| |
Automobile Motorino

Sia Automobile che Motorino sono Veicoli e posseggono un Motore. E' evidente però che idealmente i due motori non possano appartenere allo stesso modello.

La soluzione "povera" consiste nel creare una gerarchia di motori:

Motore
| |
MotoreAutomobile MotoreMotorino

La povertà sta nell'incoerenza: creiamo una gerarchia di modelli di motore in funzione dell'appartenenza di questi modelli a classi di veicoli, senza che vi sia alcuna relazione tra il modello di motore e la classe di veicolo.

Ha senso un modello di motore per automobile che non appartenga al concetto di modello di automobile? La logica grida no.


package partiVeicolo;
public class Motore {
}

package veicoli;
public abstract class Veicolo {
}

package veicoli;
public class Automobile extends Veicolo {
public static class Motore extends partiVeicolo.Motore {
}
}

package veicoli;
public class Motorino extends Veicolo {
public static class Motore extends partiVeicolo.Motore {
}
}


Il che ti consente di creare delle automobili che abbiano come parte un motore per automobile, a partire da due modelli funzionalmente collegati.

Quindi, le classi "nested" sono l'espressione forte della relazione "è parte di" tra modelli, che è diversa dalla relazione "è parte di" tra un modello ed un oggetto (che ottieni quando inserisci un campo in una classe) e che è diversa ancora dalla relazione tra una "top-class" ed una sua "inner-class", che è di tipo esclusivamente strumentale (serve al linguaggio ma non al design del modello di simulazione, ma qui è IMHO).

Quanto è importante tutto l'ambaradam? Moltissimo: il succo della programmazione orientata agli oggetti è esprimere un modello in aderenza alla realtà. Questo genera sistemi solidi, facili da estendere, rimpicciolire, mantenere, perchè rispondono ad uno schema in tutto e per tutto simile al modo in cui crei il modello immaginario della realtà che stai simulando.

Ciao.

kingv
18-05-2004, 09:10
PGI -> appena ho un attimo leggo tutto il post che sembra interessante :O

Passy
18-05-2004, 12:05
Originariamente inviato da PGI
"classi statiche" e "metodi statici" sono cose diverse, come avrai già capito. Io ti parlo di "classi statiche"......il modello immaginario della realtà che stai simulando.

Ciao.

Ma quanto ne sai :sbavvv: :ave:
Se ne impara tutti i gironi una nuova

Ciao

anx721
18-05-2004, 20:43
Originariamente inviato da PGI
"classi statiche" e "metodi statici" sono cose diverse, come avrai già capito. Io ti parlo di "classi statiche".

Ma prima risolviamo le questioni "terminologiche"...



Molto interessante ;)

luxorl
21-05-2004, 13:08
Ho un professore all'università per POO! Fantastico!!
e tu me lo hai ricordato tantissimo... si sente la passione per la programmazione ;)

cmq grazie per le dritte! :)

luxorl
21-05-2004, 13:11
L'altro giorno abbiamo studiato proprio l'ereditarietà!

un concetto che mi è sfuggito è quello di casting!

forse perchè ho una gran confusione in testa.. che schifo il nuovo ordinamento!!!!!!

provate a mettermi un po' di ordine nell'encefalo? :P :P

cn73
21-05-2004, 16:13
Aspettando PGI :D provo a chiarirti il concetto. Rientra nel concetto più ampio di polimorfismo. Un oggetto può assumere molte forme. Ad esempio se conosci i Vector, saprai che gli oggetti in esso contenuti sono degli Object (il papà di tutte le classi Java). Ma per utilizzarli, devi sapere cosa effettivamente sono. Ad esempio se sai che sono delle Stringhe, dovrai castizzarle come tali.

String oggetto= (String)myVector.elementAt(0)... ovviamente se l'oggetto non è una stringa, a runtime (ma non in fase di compilazione!!) avrai una ClassCastException.

Un'altro esempio può essere questo: tu hai n classi che implemetano un'interfaccia.

Class1 implements MyInterface
Class2 implements MyInterface
...
Classn implements MyInterface

Ogni istanza di una qualunque delle n classi può essere castizzata come MyInterface. L'utilità?? Pensa a un metodo che prende come parametro un oggetto MyInterface. Tu puoi passargli indifferentemente un qualunque oggetto di una classe che lo implementa(naturalmente class1...classn implementano i metodi definiti VUOTI nell'interfaccia).

O ancora se MyClass1 extends MyClass2 extends MyClass3...

una istanza di MyClass1 può essere castizzata(e usata) come una qualunque istanza delle classi padri.

MyClass1 mioOggetto= new MyClass1(...);Se hai un metodo che necessita di un oggetto MyClass3, puoi passargli
(MyClass3)mioOggetto.

Pensa invece a MyClass1 mioOggetto= new MyClass2(...); è lecito?? E il contrario??

luxorl
22-05-2004, 13:57
Dovrebbe essere lecito, ma nn il contrario...
dal generale al particolare si, dal particolare al generale no!
o sbaglio?

luxorl
22-05-2004, 19:22
Forse rivedendo meglio... è class 3 la padre di tutte!
e quindi sarebbe lecito:

MyClass2 mioOggetto= new MyClass1(...);

e nn viceversa!!

al primo mettiamo il generale, e dopo new il particolare.. giusto?

cn73
22-05-2004, 20:39
Pensa a queste 2 dichiarazioni:

MyClass1 miaclasse = new Object();
Object oggetto = new MyClass1();

;)

luxorl
22-05-2004, 20:42
la prima è errata, mentre la seconda si può fare!! o no?

cn73
24-05-2004, 10:40
Giusto!