[Java] Comportamento costruttori di classi figlie a cascata

BoG3
Ciao a tutti, ho una domanda:
Supponiamo di avere:
class A{ void f1(){
    System.oput.println("f1");}
}

class B extends A { void f2(){
    System.oput.println("f2");}
}

class C extends B { void f3(){
    System.oput.println("f3");}
}

public class Test{
    public static void main(String a[]){
        new Test();
    }
    Test(){
        A a;
        B b = new B();
        a = b;
        a.f1();  //OK, UPCAST IMPLICITO
        ((C)a).f3();  //NO, DOWNCAST ERRATO
    }
}


Ma se io avessi questo: ?
class A{ void f1(){
    System.oput.println("f1");}
}

class B extends A { void f2(){
    System.oput.println("f2");}
}

class C extends B { void f3(){
    System.oput.println("f3");}
}

public class Test{
    public static void main(String a[]){
        new Test();
    }
    Test(){
        A a;
        C c = new C();
        a = c;
        c.f1();  //OK, UPCAST IMPLICITO
        ((C)c).f3();  //Ora è possibile?
        ((B)c).f2(); //ANCHE QUESTO FUNZIONA? Non credo perchè non avendo mai istanziato la classe B f2(); non esiste! no?

Risposte
Howard_Wolowitz
Mmmh, non so è da un po' che non uso Java, non sono aggiornato sullo standard o cosa ma da cosa capisco dal codiche chi è figlio di chi?

BoG3
"Howard_Wolowitz":
da cosa capisco dal codiche chi è figlio di chi?


Hai ragione, scusa! ho rieditato il codice! Ora dovrebbero essere esatte le "Extends"

Howard_Wolowitz
Penso tu abbia copiato male o abbia involontariamente inserito pezzi da altre prove: non è possibile assegnare un oggetto della classe B alla classe C dove C è classe figlia di B.
Nel caso edita il primo post ed in seguito io editerò questo.
Può esserti inoltre d'aiuto provare a compilare tale sorgente e vedere che errori da.
Edit:
"BoG":

Ma se io avessi questo: ?
class A{ void f1(){
    System.oput.println("f1");}
}

class B extends A { void f2(){
    System.oput.println("f2");}
}

class C extends B { void f3(){
    System.oput.println("f3");}
}

public class Test{
    public static void main(String a[]){
        new Test();
    }
    Test(){
        A a;
        C c = new C();
        a = c;
        c.f1();  //OK, UPCAST IMPLICITO
        ((C)a).f3();  //Ora è possibile?
        ((B)c).f2(); //ANCHE QUESTO FUNZIONA? Non credo perchè non avendo mai istanziato la classe B f2(); non esiste! no?

Suppongo tu volessi scrivere ((C)a).f3(), alternativamente ((C)c).f3() non produrrebbe nulla di diverso da c.f3().
In tal caso il downcasting dell'oggetto a ad un oggetto della classe figlia C è possibile.
Per ((B)c).f2() questo upcasting è inutile perchè esegue sempre la funzione f2() definita in o ereditata da C, questo anche nel caso in cui tu riefinisca f2 in C, come mostro nel successivo esempio:
class A{
    
    public void f1(){
        System.out.println("f1");
    }
    
}

class B extends A {
    
    public void f2(){
        System.out.println("f2");
    }
    
}

class C extends B { 
    
    public void f2(){
        System.out.println("f2 definita in C!!");    
    }
    
    public void f3(){
        System.out.println("f3");
    }
    
}

public class Test{

    public static void main(String args[]){
        A a;
        C c = new C();
        a = c;
        c.f1();
        ((C)a).f3();
        B b = c;
        b.f2();
    }

}

BoG3
Fatto..

claudio862
C eredita da B, quindi è una sottoclasse di B (e di A). Quindi ha tutti i metodi di B (e quelli di A).

        A a;
        C c = new C();
        a = c;
        c.f1();  //OK, UPCAST IMPLICITO


        ((C)c).f3();  //Ora è possibile?

Certo che è possibile, stai convertendo un riferimento a C in un riferimento a C con un cast. Tanto valeva usare direttamente

        c.f3();



        ((B)c).f2(); //ANCHE QUESTO FUNZIONA? Non credo perchè non avendo mai istanziato la classe B f2(); non esiste! no?

Anche questo funziona, C ha tutti i metodi di B, quindi anche f2. Anzi, non serve nemmeno il cast:

        c.f2();

BoG3
capito grazie!

giogiomogio
mai indentare in quella maniera, mai!

quando lavori con le sottoclassi, nel momento in cui le istanzi esse hanno duplice tipo
quello figlio piu quello padre...

per fare un test usa una condizione dove gli chiedi di che istanza e' l'oggetto... usando istance of...
ti ritornera' true sia per la classe padre che per quella figlio...

l'oggetto rimane, in memoria del tipo della classe da cui istanziato...questo si ma al contempo e' anche di tipo della classe padre.
ma questo e' ovvio... seno' non avresti quella compatibilita' che ti permetterebbe di sfruttare anche i metodi della classe padre...

vedila cosi...
classe padre = veicoli
classe figlia di padre = trattore...

il trattore e' sia un trattore ma ANCHE un veicolo, giusto?
e' ambedue...

un veicolo invece e' solo un veicolo e NON per forza di cose un trattore ma potrebbe essere altro.
quindi per convenzione rimane un veicolo e basta.

se parti dal basso puoi risalire, ma se parti dall'alto non puoi scendere per determinare la tipologia di un oggetto, pertanto vai di cast...

consiglio,
leggiti un bel libro in inglese e non in italiano... ce ne sono a vagonate e gratuiti.

BoG3
ciao, grazie per la risposta, era un esempio dalle schede del prof, proprio per dare un idea di come si comportano i costruttori e metodi di classi padre e figlie :)
Sì, sto cercando di documentarmi sul sito della sun/oracle sulle cose che non capisco... pian piano ... :)

giogiomogio
ti consiglio questa lettura:
http://math.hws.edu/javanotes/
è stato scritto da un docente negli stati uniti di programmazione.
Di cui ho avuto l'onore di conoscere.

BoG3
Ciao, grazie del consiglio... do subito una letta. Vediamo che dice sugli Action Listener ... che sinceramente ho dei dubbi sul concetto :)

giogiomogio
se vuoi un altro consiglio:
imparati bene java e C che poi sei al top!

Rispondi
Per rispondere a questa discussione devi prima effettuare il login.