Newsgroup: it.comp.java
Titolo: Java e i costruttori

Ciao,
aiutatemi un attimo a capire meglio il concetto di costruttore...o 
meglio la differenza fra il costruttore e il comando new, perche' nella 
mia testa si confondono un po'.
Vi spiego come l'ho capita io, poi mi direte se vi va dove (e se) sbaglio.
Il metodo costruttore in java deve esserci; può essere definito dal 
programmatore, e deve essere per forza public, non restituire nessun 
valore e avere il nome uguale a quello della classe cui si riferisce, ma 
se il programmatore non lo definisce java ne creerà uno di default, 
perche' in java qualsiasi oggetto o variabile deve essere sempre 
inizializzata. Il costruttore si occupa infatti di inizializzare un 
oggetto a un determinato valore, se si lascia fare a java il costruttore 
di default inizializzerà l'oggetto a un valore nullo, ad esempio se 
l'oggetto è composto da interi il costruttore di default lo 
inizializzerà con 0, in linea generale al valore di default previsto per 
quel tipo di oggetto.
Il comando new invece 'crea fisicamente' l'oggetto, allocando l'area di 
memoria necessaria a contenere le informazioni sull'oggetto (che vanno 
nell'heap) e il riferimento all'oggetto (che va nello stack delle 
attivazioni).
Mettiamo di schematizzare la faccenda:
1- La classe definisce le proprietà e le caratteristiche degli oggetti
2- Il costruttore li inizializza
3- new riserva la memoria necessaria a contenerli
 
Se il costruttore si omette, l'oggetto non avrà alcun valore ma a quel 
punto è ancora possibile crearlo con new? Si andrebbe quindi ad 
impegnare un'area di memoria che conterrà solo il riferimento e nient'altro?
 
Grazie...
 
 
 

Dimenticavo. Prendendo ad esame questo frammento di codice:
 
public class ProdottoPerSomma
{
	private int moltiplicando;
	private int moltiplicatore;
	private int risultato;
 
public ProdottoPerSomma(int moltiplicando, int moltiplicatore)
{
      this.moltiplicando = moltiplicando;
      this.moltiplicatore = moltiplicatore;
      risultato = 0;
}
 
 
Perche' a risultato non e' stato anteposto il this?
 

 Grazie...
 
Sta' programmazione proprio non te vuole andare giu' eh? :))
 
Resetto tutto quello che hai detto perche' vedo solo confusione e
riassumo solo i concetti:
 
1) java e' un linguaggio ad oggetti
2) gli oggetti/le classi cosa sono? sono un modo di raggruppare le 
variabili e le funzioni (ce n'e' bisogno perche' un fenomeno e' 
rappresentato spesso da piu' variabili, non da 1 sola)
3) descrivi una classe scrivendo class { ... }
4) una volta che hai descritto la tua classe vorrai anche usarla no?
5) allora la usi facendo "MiaClasse mc = new MiaClasse()", ovviamente 
solo quando la usi occupa memoria
6) se non descrivi il costruttore, le varie variabili della classe 
saranno inizializzate a valori di default, prendo uno degli nMila esempi 
su internet:
 
class ClassInitializationDemo1
{
    static boolean b;
    static byte by;
    static char c;
    static double d;
    static float f;
    static int i;
    static long l;
    static short s;
    static String st;
    public static void main (String [] args)
    {
       System.out.println ("b = " + b);
       System.out.println ("by = " + by);
       System.out.println ("c = " + c);
       System.out.println ("d = " + d);
       System.out.println ("f = " + f);
       System.out.println ("i = " + i);
       System.out.println ("l = " + l);
       System.out.println ("s = " + s);
       System.out.println ("st = " + st);
    }
}
 
7) cosa ancora non e' chiaro?
 
Ciao.

 Perche' a risultato non e' stato anteposto il this?
 
Pero' tu il libro su java mica lo hai comperato... :))
Ho preso in mano ora un libro di Java del 2001 e nell'indice analitico 
"this" c'e'.
 
Allora, "this" e' una variabile che punta all'oggetto stesso in cui e' 
dichiarata. Quindi this.moltiplicando vuol dire il campo "moltiplicando" 
della classe in cui mi trovo.
 
E' un classico usarla nei costruttori quando i parametri del costruttore
hanno gli stessi nomi dei membri della classe => sei obbligata a scrivere:
this.moltiplicando = moltiplicando
per togliere l'ambiguita' tra "moltiplicando" campo e "moltiplicando" 
parametro.
 
