Question

Je veux forcer un baissés sur un objet qui ne peut pas être vers le bas et casted se demandait ce que la bonne approche serait. Le cas d'utilisation est que j'ai une liste de règles qui sont vérifiées et ce qui va générer une liste de règles a échoué. Une règle a échoué est une sous-classe d'une règle. Mais comme
coulée en descente      FailedRule failedRule = (FailedRule) règle;

échouera parce que l'objet de la règle n'est pas un instanceof FailedRule

Pour contourner cela, j'instancier un clone;
     FailedRule failedRule = new FailedRule (règle);

et mes regards de classe FailedRule comme ceci

public class FailedRule extends Rule{

/* 
 *force a down cast from Rule to FailedRule through cloning
*/
public FailedRule (Rule upcast){
   super.setRuleCode( upcast.getRuleCode());
   super.setType(upcast.getType());
   ..

Yat-il un moyen plus facile de le faire? Pour répondre moi-même, la conception est erronée, le code doit être:

public class FailedRule{
  private Rule rule;
  ..
  public setRule(Rule rule){
  ..
Était-ce utile?

La solution

Ceci est probablement un symptôme que votre hiérarchie d'héritage est faiblement conçu. Vous essayez d'introduire mutabilité des attributs par héritage (un Rule a « échoué » si elle est une instance de FailedRule). L'héritage est pas vraiment bon pour ce genre de chose.

Je dirais que vous devriez soit la composition d'utilisation (un FailedRule a une règle comme source) ou que failed doit être un attribut booléen d'une instance de Rule.

Autres conseils

utiliser une méthode qui permet de convertir une règle à une FailedRule:

public static FailedRule asFailedRule(Rule rule){
    return (rule instanceof FailedRule)
    ? (FailedRule) rule
    : new FailedRule(rule)
}

(Si la règle est déjà un FailedRule, acteurs et le retourner, sinon l'utiliser pour construire un FailedRule)

Qu'est-ce que vous avez ressemble à une solution raisonnable. Si une règle pourrait être une règle a échoué, il est peut-être plus approprié de modèle que Rule.isFailed().

Edit: Echec ressemble beaucoup à un état, pas une variante d'une règle. Si tel est le cas Rule.isFailed() serait également préférer. S'il y a des règles qui vraiment ne manquent pas, nous pourrions modèle comme:

           Rule
         /      \
         |       \
    FailableRule  RuleC
     /     |   
 RuleA    RuleB

Hmm ... est failable règle en fait un faillible règle? Gaawgh ... linguistique.

Il n'y a pas moyen plus facile. Vous faites cela correctement.

Plusieurs fois, je vais écrire une méthode privée, quelque chose comme ceci:

private void copyFromRule(Rule otherRule) {
  this.setRuleCode(otherRule.getRuleCode());
  this.setType(otherRule.getType());
  ...
}

De cette façon, je peux l'appeler dans un constructeur comme celui-ci, et aussi dans une méthode clone() si je dois définir un.

Une autre question est de savoir si vous appelez super.setRuleCode ou this.setRuleCode. De toute évidence, ces deux choses faire des choses différentes selon que FailedRule redéfinit setRuleCode.

Vous ne pouvez pas lancer une classe à une sous-classe comme ça. Il n'a pas de sens car il n'aurait aucune des méthodes ou des variables de la sous-classe. La façon dont vous faites bien.

La façon dont vous faites est correct. Le seul commentaire que je dois ajouter est de déplacer le code de copie vers le bas pour lui-même la règle.

public class FailedRule extends Rule{

/* 
 *force a down cast from Rule to FailedRule through cloning
*/
public FailedRule (Rule upcast){
   super(upcast);
   //init FailedRule fields to defaults
}
}

public class Rule {

publiic Rule(Rule ruleToCopy) {
   //or even use the fields themselves. 
   this.setRuleCode( ruleToCopy.getRuleCode());
   this.setType(ruleToCopy.getType());
   ...
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top