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

    Operatore ? e downcasting

    Ciao a tutti! Volevo porvi una domanda su una cosa che non capisco.

    Ho una classe astratta Oggetto e due sottoclassi Regalo e Libro.
    La classe Oggetto dispone di un metodo peso, che restituisce il peso dell'oggetto, metodo definito nelle sottoclassi.
    In un'altra Classe Scatola posso aggiungere degli oggetti di tipo Regalo e Libro.
    La classe Scatola ha al suo interno due metodi: pesoTotale() e numeroOggetti().

    codice:
    Class Scatola {.. campi, metodi...
    
      numeroOggetti() [ //tutto ok, non mi dà problemi, restituisco l'indice degli elementi inseriri }
    
      pesoTotale(){
         double tot=0;
        (for Oggetto o:p) //dove p è l'array degli oggetti inseriti
    //DOWNCAST PER UTILIZZARE IL METODO peso()
           if (o instanceof Regalo){
               tot += ((Regalo)o).peso();
             }
           else if (o instance of Libro){
               tot += ((Libro)o).peso();
            }
            return tot;
        }
    La domanda è: perchè non mi lascia sostituire tutto l'if con:
    tot += (o instanceof Regalo) ? ((Regalo)o).peso() : ((Libro)o).peso();

    ?? Grazie
    p.s. Un'altra domanda, forse stupida. Una volta che controllo se o è un'istanza di regalo, se è vera, bene. Nel'else devo per forza mettere il controllo sull'istanza di Libro? Perchè?

    Grazie!!

  2. #2
    Moderatore di Programmazione L'avatar di LeleFT
    Registrato dal
    Jun 2003
    Messaggi
    17,320
    A dire il vero, se il metodo "peso()" è definito nella classe Oggetto, non serve affatto fare tutto quel casino... :


    codice:
    for(Oggetto o : p) {
       tot += o.peso();
    }

    Questo codice funziona tranquillamente (è la base del polimorfismo).

    Inoltre, non vedo perchè tu non possa usare l'operatore ternario "?" nel modo che hai descritto. Quell'istruzione è perfettamente valida (ma, come già detto, inutile).

    La terza domanda è più "complessa"... se tu sei sicuro che tutti gli oggetti "Oggetto" si dividono in istanze di "Libro" e istanze di "Regalo", non ci sono problemi e il test nell'else lo puoi tranquillamente saltare... se, al contrario, vi sono altre classi che estendono "Oggetto" e non hai la certezza che tutte le istanze di quell'array siano dei due tipi descritti, allora potresti incorrere in un ClassCastException nel caso tu provassi a castare un oggetto ad una classe che non c'entra nulla.

    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

  3. #3
    Grazie mille per la risposta

    Utilizzo il downcasting perchè utlizzando il metodo con la classe Oggetto (astratta), mi restituisce un'errore di tipo NullPointerException.

    edit: Di fatto io utlizzavo il controllo in questo modo: Se la classe è di tipo es. Regalo allora utilizzo eventualmente un metodo esclusivo della classe regalo, altrimenti puoi utilizzare qualsiasi metodo ereditato dalle sottoclassi... Ma mi dà l'errore sopra..

  4. #4
    Utente di HTML.it L'avatar di andbin
    Registrato dal
    Jan 2006
    residenza
    Italy
    Messaggi
    18,284
    Quote Originariamente inviata da GigiAriete Visualizza il messaggio
    Utilizzo il downcasting perchè utlizzando il metodo con la classe Oggetto (astratta), mi restituisce un'errore di tipo NullPointerException.
    Le due cose (downcast e NullPointerException) non centrano tra di loro. Se hai un NPE è perché stai facendo qualcosa di sbagliato con i reference in generale o perché hai dimenticato qualche inizializzazione da qualche parte. Il downcast non centra, LeleFT ti ha già risposto perfettamente dicendo quello che ti avrei detto io se fossi riuscito a postare prima di lui.
    Andrea, andbin.devSenior Java developerSCJP 5 (91%) • SCWCD 5 (94%)
    java.util.function Interfaces Cheat SheetJava Versions Cheat Sheet

  5. #5
    Grazie a entrambi!
    Quindi per il downcasting non c'è bisogno di tutto quel codice perchè lo fa in "automatico", ok.
    Il problema è che, ad esempio in una classe Tester, utilizzando il metodo pesoTotale(), mi restiuisce in fase di esecuzione quell'errore se scrivo semplicemente o.peso(), mentre va tutto bene se faccio tutto il casino postato sopra.

  6. #6
    Utente di HTML.it L'avatar di andbin
    Registrato dal
    Jan 2006
    residenza
    Italy
    Messaggi
    18,284
    Quote Originariamente inviata da GigiAriete Visualizza il messaggio
    Quindi per il downcasting non c'è bisogno di tutto quel codice perchè lo fa in "automatico", ok.
    È appunto il "polimorfismo". E non fa alcun downcast lui in automatico.

    Quote Originariamente inviata da GigiAriete Visualizza il messaggio
    utilizzando il metodo pesoTotale(), mi restiuisce in fase di esecuzione quell'errore se scrivo semplicemente o.peso()
    Se uno degli elementi nel tuo array può essere null, questo chiaramente va testato, fai la/e invocazione/i su o solo se o != null. Ma questo non centra nulla con downcast e polimorfismo.
    Andrea, andbin.devSenior Java developerSCJP 5 (91%) • SCWCD 5 (94%)
    java.util.function Interfaces Cheat SheetJava Versions Cheat Sheet

  7. #7
    Grazie, funziona! Mi ero dimenticato del controllo sul valore null!
    Ultima domanda: se i metodi sono ereditati dalla superclasse, allora agisce il polimorfismo. Se un metodo invece appartiene solamente ad UNA sottoclasse, chiaramente devo fare un casting esplicito dopo aver controllato che sia effettivamente un'istanza di quella sottoclasse?
    Grazie ancora per la pazienza!

    edit: ad esempio se Libro ha: numeroPagine()

    Allora QUI è giusto che faccia

    if (o.instanceof Libro)
    tot += (Libro)o).numeroPagine(); ??

  8. #8
    Utente di HTML.it L'avatar di andbin
    Registrato dal
    Jan 2006
    residenza
    Italy
    Messaggi
    18,284
    Quote Originariamente inviata da GigiAriete Visualizza il messaggio
    se i metodi sono ereditati dalla superclasse, allora agisce il polimorfismo.
    Ereditato e ridefinito. Allora sì, invocando su un reference della classe base (superclasse) hai una invocazione polimorfica.

    Quote Originariamente inviata da GigiAriete Visualizza il messaggio
    Se un metodo invece appartiene solamente ad UNA sottoclasse, chiaramente devo fare un casting esplicito dopo aver controllato che sia effettivamente un'istanza di quella sottoclasse?
    Grazie ancora per la pazienza!

    edit: ad esempio se Libro ha: numeroPagine()

    Allora QUI è giusto che faccia

    if (o.instanceof Libro)
    tot += (Libro)o).numeroPagine(); ??
    Sì, se numeroPagine() è "nuovo" solo in Libro, non puoi fare altrimenti. Oggetto non ne "sa" nulla di numeroPagine, non ce l'ha e quindi o.numeroPagine() non compilerebbe nemmeno.
    Andrea, andbin.devSenior Java developerSCJP 5 (91%) • SCWCD 5 (94%)
    java.util.function Interfaces Cheat SheetJava Versions Cheat Sheet

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.