2016-04-04 2 views
0

J'ai besoin de ma classe C pour choisir le constructeur correct basé sur la variable d'instance. J'ai le code de base montré ci-dessous. Chaque fois que je crée une instance d'une classe B et que je la stocke comme référence à A. Le constructeur 'Wrong' est utilisé sur la classe C. Quelles sont mes options pour changer cela si je ne veux pas utiliser (b instanceOf B) parce que c'est dans autre paquet.Java, utiliser le constructeur correct basé sur l'instance

Class A { 
} 

Class B extends A { 
} 


Class C { 
    C(A a){...} 
    C(B b){...} 
} 

Class Main{ 
    private createClass(String s){ 
     if (...){ 
      return new B(); 
     } 
    } 

    public static void main(String[] args){ 
     A b = createClass("s"); 
     new C(b); //--> constructor C(A a) is used but i need C(B b) 
    } 
} 

Répondre

2

new C(A a) est appelée, car la variable b est de type A à la compilation. Le compilateur ne sait pas qu'au Runtime il contiendra une référence à une instance de B et c'est pourquoi il se lie au constructeur new C(A a).

En général, je pense que votre devrait reconsidérer votre conception, mais si vous voulez le garder comme ça, vous pourriez au moins faire la méthode createClass() générique et passer le Class<T> du type resuling:

private <T extends A> T createClass(String s, Class<T> clazz){ 
    if (...) { 
     return clazz.newInstance(); 
    } 
    // 
} 

Cela vous permettra de mettre en évidence (et passer facilement) le type du résultat dont vous avez besoin:

B b = createClass("s", B.class); 
new C(b); 
0

plutôt que d'utiliser deux constructeurs, utilisez constructeur unique et utiliser if (a instanceOf B) et jeté l'objet en B to perf oum toutes les opérations liées à la classe B spécifiquement. comme extrait ci-dessous

Class C { 
    C(A a){ 
     if(a instanceOf B){ 
      B b =(B) a; 
      // all the stuff related to B only 
     } 
     //common work for both the scenarios 
    } 
} 
+0

je l'ai mentionné que instanceOf est pas une option que la classe C est pas dans le même paquet et peut être distribué seul donc un ClassNotFound serait tiré. – Mazmart

+0

CNF sera renvoyé dans tous les cas, alors, si la classe n'est pas accessible, quelle instanceOf doit faire avec. 'Pour ClassNotFoundException: Lance lorsqu'une application tente de charger dans une classe via son nom de chaîne en utilisant: 1. La méthode forName dans la classe Class. 2. La méthode findSystemClass dans la classe ClassLoader. 3. La méthode loadClass dans la classe ClassLoader.' –