Con "risultato" questa ambiguita' non c'e' e quindi non c'e' bisogno di 
metterlo. Ma se lo mettessi non ti darebbe errore, sarebbe solo inutile.
 
Ciao.

 7) cosa ancora non e' chiaro?
 
un botto di cose :-)))

 (static ancora non l'ho capito benissimo)
 
Qui sono stato impreciso io, volevo dire che se una variabile non la 
inizializzi (nel costrutture o altrove) avra' un valore di default.
L'esempio postato ti mostrera' i valori di default.
 
Riguardo alla parola static, dovrei cambiare argomento. Facciamo cosi' 
rifaccio per adesso l'esempio:
 
============================================
class ClassInitializationDemo1
{
    boolean b;
    byte by;
    char c;
    double d;
    float f;
    int i;
    long l;
    short s;
    String st;
 
    public void testValori() {
       System.out.println ("b = " + b);
       System.out.println ("by = " + by);
       System.out.println ("c = " + c);
       System.out.println ("d = " + d);
       System.out.println ("f = " + f);
       System.out.println ("i = " + i);
       System.out.println ("l = " + l);
       System.out.println ("s = " + s);
       System.out.println ("st = " + st);
    }
 
    public static void main (String [] args) {
        ClassInitializationDemo1 cid = new ClassInitializationDemo1();
        cid.testValori();
    }
}
============================================
 
Riguardo allo static del vecchio esempio puoi leggere qui:
http://docs.oracle.com/javase/tutorial/java/javaOO/classvars.html
 
 
Ciao!
 
 
 
 
 
 

Se il costruttore si omette, l
 
 
hai detto tu stessa che esiste il costruttore di default
 
il costruttore di default devi scriverlo tu di tuo pugno
se e solo se hai scritto altri costruttori (e ti serve cmq il
costruttore di default)
 
ciao, Jasmine

 nient'altro?
No, forse con un esempio si puo' far chiarezza.
public class Paese {
   long abitanti;
   double superficie;
   public long getAbitanti() {
     return abitanti;
   }
   public double getSuperficie() {
     return superficie;
   }
   public void setAbitanti(long abitanti) {
     this.abitanti = abitanti;
   }
   public void setSuperficie(double superficie) {
     this.superficie = superficie;
   }
}
 
in questa classe (un classico bean di dati) non e' stato definito un 
costruttore, quindi implicitamente la classe eredita il costruttore 
senza argomenti definito da Object. Applicando l'operatore new si 
ottiene un'istanza della classse i cui membri verranno inizializzati al 
loro valore di default. Lo statement:
 
Paese paese = new Paese();
 
e' perfettamente lecito, utilizza il costruttore di default, ovvero il 
costruttore implicito derivato da Object. I valori dei suoi membri, 
inizializzati a 0L e 0.0D rispettivamente, saranno governati dai metodi 
setter e getter. Quindi:
 
paese.getAbitanti();
 
restituisce 0L, e se paese fosse stato null, questo statement sarebbe 
risultato nell'eccezione NullPointerException a runtime.
 
 

 punto è ancora possibile crearlo con new? 
 
scusa ma l'hai scritto prima: se il programmatore omette il costruttore 
c'è sempre implicito il costruttore di default, pubblico e senza 
argomenti.
 
comunque per essere esaustivi sui costruttori e sul processo di 
inizializzazione degli oggetti ci sarebbe veramente tanto altro da 
aggiungere. però sarebbe meglio per te evitare di acquisire nozioni in 
modo raffarzonato e cercare di documentarti su testi e documenti con una 
forma corretta. lo so è noioso ed è più divertente "dirlo con parole tue" 
ma non è così che si impara il linguaggio.
 
 

 create nuove istanze.
 
sei sicuro? perche' il fatto che un costruttore deve essere per forza 
public l'ho letto qua:
http://www.webmasterpoint.org/programmazione/java/java/classi-oggetti.html
 
Cito:
"Analizzando l'intestazione del costruttore della classe Impiegato 
notiamo subito che si tratta di un metodo pubblico (public), che non è 
specificato alcun tipo di dato restituito. Tutti i costruttori devono 
avere queste due caratteristiche. Non è possibile definire costruttori 
di tipo private o che restituiscano un qualche tipo di valore in output"
 
Altra domanda: è giusto dire che si possono definire tanti costruttori 
quanti sono al massimo i campi di una classe?
 
[al resto rispondo dopo]

 quanti sono al massimo i campi di una classe?
Non necessariamente, se vuoi si puo' dire che puo' avere poco senso, ma 
ha ancora meno senso legare il numero dei costruttori al numero di 
campi. Considera questa classe:
 
public class Piffero {
   String pippo, pluto;
}
 
in questo caso sarebbe impossibile definire due costruttori uno per ogni 
variabile, perche':
 
public Piffero(String pippo) {...
 
e
 
public Piffero(String pluto) {...
 
hanno la stessa firma (un solo argomento di tipo String), quindi non 
puoi definirli entrambi.

 quanti sono al massimo i campi di una classe?
 
no, è una affermazione senza alcun fondamento.
 

 no, è una affermazione senza alcun fondamento.
 
bene!! mi pareva, però era una delle domande nel test che ho fatto oggi 
(prima parte dell'esame, teoria) e bisognava dire se fosse giusto o 
meno, ho intuito la risposta pur senza averne la certezza matematica.
 
 
 

spegnendo il cervello...
 
 
ma li' non è questione di spegnere il cervello...
se non si ha pratica e viene scritto che i costruttori devono essere
public è consequenziale basarsi su questa informazione (salvo
leggere anche altri testi per confronto)
 
quello che mi domando è come abbia potuto l'autore
fare un errore cosi' pacchiano,
 
che si confonda con qualche altro linguaggio di programmazione?
ma quale?
 
ciao, Jasmine

 fare un errore cosi' pacchiano,
Mah, difficile a dirsi. La risposta banale e' che l'autore avrebbe 
dovuto dedicarsi ad altro! :-))
Non ho letto attentamente il testo che hai citato, potrebbero esserci 
delle premesse che rendono vera quell'affermazione, che altrimenti e' falsa.
Certo e' che il modificatore public non e' l'unico che puo' essere 
attribuito ad un costruttore. Altrettanto certo, e' che se il 
costruttore non ha il modificatore public, non potro' istanziarlo 
tramite l'operatore new all'interno di un'altra classe. E' una tecnica 
abbastanza comune, definire private un costruttore, per  ottenere 
istanze singleton, ovvero quando il programmatore decide che di un 
oggetto debba esistere un'unica istanza nell'intera applicazione. Questo 
pattern e' comune anche ad altri linguaggi, C++ ad esempio.
Analizza questa classe:
 
public class UnoSolo {
   static UnoSolo instance;
   private UnoSolo () {
     super();
   }
   public static UnoSolo getInstance() {
     if (instance == null)
       instance = new UnoSolo();
     return instance;
   }
}
 
alternativamente potrebbe essere:
 
public class UnoSolo {
   static UnoSolo instance = new UnoSolo();
   private UnoSolo () {
     super();
   }
   public static UnoSolo getInstance() {
     return instance;
   }
}
 
un'altra classe che abbia bisogno di un'istanza dell'oggetto UnoSolo, 
non potra' crearla con l'operatore new, ma dovra' per forza ricorrere al 
metodo getInstance() in questo modo:
 
UnoSolo uno = UnoSolo.getInstance();
 
qualsiasi altra classe utilizzera' quindi il medesimo riferimento 
(istanza) di UnoSolo().

UnoSolo uno = UnoSolo.getInstance();
 
 
thanks
 
ciao, Jasmine
--
 
camminatore che vai cercando la pace al crepuscolo
la troverai' alla fine della strada (Battiato)

 per le classi, 0 per i tipi primitivi numerici, etc.)
 
Un costruttore non restituisce alcun valore: è l'espressione di 
istanziazione di una classe (tipicamente iniziata dalla parola chiave 
new) che alloca la memoria per l'oggetto, inizializza gli attributi al 
loro valore di default (il default per il suo tipo, o il valore indicato 
nella dichiarazione dell'attributo), e avvia la chiamata al corretto 
costruttore.
 
-- 
Lucio Benfante       
http://www.lambico.org
 
JUG Padova           
http://www.parancoe.org
 
www.jugpadova.it
 
http://www.jugevents.org
 

 fare un errore cosi' pacchiano,
 
Non e' che magari parlava di java beans? forse mi č sfuggito, ma dove 
l'avresti letta questa cosa?

 ereditato dalla classe java.lang.Object che tutte le classi estendono.
 
attenzione non è esatto dire che viene ereditato perché non esiste 
l'ereditarietà nei costruttori.
 
i costruttori hanno regole tutte loro riguardo all'argomento. le regole 
impongono che ciascun costruttore invochi *obbligatoriamente* un 
costruttore della classe padre; implicitamente quello di default senza 
argomenti (se esiste ed è visibile!) oppure esplicitamente con super(args) 
che deve anche essere la prima istruzione.  
 
ci sarebbe poi da parlare anche dei blocchi di inizializzazione anonimi, 
che anche quelli fanno parte del processo di inizializzazione della 
classe... insomma il nostro amico (o la nostra amica) deve prendersi un 
testo decente e leggersi quello perché i fondamentali non si esauriscono 
con articoletti pescati a casaccio nel web e qualche volenteroso che 
risponde alle domandine... 

l'avresti letta questa cosa?
 
 
sul sito citato da Jamie
 
Quoto integralmente il pezzo:
 
"citazione:Analizzando l'intestazione del costruttore della classe
Impiegato notiamo subito che si tratta di un metodo pubblico (public),
che non è specificato alcun tipo di dato restituito. Tutti i
costruttori devono avere queste due caratteristiche. Non è possibile
definire costruttori di tipo private o che restituiscano un qualche
tipo di valore in output. Il costruttore della classe Impiegato
richiede in input quattro parametri: nome, cognome, anno di nascita e
posizione del nuovo oggetto di tipo Impiegato che verrà generato.
Osserviamo che ai parametri passati in input viene dato lo stesso nome
delle proprietà della classe. Questa procedura, che altrimenti
potrebbe generare confusione, viene risolta utilizzando la parola
chiave this all'interno del corpo del costruttore. L'uso di this è un
modo per far riferimento ad una proprietà dell'oggetto che stiamo
generando. In questo modo, pur avendo entrambe lo stesso nome, non si
farà confusione tra le variabili passate al costruttore e le
corrispondenti proprietà dell'oggetto. Per evitare l'uso della parola
chiave this avremmo potuto scrivere: "


 l'ereditarietÃ  nei costruttori.
Hai ragione, ho sicuramente abusato del termine nel tentativo, maldestro 
se vuoi, di semplificare il concetto.
D'altra parte, le regole dell'ereditarietà impongono che non si possa 
restringere la visibilità di un metodo ereditato, ad esempio da public a 
private, e' invece possibile farlo con un costruttore proprio per le 
ragioni che hai voluto ricordare.
 

 nemmeno  linguaggi nuovi come Python o Ruby...
 
A parte il fatto che Python e' piu' vecchio di Java, in realta' il fatto
che uno specifico pattern sembri avere bisogno di una data feature non
implica che quella feature debba essere necessariamente parte del
modello ad oggetti "di per se". Oltretutto io in generale preferisco
monostate a singleton. 
 
Comunque, tornando a noi... per esempio in Python il modo piu' comune
per ottenere un singleton (per le persone che si ostinano a non usare
Borg) e' usare semplicemente un modulo. Gia'... i moduli di Python non
sono come i package di Java. In Python tutto e' un oggetto: anche un
modulo. E il linguaggio garantisce che un modulo sia importato una sola
volta e ne esista una sola istanza. O, volendo, si puo' usare una
classe. Tutto e' un oggetto: anche una classe. ;)
 
Poi per dire... in Smalltalk non ci stanno manco i costruttori
propriamente detti (solo un metodo new, che non ha terribili
peculiarita')
 
 
 
-- 
-riko
http://www.enrico-franchi.org/
 
http://rik0-techtemple.blogspot.com/
 

classe. Tutto e' un oggetto: anche una classe. ;)
 
 
 
sei sicuro che Python sia piu' vecchio di Java? Ho sempre saputo che
fosse un linguaggio piu' semplice e piu' recente rispetto a Java
 
Il fatto che Python utilizzi l'intentazione come elemento sintattico
del linguaggio mi scoraggia del tutto a "farne la conoscenza"
 
 
ciao, Jasmine
che non aveva mai sentito parlare del Pattern monoton

 che non aveva mai sentito parlare del Pattern monoton
 
E' monostate. ;)
In Agile Software Development di Uncle Bob ne parla. Potrebbe anche
essere un articolo che ha pubblicato in precedenza, alcuni capitoli di
quel libro lo sono.


 Quoto integralmente il pezzo:
 
Ah va beh, meglio che scriva di cucina.