Visualizza versione completa : Dubbio java...
Fast-M
13-09-2003, 19.06.11
Se prendiamo per esempio un metodo predefinito di java come il println(), cioè System.out.println(), questo metodo manda ciò che gli viene passato come parametro, per esempio una stringa, allo standard output, che in genere è il monitor.
Ora, ho letto in più posti che l’out dell’istruzione System.out.println() è un campo della classe System(cioè un dato membro di System) e quindi println() come fa ad essere un metodo??
Questa classe System come fa a contenere metodi all'interno di campi, cioè all'interno di dati membro??
Oppure è qualcosa che ha a che fare con l'ereditarietà e quindi con il comando extend?
Preciso che ho preso println() solo come esempio, ma la mia richiesta si estende a tutti i casi in cui si trova qualcosa del tipo:
"Class.campo1.campo2.campo3...campoN"
Grazie mille in anticipo!
Dav82
13-09-2003, 19.45.53
Perfetto quello che hai detto.
Out è un campo della classe System. Out è, se non mi ricordo male, un oggetto di tipo Stream (o qualcosa del genere, insomma un flusso dati), e questo tipo ha il metodo println. Perciò tu chiami il metodo println(), dell'oggetto out (di tipo Stream) della classe System. Puoi chiamare un metodo su questo campo perchè non è private, bensì public. Se fosse private non potresti chiamare metodi sul campo, perchè il campo sarebbe accessibile solo attraverso un'oggetto della classe System.
Ciao! :)
Fast-M
13-09-2003, 20.30.13
Allora...c'è qualcosa che non quadra.
L'operatore punto(.) in java si usa per accedere ai dati membro o ai metodi membro di una classe.
Ovviamente per accedervi bisogna dichiarare una variabile di tipo classe e assegnargli il puntatore alla nuova istanza della classe, cioè: Classe var=new Classe();
E questo bisogna farlo a meno che la classe Classe non sia stata dichiarata Static, perchè in questo caso non c'è bisogno di creare istanze perchè è già in memoria e per puntarvi basta usare il suo nome stesso.
Detto questo, se io voglio agire su un dato membro della classe che si chama per esempio "campo1" oppure su un metodo membro che si chiama "metodo1()" allora tramite la variabile che ho usato per puntare la istanza della classe, cioè var1, scriverò:
var1.campo1=...
oppure
var1.metodo1(..)=...
Quindi come vediamo ho usato una sola volta l'operatore "."
La cosa che non ho capito bene è quando il punto si usa piu di una volta e perchè.
Cioè se io, usando il punto una volta accedo ad un campo o ad un metodo della classe, a cosa mi serve usarlo più di una volta come nel caso di System.out.println() o di molti altri casi?
Visto che non possono esserci metodi all'interno di altri metodi o campi dentro altri campi, allora usare il punto più di una volta a cosa serve?
Per caso è dovuto al discorso dell'ereditarietà e del comando extend?
Ma se così fosse, come potrebbe "out" essere un campo di System?:confused::confused::confused:
Grazieee!
:)
Dav82
13-09-2003, 20.44.21
Metti che ci sia questa situazione (non sarà sicuramente così in modo esatto, ma per rendere l'idea)
public static class System{
public Stream out //out è un campo della classe System, di tipo Stream
// corpo della classe System
}
public class Stream {
//campi
public void println (String StringaDaStampare){
//corpo del metodo
}
//resto della classe Stream
}
Adesso tu dal tuo main vuoi stampare una stringa sullo standard output. Devi chiamare il metodo println() del campo out della classe System. Quindi con System.out identifichi il campo, e con il successivo ".println()" invochi il metodo println() sull'oggetto identificato, che è appunto "System.out".
Spero di essermi spiegato meglio! ;)
Ciao! :)
Fast-M
13-09-2003, 21.00.20
Grazie mille Dav82!
Quindi il fatto che la classe System abbia un campo out di tipo Stream significa che out potrà contenere un puntatore ad una istanza di Stream, cioè sarà una variabile tramite la quale si potrà accedere tramite l'operatore punto a membri di Stream non di System!
Correggimi se sbaglio.
Quindi in generale si usa il punto più volte quando si hanno delle classi che hanno come campi variabili oggetto e quindi per accedere ai membri dell'oggetto puntato da queste variabili oggetto, bisogna usare per forza il punto più volte!?
Sei stato utilissimo, grazie davvero!
:D
Dav82
13-09-2003, 21.35.55
Originariamente inviato da Fast-M
cioè sarà una variabile tramite la quale si potrà accedere tramite l'operatore punto a membri di Stream non di System!
Correggimi se sbaglio.
In sostanza sì.
Piccola divagazione ma non troppo:
se out fosse private, tu non potresti invocare out.println(), perchè lo faresti da una classe diversa da System, e quindi ci sarebbe un errore di protezione (o come diavolo si chiama, non ricordo! :confused: ). Potresti però chiamare lo stesso il metodo su out, a patto che la classe System fornisca un metodo che, chiamato, invochi la println() sul proprio membro privato out. In sostanza un metodo fatto così:
public void stampa(Stream NdoCacchioVuoiStampà){
NdoCacchioVuoiStampà.println();
}
Originariamente inviato da Fast-M
Quindi in generale si usa il punto più volte quando si hanno delle classi che hanno come campi variabili oggetto e quindi per accedere ai membri dell'oggetto puntato da queste variabili oggetto, bisogna usare per forza il punto più volte!?
Come sopra, a patto che siano public (o protected o friendly... guarda su un manuale). La "multi-dot-notation" si può usare anche in un altro modo. Pensa di avere un polinomio Poli, puoi fare:
(Poli.add(Polinomio2)).mult(Polinomio3)
Cosa abbastanza ovvia, lo so! :D :p
Di niente, figurati! Ho fatto una pausa mentre studio elettronica!
Ciao! :)
Fast-M
13-09-2003, 21.50.02
Si certo, hai precisato il discorso sui campi privati che per essere gestiti necessitano di un metodo publico che agisce su di loro.
Come il discorso di un forno che ha una resistenza interna che scalda e poi delle manopole esterne che permettono di modificare lo stato della resistenza che cuoce i cibi.
Di certo per cuocere qualcosa in forno non lo smonta l'utente per effettuare il contatto che accende la resistenza, ma agisce sulle manopole che sono appunto il metodo public che modifica lo stato interno della resistenza che è appunto il campo private.
Ho inteso? :rolleyes:
Un'ultima domanda a questo punto mi sorge spontanea.
Perchè visto che println() è un metodo membro di Stream, non usare direttamente una forma tipo: Stream.println(...); ??
Cioè perchè partire da System che ha come campo un oggetto Stream, quando visto che Stream è un oggetto a se stante si potrebbe usare direttamente da solo con i suoi metodi??
:confused:
Dav82
13-09-2003, 21.59.39
Bello l'esempio! Me lo segno così se devo spiegare a qualcuno sta cosa! (Y)
Non chiami Stream.println() perchè:
1) Non penso che la classe Stream abbia un metodo println statico, cioè riferito alla classe. Tu stampi su un qualche flusso, che può essere un InputStream (che è il tipo del membro "in" della classe System) oppure un OutputStream (il tipo di "out") o un ErrorStream (il tipo di "err", sempre di System).
2) Perchè a te interessa stampare su out, che è il flusso di uscita sullo standard output, e non su un generico flusso. ;) (cosa che peraltro, come al punto 1, non penso abbia senso nè sia permessa, mi informerò)
Ciao ciao! :)
Fast-M
14-09-2003, 04.35.39
Ah ecco!
Quindi chiamando il metodo println() da System che ha come campo una variabile oggetto di tipo Stream, vuol dire che sottopongo la mia chiamata anche al corpo di codice di System che a modo suo agirà su out e quindi su println() mandandomi questo stream di caratteri allo standard output.
Invece se chiamassi soltanto println() da Stream, allora genererei un flusso di caratteri che magari dovrei mettere io stesso in un array di char e non mi andrebbe direttamente allo standard output.
Ho afferrato?
:)
Fast-M
14-09-2003, 12.27.03
Ma comunque in linea generale, quando si chiama un metodo contenuto in un oggetto che a sua volta è campo di un altro oggetto, come nel caso di System.out.println(), questo oggetto di tipo Stream, cioè out che è campo di System, dovrà al suo interno, cioè Stream, avere il metodo println() dichiarato come static, o no?
Altrimenti se io scrivo System.out.println(...), su System ci siamo perchè è static è quindi non c'è bisogno che ne crei una istanza, ma per potere chiamare poi anche println() che è metodo di Stream, senza creare alcuna istanza di Stream, significa che anche la classe Stream oppure il metodo println() all'interno di Stream devono essere statici?
Oppure il fatto che una classe statica abbia come campo un oggetto di un'altra classe, rende automatica la staticità di questo campo oggetto, anche se questo oggetto in se non ha nulla di statico?(mi pare strano,possibile?)
Con questo ho chiuso i dubbi.
Grazie molte Dav82!
:) (D)
Fast-M
19-09-2003, 18.01.01
Originariamente inviato da Dav82
Metti che ci sia questa situazione (non sarà sicuramente così in modo esatto, ma per rendere l'idea)
public static class System{
public Stream out //out è un campo della classe System, di tipo Stream
// corpo della classe System
}
public class Stream {
//campi
public void println (String StringaDaStampare){
//corpo del metodo
}
//resto della classe Stream
}
Adesso tu dal tuo main vuoi stampare una stringa sullo standard output. Devi chiamare il metodo println() del campo out della classe System. Quindi con System.out identifichi il campo, e con il successivo ".println()" invochi il metodo println() sull'oggetto identificato, che è appunto "System.out".
Spero di essermi spiegato meglio! ;)
Ciao! :)
Ma può anche essere direttamente inizializzato il campo out a puntare ad una istanza di Stream?
Cioè tipo:
---------------
public static class System{
public Stream out=new Strem(); //out è un campo della classe System, di tipo Stream
// corpo della classe System
}
----------------
è possibile mettere come campo di una classe, direttamente una variabile reference ad una istanza di un altro oggetto?
Dav82
19-09-2003, 20.13.56
In java tutti i campi sono reference, tranne i char e gli integer (forse altri... ma non ricordo.. cmq tipi "primitivissimi" :D ). Quindi se in una classe hai un campo che non è di uno di questi tipi, ovviamente deve essere un reference, e quindi punta ad un oggetto che è istanza di una classe. (attenzione ;) si istanzia una classe con un oggetto, che è appunto istanza di una classe).
Poi il campo out lo puoi "inizializzare" in fase di dichiarazione, facendo out = new Stream(), oppure prima del primo uso... va a gusti... io preferisco farlo subito.
Ciao! :)
Fast-M
20-09-2003, 15.56.42
package classes.Prova;
class A{
void campo(){
System.out.println("Metodo 'campo' di classe A usato!");
}
}
class B{
void B(){
//costruttore
}
A campoRef=new A();
void stampa(){
campoRef.campo();
}
}
class C{
static B campoRef2=new B();
public static void main(String[] args){
campoRef2.campoRef.campo();//accedo al metodo campo di A, tramite B che lo referenzia tramite campoRef
campoRef2.stampa();//non mi fa accedere perchè B non ha metodo main ??
}
}
Compila correttamente, ma quando lo lancio mi da un messaggio in cui mi dice che la classe B non ha metodo main e non parte.
Dav82
20-09-2003, 16.49.16
Qualche appunto ;)
Quando posti del codice, metti i tag di code (che sono (code) e (/code), con al posto delle tonde le quadre), così si capisce meglio il tutto.
E soprattutto fai un file separato per ogni classe che programmi... lo so che all'inizio sembra più facile e immediato fare tutto in un solo file, ma credimi che è molto meglio spezzare il tutto.
Infatti ho fatto copia-incolla nel più squallido dei compilatori (Jcreator), semplicemente spezzando i file e ha eseguito tutto subito, senza errori.
Tu che compilatore usi?
Anche se sei alle prime armi, ti consiglio, se hai un pc non vecchissimo, di usare SunOneStudio della Sun... è spettacolare! Lo puoi trovare qui (http://java.sun.com)
Ciao! :)
Fast-M
20-09-2003, 19.36.13
Si certo uso il Netbeans e devo scaricare la versione nuova, ma questa che uso è comunque abbastanza nuova.
Comunque non è quello il problema, perchè ho creato 3 classi sistinte con 3 source distinti ecc., ma dopo che compilo e va tutto bene, quando avvio mi da lo stesso errore.
"La classe B non ha metodo main"
Che sarà?
Premetto che io per creare un progetto come questo, innanzitutto creo una nuova cartella col nome che avrà la classe publica e poi ci premo su col destro e scelgo nuova classe e mi compare il source della classe vuota già impostata con costruttore vuoto e tutto.
:rolleyes:
pholcus
20-09-2003, 20.26.36
la classe C deve essere public perche' il main e' li.Poi se metti tutto in un file devi nominare il file C.java
Togli package classes.prova.
Compila con java *.java
e poi x far partire
java C
vedrai che funziona tutto alla perfezione..
dav82 com'e' SunOneStudio? E' meglio del JBuilder?
Dav82
20-09-2003, 20.40.36
Originariamente inviato da pholcus
dav82 com'e' SunOneStudio? E' meglio del JBuilder?
D'oh! Copiando e incollando avevo messo "public" in automatico.. non ci avevo fatto caso! :S
Io ho provato un giorno JBuilder e poi ho cambiato subito, e il parere è lo stesso di molti miei amici che sono anche stati più tempo con JBuilder. C'è poi da dire che SunOneStudio è fatto dalla Sun che ha "inventato" Java... chi meglio di loro! Unica pecca è che è scritto tutto in Java, quindi all'apertura è un po' lento, e mangia tanta ram... ma anche lì Jbuilder non è che ne usi poca. In sostanza, va un po' a gusti... però SunOneStudio è, secondo me e a detta di molti, il meglio (Y)
Ciao! :)
pholcus
20-09-2003, 21.13.58
Scaricato sia la versione x windows che x linux trial..ora li provo..
Ciao!
Fast-M
21-09-2003, 14.28.23
Ahahahaha!
Ragazzi, non sapete quale era il problema!:D
Praticamente quando lanciavo dal Netbeans l'applicazione, ero posizionato su una delle classi senza metodo main, quindi l'IDE chiaramente lo prendeva come se volevo lanciare la classe attiva che era senza main e cioè A o B.
Incredibile, provando e riprovando ho notato per caso che solo quando ero posizionato sulla classe C che contiene il main, allora partiva tutto senza problemi.
Comunque anche togliendo il modificatore public parte comunque, perchè se non si mette nulla il default non ricordo precisamente quale sia(forse protected), ma è comunque package frendly e permette la visibilità con scope di package.
L'importante è non mettere private.
Ok, grazie lo stesso!
:)
vBulletin® v3.8.6, Copyright ©2000-2025, Jelsoft Enterprises Ltd.