Comment downcaster un objet Java?
-
26-09-2019 - |
Question
Je suis en train de comprendre le polymorphisme de Java, et j'ai une question sur un objet coulée en descente. Disons que pour cet exemple, j'ai deux sous-classes avec chiens et chats qui héritent d'un animal superclasse
D'après ce que je comprends, la seule façon de downcaster un objet est si cet objet est déjà du bon type comme ceci:
Animal a = new Dog();
Dog d = (Dog) a;
Cela fonctionne bien?
Mais si je veux créer un animal régulier sans savoir ce qu'il serait, puis jeté quand je sais, comment puis-je faire?
Animal a = new Animal();
Dog d = (Dog) a;
Cela jette un ClassCastException au droit d'exécution?
La seule manière que je trouvais de le faire est de créer un nouveau constructeur de chien qui crée un chien d'un animal normal:
Animal a = new Animal();
Dog d = new Dog(a);
avec
public Class Dog extends Animal{
public Dog(Animal a){
super(a);
}
}
Alors, ma question est, comment suis-je censé faire?
- Suis-je le faire de la meilleure façon?
- Suis-je pas censé le faire du tout, si je dois cela signifie que mon programme est conçu pas bien?
- Y at-il une meilleure façon que je manqué?
Merci beaucoup! nbarraille
La solution
Si vous voulez créer une instance d'un type qui peut varier en fonction des conditions non locales, utilisez un Abstract Factory (tel que décrit dans le livre de design Patterns).
Dans sa forme la plus simple:
interface AnimalFactory {
Animal createAnimal();
}
class DogFactory implements AnimalFactory {
public Dog createAnimal() {
return new Dog();
}
}
Notez également qu'il ya une différence entre le type statique d'une référence et le type dynamique de l'objet. Même si vous avez une référence Animal
, si l'objet original est un Dog
, il se comporte toujours comme un Dog
.
Autres conseils
Vous ne devriez jeter à une classe que l'objet est vraiment, donc si vous avez un Dog
qui va Animal
vous pouvez le jeter à un Animal
(parce qu'il est l'un), mais vous ne devriez pas jeter un coup Animal
à un Dog
parce que tous les Animal
s sont Dog
s. La classe Dog
pourrait bien avoir des champs supplémentaires qui ne sont pas mises en œuvre par la classe Animal
et donc le casting n'a pas de sens (ce initialisez-vous ces valeurs?).
Java est un langage fortement typé, et cela signifie que vous ne pouvez jeter un objet à un type, il va de (soit une superclasse ou une interface).
Même si vous « faux », a par exemple copier toutes les classes une des méthodes et des champs, vous ne pouvez pas lancer un objet à un type qu'il ne se déploie pas.
public class Foo{
public String phleem;
public void bar(){
}
}
public class Bar{
public String phleem;
}
public interface Baz{
public void bar();
}
Vu le code ci-dessus, vous ne pouvez pas jeter un objet Foo
soit un Bar
ou Baz
, bien que la structure de classe semble impliquer que vous pourriez. Il n'y a pas d'héritage en cause, donc une ClassCastException
est levée.
Ici, vous parlez de coulée en descente, donc dans ce scénario toujours superclasse devrait être utilisé comme un objet de référence et de l'enfant doit être fait par cela. Cette USD essentiellement en boniment usine.