2010-04-09 3 views
0

je me suis le suivant:comportement du pointeur comme en Java

class A{ 
    int foo; 
} 
class B extends A{ 
    public void bar(); 
} 

j'ai eu un exemple de A et que vous souhaitez le convertir en une instance de B sans perdre la référence à la variable foo.

Par exemple:

A a = new A(); 
a.foo = 2; 
B b = a; <-- what I want to do. 
//use b 
b.foo = 3; 
//a.foo should now be 3 

Merci pour toute aide!

+1

Vous pouvez essayer un peu de "composition over inheritance" ou bien ajouter une couche supplémentaire d'indirection. –

+0

Ce n'est pas possible. – SLaks

Répondre

4

Java ne supporte pas cela. Vous pouvez tirer parti du polymorphisme pour traiter une instance de B comme une instance de A, mais pas l'inverse.

La raison pour laquelle vous ne pouvez pas le faire est qu'il n'existe aucun moyen sûr de garantir que votre instance de A est en fait une instance de B (vous pouvez lancer l'instance mais même si vous l'avez fait, vous vous garantissez uniquement une exception au moment de l'exécution).

La meilleure façon de savoir s'il y a un type de sécurité, les relations entre les types polymorphes est de tester cette déclaration validité:

Toute instance d'un certain type est une instance d'un autre type.

Par exemple:

Toute instance de chien est une instance de mammifères.
Une instance de Mammal est une instance de Dog.

Notez que le premier exemple est vrai alors que le second est faux. Ce que vous essayez de faire dans votre exemple de code est exactement comme essayer de traiter un mammifère comme un chien - même si c'est parfois vrai, ce n'est pas vrai catégoriquement ce qui signifie que le compilateur ne le permettra pas.

Encore une fois, pour les moments où cela pourrait être vrai, vous devez lancer la référence, mais cela vous ouvre des exceptions au moment de l'exécution. Votre exemple spécifique ci-dessus est l'un de ces cas où une exception se produirait car nous pouvons clairement voir que vous avez instancié une instance de type A.

0

Utilisez un constructeur de copie:

class B extends A{ 
    public B(A a){ 
     this.foo = a.foo; 
    } 
} 
+0

foo est un int et ne sera pas référencé, il sera copié dans un nouveau foo. – Shmoo

+0

Il existe une solution simple: utilisez la classe wrapper 'Integer' au lieu de' int'. –

+0

Oui, mais la modification de la classe A n'est pas une option dans mon cas. – Shmoo

0

Vous ne pouvez pas le faire clairement parce que le type d'exécution de la variable a sera de toute façon A, pas B.

Cela signifie que a n'aura pas les caractéristiques de B .. et vous ne pouvez pas l'obtenir avec un casting!