2010-10-27 11 views
19

Sto cercando di capire il polimorfismo di Java e ho una domanda su downcasting di un oggetto. Diciamo che per questo esempio ho due sottoclassi cane e gatto che ereditano da un animale superclasseCome downcast di un oggetto Java?

Da quello che ho capito, l'unico modo per downcast un oggetto è se questo oggetto è già di tipo buono, come questo:

Animal a = new Dog(); 
Dog d = (Dog) a; 

Funziona bene?

Ma cosa succede se voglio creare un animale normale senza sapere cosa sarebbe, e quindi lanciarlo quando lo so, come posso farlo?

Animal a = new Animal(); 
Dog d = (Dog) a; 

In questo modo verrà generata una ClassCastException in fase di esecuzione?

L'unico modo che ho trovato per farlo è quello di creare un nuovo costruttore cane che crea un cane da un animale normale:

Animal a = new Animal(); 
Dog d = new Dog(a); 

con

public Class Dog extends Animal{ 
    public Dog(Animal a){ 
     super(a); 
    } 
} 

Quindi la mia domanda è: come sono Dovrei fare questo?

  • Sto facendo nel modo migliore?
  • Non dovrei farlo affatto, se devo farlo significa che il mio programma non è ben concepito?
  • C'è un modo migliore che ho perso?

Grazie mille! nbarraille

risposta

8

Se si desidera creare un'istanza di un tipo che può variare a seconda delle condizioni non locali, utilizzare Abstract Factory (come descritto nel libro Motivi di progettazione).

Nella sua forma più semplice:

interface AnimalFactory { 
    Animal createAnimal(); 
} 

class DogFactory implements AnimalFactory { 
    public Dog createAnimal() { 
     return new Dog(); 
    } 
} 

noti inoltre v'è una differenza tra il tipo statico di riferimento e il tipo dinamico dell'oggetto. Anche se si dispone di un riferimento Animal, se l'oggetto originale è un Dog, si comporta ancora come un Dog.

1

Java è un linguaggio fortemente tipizzato e ciò significa che è possibile eseguire il cast di un oggetto solo per un tipo che estende (una superclasse o un'interfaccia).

Anche se "si simula", ad es. copia tutti i metodi e i campi di una classe, non puoi semplicemente lanciare un oggetto su un tipo che non estende.

public class Foo{ 

    public String phleem; 

    public void bar(){ 

    } 

} 

public class Bar{ 

    public String phleem; 

} 

public interface Baz{ 

    public void bar(); 

} 

Dato il codice di cui sopra, non si può lanciare un oggetto Foo, o un Bar o un Baz, anche se la struttura di classe sembra implicare che si poteva. Non è coinvolta alcuna eredità, quindi viene lanciato uno ClassCastException.

3

Si dovrebbe lanciare solo una classe che l'oggetto è davvero, quindi se avete un Dog che si estende Animal si può lanciare a un Animal (perché è uno), ma non si deve lanciare un Animal ad un Dog perché non tutti gli Animal s sono Dog s. La classe Dog potrebbe avere campi aggiuntivi che non sono implementati dalla classe Animal e quindi il cast non ha senso (a cosa si inizializzano quei valori?).

0

Qui si parla di downcasting, quindi in questo scenario dovrebbe sempre essere utilizzata la superclasse come riferimento e l'oggetto figlio dovrebbe essere indicato da quello. Questo usd fondamentalmente in picchi di fabbrica.

Problemi correlati