Visualizzazione dei risultati da 1 a 6 su 6
  1. #1

    [JAVA] Il cast tra riferimenti è utile nella pratica?

    Salve,
    In java, grazie all'ereditarietà, ogni oggetto di una sottoclasse può essere trattato come un oggetto della sua superclasse in quanto un oggetto di una sottoclasse (es.: Cane) è un oggetto della sua superclasse (es.: Animale).
    Il contrario non è vero. Per referenziare un oggetto di una superclasse con un riferimento di una sottoclasse devono esserci i seguenti due presupposti:
    [list=1][*]Vi deve essere un cast esplicito, ovvero una conversione di tipo;[*]L'oggetto della superclasse deve referenziare un oggetto della sottoclasse.[*]Eventualmente fare dei controlli con l'operatore istanceof[/list=1]

    Quindi:

    Animale a = new Animale;
    Cane c = new Cane; //dove Cane è sottoclasse di Animale
    a = c; //OK
    c = a; // ERRORE! ma se a fa riferimento ad un oggetto Cane posso fare c = (Cane) a

    Detto questo, nella speranza che sia giusto, mi chiedo:
    nella pratica della programmazione la conversione esplicita di riferimenti di superclassi in riferimenti di sottoclassi è una cosa effettivamente utile ed usuale o sarebbe bene, come si suol dire, che faccio finta di non conoscerla proprio questa nozione in quanto, oltre a confondermi, è pericolosa?

    Grazie dell'attenzione,
    Matteo
    Gutta cavat lapidem
    [La goccia scava la pietra]
    ***
    (Ovidio)

  2. #2
    Utente di HTML.it L'avatar di andbin
    Registrato dal
    Jan 2006
    residenza
    Italy
    Messaggi
    18,284

    Re: [JAVA] Il cast tra riferimenti è utile nella pratica?

    Originariamente inviato da matthew80
    Animale a = new Animale;
    Cane c = new Cane; //dove Cane è sottoclasse di Animale
    a = c; //OK
    c = a; // ERRORE! ma se a fa riferimento ad un oggetto Cane posso fare c = (Cane) a
    Certo che puoi fare:

    c = (Cane) a;

    A livello di compilazione sarebbe ok, il cast è possibile in quanto il compilatore sa che Cane e Animale sono in linea di ereditarietà (non puoi fare cast tra tipi non in relazione tra di loro, es. non puoi fare un cast da String a Integer o viceversa).

    Ma a runtime ti beccheresti un bel ClassCastException. Perché?? Semplice: l'oggetto referenziato da 'a' NON è un Cane ma è un Animale (hai fatto new Animale() infatti).

    Se facessi:

    codice:
    Animale a = new Cane ();
    
    Cane c = (Cane) a;
    allora sarebbe tutto ok.

    Originariamente inviato da matthew80
    Detto questo, nella speranza che sia giusto, mi chiedo:
    nella pratica della programmazione la conversione esplicita di riferimenti di superclassi in riferimenti di sottoclassi è una cosa effettivamente utile ed usuale o sarebbe bene, come si suol dire, che faccio finta di non conoscerla proprio questa nozione in quanto, oltre a confondermi, è pericolosa?
    No ti conviene conoscerla e molto bene.
    Andrea, andbin.devSenior Java developerSCJP 5 (91%) • SCWCD 5 (94%)
    java.util.function Interfaces Cheat SheetJava Versions Cheat Sheet

  3. #3
    Anzitutto grazie della risposta.

    Beh si, alla fine ho capito che posso fare il casting esplicito di un oggetto di una superclasse in un oggetto di una sottoclasse se e solo se l'oggetto della superclasse fa riferimento ad un oggetto della sottoclasse.

    Però mi chiedo: essendo pericolosa (e contorta a mio avviso) questa logica, non sarebbe meglio evitarla nella costruzione di programmi reali facendo in modo che le relazioni di ereditarietà tra gli oggetti seguano il loro percorso "naturale"?
    In altre parole voi quando fate programmi reali (e non mi riferisco ai programmini che faccio io ad uso didattico) vi trovate spesso nella condizionine di dover usate questo genere di conversione?
    Gutta cavat lapidem
    [La goccia scava la pietra]
    ***
    (Ovidio)

  4. #4
    Moderatore di Programmazione L'avatar di LeleFT
    Registrato dal
    Jun 2003
    Messaggi
    17,328
    Dipende tutto dalla complessità dell'applicazione e dal livello di astrazione che si vuole ottenere. Ma soprattutto questo genere di operazioni viene fatto quando si lavora con oggetti grafici complessi (come i JTextComponent o simili si Swing) e quando si ha a che fare con le interfacce (più che con le sottoclassi). Ad esempio molti controlli complessi (come JTable e JTree) offrono un alto livello di astrazione: vi sono metodi per ottenere, ad esempio, il TableModel da una JTable... TableModel è un'interfaccia, ma l'implementazione vera e propria (dei default) viene fatta attraverso un DefaultTableModel. Per poter oprare su di esso è quind "necessario" un cast esplicito per ottenere il reale oggetto di partenza.


    Ciao.
    "Perchè spendere anche solo 5 dollari per un S.O., quando posso averne uno gratis e spendere quei 5 dollari per 5 bottiglie di birra?" [Jon "maddog" Hall]
    Fatti non foste a viver come bruti, ma per seguir virtute e canoscenza

  5. #5
    Utente di HTML.it L'avatar di andbin
    Registrato dal
    Jan 2006
    residenza
    Italy
    Messaggi
    18,284
    Originariamente inviato da matthew80
    Beh si, alla fine ho capito che posso fare il casting esplicito di un oggetto di una superclasse in un oggetto di una sottoclasse se e solo se l'oggetto della superclasse fa riferimento ad un oggetto della sottoclasse.
    Diciamo, per essere più precisi, che a runtime, l'oggetto reale deve passare il test IS-A (è-un) con il tipo specificato nel cast.

    Mi spiego meglio con 2 esempi:

    Animale a = new Gatto (); // Gatto estende Animale
    Cane c = (Cane) a; // compilazione ok, a runtime ClassCastException!!

    Animale a = new CaneSanBernardo (); // CaneSanBernardo estende Cane
    Cane c = (Cane) a; // compilazione ok, runtime ok


    Originariamente inviato da matthew80
    Però mi chiedo: essendo pericolosa (e contorta a mio avviso) questa logica, non sarebbe meglio evitarla nella costruzione di programmi reali facendo in modo che le relazioni di ereditarietà tra gli oggetti seguano il loro percorso "naturale"?
    In altre parole voi quando fate programmi reali (e non mi riferisco ai programmini che faccio io ad uso didattico) vi trovate spesso nella condizionine di dover usate questo genere di conversione?
    In genere si cerca di sfruttare il più possibile il polimorfismo. Ad un metodo che riceve un reference di tipo Animale potrebbe anche non interessare se l'oggetto reale è un Cane, un Gatto o altro.

    Normalmente è più interessante sfruttare la chiamata di metodi in modo polimorfico, tramite la classe base. Se so che Animale definisce un metodo mangia() e che le sottoclassi Cane, Gatto o altro fanno l'override del metodo per fornire una implementazione più specifica, a me potrebbe servire solamente invocare il metodo mangia() attraverso il reference di tipo Animale. Questo è quello che si fa tipicamente.

    Poi è chiaro che ci sono dei casi in cui è necessario avere davvero un reference ad una sottoclasse, magari per chiamare metodi che esistono solo in quella classe o per altri motivi.
    In tal caso è bene fare prima un test con l'operatore 'instanceof' e solo se il test è true, allora fare il cast.
    Andrea, andbin.devSenior Java developerSCJP 5 (91%) • SCWCD 5 (94%)
    java.util.function Interfaces Cheat SheetJava Versions Cheat Sheet

  6. #6
    Ora la cosa mi è chiara

    Grazie tante
    Gutta cavat lapidem
    [La goccia scava la pietra]
    ***
    (Ovidio)

Permessi di invio

  • Non puoi inserire discussioni
  • Non puoi inserire repliche
  • Non puoi inserire allegati
  • Non puoi modificare i tuoi messaggi
  •  
Powered by vBulletin® Version 4.2.1
Copyright © 2025 vBulletin Solutions, Inc. All rights reserved.