Delucidazioni reference

di il
6 risposte

Delucidazioni reference

Ciao a tutti! mi chiamo Alessandro ed è da un po di mesi che sto studiando il java da autodidatta.
Ieri mi sono imbattuto in alcuni quesiti ai quali non riesco a trovare risposta da nessuna parte, probabilmente perchè non mi porgo le giuste domande, comunque voglio provare a condividerle con voi, magari qualcuno riesce a chiarirmi le idee.

1) qualli dati contiene un refernce? (lo so che contiene l'indirizzo del ogetto puntato, e anche " l'interfaccia publica ", ed e quest'ultima che non capisco cos'è e che meccanismi nasconde)
2) come funziona l'area dei metodi?
3) ci sono delle relazioni tra refference e area dei metodi?
4) cos'è e come viene implementata la Virtual method table in java?
5) dato l'esempio:

    class A {...}
    class B extends A {...}

     main(...)
      {
         A a=new A();
         B b=new B();
         a=b;
      }
come mai dopo aver assegnato il vallore del refernce b ad a, i due puntano ad oggetti apparentemente diversi?

6 Risposte

  • Re: Delucidazioni reference

    alexrr2iggs ha scritto:


    1) qualli dati contiene un refernce? (lo so che contiene l'indirizzo del ogetto puntato, e anche " l'interfaccia publica ", ed e quest'ultima che non capisco cos'è e che meccanismi nasconde)
    Una variabile "reference" o vale null (=nessun oggetto referenziato) oppure vale non-null (=c'è un oggetto referenziato). Non ci sono altre possibilità.
    Il valore contenuto in un reference, a basso livello, cioè per la JVM, sarà alla fin fine un "puntatore" sostanzialmente simile ai "puntatori" del C/C++.
    Ma per il programmatore Java un reference è qualcosa di molto "opaco": a) non è un valore numerico (non puoi stamparlo, non puoi convertirlo in un numero), b) non puoi farci della "aritmetica" (come invece è possibile in C/C++), c) non sai a priori quanti byte occupa (questo dipende dalla implementazione della JVM).

    Per il programmatore Java, un reference o è null o non-null. Stop.

    alexrr2iggs ha scritto:


    2) come funziona l'area dei metodi?
    Cioè? Cosa intendi per "area"??

    alexrr2iggs ha scritto:


    3) ci sono delle relazioni tra refference e area dei metodi?
    Idem: cosa intendi per "area"?

    alexrr2iggs ha scritto:


    4) cos'è e come viene implementata la Virtual method table in java?
    Credo che la implementazione esatta dipenda dalla JVM specifica. Puoi provare a vedere cosa dice il Java Virtual Machine Specification.
    Ma ti garantisco che puoi "vivere" tranquillamente anche senza sapere nulla di come la JVM implementi praticamente la "virtualità" dei metodi di istanza.

    alexrr2iggs ha scritto:


    5) dato l'esempio:
    come mai dopo aver assegnato il vallore del refernce b ad a, i due puntano ad oggetti apparentemente diversi?
    No, dopo a=b; le due variabili hanno lo STESSO reference.
  • Re: Delucidazioni reference

    andbin ha scritto:


    alexrr2iggs ha scritto:


    5) dato l'esempio:
    come mai dopo aver assegnato il vallore del refernce b ad a, i due puntano ad oggetti apparentemente diversi?
    No, dopo a=b; le due variabili hanno lo STESSO reference.
    i miei dubbi sono sorti dopo aver fatto questa prova:
    
    class Madre 
    {
    	public String nomeOgetto="oggetto Madre, ";
    	public String stringaDefault="default madre";
    	
    	
    	public Madre(String s)
    	{
    		this.nomeOgetto+=" "+s;
    		System.out.println("nuovo ogetto Madre \""+s+"\" istanziato");
    	}
    	
    	public void metodoComune()
    	{
    		System.out.println("metodo comune Madre");
    	}
    	
    	public void metodoMadre()
    	{
    		System.out.println("metodoMadre");
    		System.out.println(nomeOgetto+'\n'+stringaDefault);
    		
    	}
    	
    	public void aStringa()
    	{
    		System.out.println(this.toString());
    		System.out.println("nomeOggetto = \""+nomeOgetto+"\"");
    		System.out.println("stringaDefault = \""+stringaDefault+"\"\n");
    		
    	}
    }
    
    
    class Figlia extends Madre
    {
    	public String nomeOgetto="oggetto Figlia";
    	public String stringaDefault="default figlia";
    	
    	
    	public 	Figlia(String s)
    	{
    		super(s);
    		System.out.println("nuovo ogetto Figlia \""+s+"\" istanziato");
    	}
    	
    	public void metodoComune()
    	{
    		System.out.println("metodo comune Figlia");
    	}
    	
    	
    	public void metodoFiglia()
    	{
    		System.out.println("metodo Figlia");
    	}
    	
    	public void aStringa()
    	{
    		System.out.println(this.toString());
    		System.out.println("nomeOggetto = \""+nomeOgetto+"\"");
    		System.out.println("stringaDefault = \""+stringaDefault+"\"\n");
    		
    	}
    }
    
    
    
    public class Main 
    {
    	static Madre m=new Madre("mdr");
    	static Figlia f=new Figlia("fgl");
    	
    	static void info()
    	{
    		m.aStringa();
    		System.out.println(m.nomeOgetto+'\n'+m.stringaDefault+"\n\n");
    		f.aStringa();
    		System.out.println(f.nomeOgetto+'\n'+f.stringaDefault+"\n\n");
    	}
    	
    	public static void main(String[] args)
    	{
    		
    		System.out.print('\n');
    		info();
    		
    		
    		m.stringaDefault="string M. diversa";
    		f.stringaDefault="stringa F. diversa";
    		
    		System.out.println("dopo aver cambiato il vallore delle stringhe \"stringaDefault\" degli ogetti puntati da m ed f \n");
    		info();
    		
    		m=f;
    		
    		
    		System.out.println("dopo aver assegnato il vallore di f ad m \n");
    		info();	
    		
    		m.metodoComune();
    		   System.out.print('\n');
    		m.metodoMadre();
    		  System.out.print('\n');
    		f.metodoMadre();
    		  System.out.print('\n');
    		System.out.println(f.nomeOgetto);
    		System.out.print(m.nomeOgetto);
    		
    		
    		//m.metodoFiglia();  The method metodoFiglia() is undefined for the type Madre
    	}
    	
    	
    }
    
    



    output:

    nuovo ogetto Madre "mdr" istanziato
    nuovo ogetto Madre "fgl" istanziato
    nuovo ogetto Figlia "fgl" istanziato

    testReference.Madre@33909752
    nomeOggetto = "oggetto Madre, mdr"
    stringaDefault = "default madre"

    oggetto Madre, mdr
    default madre


    testReference.Figlia@55f96302
    nomeOggetto = "oggetto Figlia"
    stringaDefault = "default figlia"

    oggetto Figlia
    default figlia


    dopo aver cambiato il vallore delle stringhe "stringaDefault" degli ogetti puntati da m ed f

    testReference.Madre@33909752
    nomeOggetto = "oggetto Madre, mdr"
    stringaDefault = "string M. diversa"

    oggetto Madre, mdr
    string M. diversa


    testReference.Figlia@55f96302
    nomeOggetto = "oggetto Figlia"
    stringaDefault = "stringa F. diversa"

    oggetto Figlia
    stringa F. diversa


    dopo aver assegnato il vallore di f ad m

    testReference.Figlia@55f96302
    nomeOggetto = "oggetto Figlia"
    stringaDefault = "stringa F. diversa"

    oggetto Madre, fgl
    default madre


    testReference.Figlia@55f96302
    nomeOggetto = "oggetto Figlia"
    stringaDefault = "stringa F. diversa"

    oggetto Figlia
    stringa F. diversa


    metodo comune Figlia

    metodoMadre
    oggetto Madre, fgl
    default madre

    metodoMadre
    oggetto Madre, fgl
    default madre

    oggetto Figlia
    oggetto Madre, fgl



    come puoi vedere nelle ultime righe del main, i due reference puntano ad ogetti con atributi diversi
  • Re: Delucidazioni reference

    alexrr2iggs ha scritto:


    come puoi vedere nelle ultime righe del main, i due reference puntano ad ogetti con atributi diversi
    Non ho letto tutto ... anche perché quel tuo codice è parecchio contorto ... ma proprio tanto. E probabilmente ti stai perdendo nel classico bicchiere d'acqua.

    Domanda: ti è chiaro il concetto di "override"?
  • Re: Delucidazioni reference

    andbin ha scritto:


    Domanda: ti è chiaro il concetto di "override"?
    l'override è il meccanismo attraverso il quale java implementa il concetto di polimorfismo per metodi, si applica quando avendo un metodo m definito in una classe A, viene ridefinito in una sottoclasse di A.

    andbin ha scritto:


    Non ho letto tutto ... anche perché quel tuo codice è parecchio contorto ... ma proprio tanto.
    su questo non posso darti torto


    comunque penso di aver capito cos'è sucesso, ma non come.
    questo e quello che ho capito, correggimi se sbaglio:

    Un oggetto che sia istanza di una classe include un istanza di ognuno dei suoi supertipi (era questo che mi aveva fatto confondere)

    ogni refernce ha un' interfaccia pubblica, che è la lista dei metodi public, la quale possiamo dire che ne determina il tipo

    un refernce, per poter puntare un oggetto, necessita che quest' ultimo implementi tutti i metodi dell' interfaccia pubblica del reference stesso

    ultima domanda. È possibile assegnare ad un refernce l'indirizzo di un oggetto che non implementi tutti i metodi dell'interfaccia del reference stesso?
  • Re: Delucidazioni reference

    alexrr2iggs ha scritto:


    l'override è il meccanismo attraverso il quale java implementa il concetto di polimorfismo per metodi, si applica quando avendo un metodo m definito in una classe A, viene ridefinito in una sottoclasse di A.
    Si può dire un pelino meglio ma il senso è proprio questo.

    andbin ha scritto:


    Un oggetto che sia istanza di una classe include un istanza di ognuno dei suoi supertipi (era questo che mi aveva fatto confondere)
    No .. nì, detto un po' male. Questo di seguito forse ti farà capire:
    public class A {
        private int v1 = 10;
    
        public void stampaV1() {
            System.out.println(v1);
        }
    }
    
    public class B extends A {
        private int v2 = 20;
    
        public void stampaV2() {
            System.out.println(v2);
        }
    }
    Quando fai new B() crei 1 (e ripeto UNO solo) oggetto di tipo B. Esso contiene sia la variabile di istanza v1, sia la variabile di istanza v2. E su quell'oggetto B puoi invocare sia stampaV1 che stampaV2.

    Il fatto che v1 e v2 sono private è solo una questione di "accessibilità". Vuol semplicemente dire che v1 sarà accessibile solo da del codice all'interno di A mentre v2 solo da del codice in B. Ma lo "spazio" di memoria per v1 e v2 c'è COMUNQUE nell'oggetto B, indipendentemente dal loro livello di accesso.

    La classe B "eredita" il metodo stampaV1 da A ma attenzione, NON eredita v1. In Java "ereditare" un membro da una super-classe è più una questione di accessibilità (visibilità se vogliamo anche dirlo così). I campi/metodi ci sono comunque TUTTI nell'oggetto, non è questo il fatto di "ereditare".

    alexrr2iggs ha scritto:


    ogni refernce ha un' interfaccia pubblica, che è la lista dei metodi public, la quale possiamo dire che ne determina il tipo
    Il reference è un valore e basta. E una variabile di un tipo reference (es. String, Object ecc...) è semplicemente una variabile che è in grado di tenere il valore di un reference, null incluso.

    alexrr2iggs ha scritto:


    un refernce, per poter puntare un oggetto, necessita che quest' ultimo implementi tutti i metodi dell' interfaccia pubblica del reference stesso
    Questa frase non vuol dire nulla, mi spiace.

    alexrr2iggs ha scritto:


    È possibile assegnare ad un refernce l'indirizzo di un oggetto che non implementi tutti i metodi dell'interfaccia del reference stesso?
    Continui a parlare di "interfaccia" e di "reference", non ha senso.

    In Java esistono: interfacce, classi astratte e classi "concrete" (ovvero non astratte). Puoi creare una istanza, ovvero ottenere un oggetto, solo di classi "concrete". Poi la variabile a cui assegni l'oggetto può essere di qualunque tipo (anche di un tipo astratto) purché l'oggetto sia lecitamente assegnabile alla variabile.

    Number n = new Integer(123);

    Number (java.lang.Number) è una classe astratta. Non potrai mai fare new Number() (non è possibile, né avrebbe granché senso).
    Integer è una sottoclasse "concreta" di Number. Quindi puoi istanziare un Integer ed assegnarlo ad una variabile di tipo Number.
    Poi siccome la variabile n è di tipo Number, potrai invocare solo metodi "noti" a Number. Non puoi fare n.compareTo(altroInteger) perché compareTo è di Integer e Number non ne "sa" nulla.
    Però puoi fare n.intValue(). Il intValue è noto a Number ed è implementato in Integer. Quindi quando l'oggetto istanziato è realmente un Integer allora è il intValue() di Integer ad essere eseguito, non quello in Number.


    Più chiaro?
  • Re: Delucidazioni reference

    Ti ringrazio! mi hai chiarito dei dubbi che mi facevano impazzire
Devi accedere o registrarti per scrivere nel forum
6 risposte