3

ダウンキャストできないオブジェクトにダウンキャストを強制したいのですが、正しいアプローチは何だろうと思っていました。ユースケースは、チェックされたルールのリストと、失敗したルールのリストを生成するものがあるということです。失敗したルールは、ルールのサブクラスです。ただし、FailedRule のようなダウンキャストは
failedRule = (FailedRule) rule;

ルール オブジェクトが FailedRule のインスタンスではないため、失敗します。

これを回避するために、クローンをインスタンス化します。
FailedRule failedRule = 新しい FailedRule (ルール);

私のFailedRuleクラスは次のようになります

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());
   ..

これを行う簡単な方法はありますか?自分自身に答えるには、設計に欠陥があります。コードは次のようにする必要があります。

public class FailedRule{
  private Rule rule;
  ..
  public setRule(Rule rule){
  ..
4

6 に答える 6

2

ルールを に変換するメソッドを使用しますFailedRule

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

(ルールがすでに である場合はFailedRule、それをキャストして返します。それ以外の場合は、それを使用して を構築しますFailedRule)

于 2010-12-03T17:14:11.223 に答える
2

これはおそらく、継承階層の設計が不十分であることを示す兆候です。継承によって属性の可変性を導入しようとしています (Ruleインスタンスの場合、 a は「失敗しました」 FailedRule)。継承は、そのようなことにはあまり適していません。

コンポジション (FailedRule にはソースとして Rule がある) を使用するかfailed、 のインスタンスのブール属性にする必要がありますRule

于 2010-12-03T16:03:23.680 に答える
1

あなたが持っているものは、合理的な解決策のように見えます。いずれかのルールが潜在的に失敗したルールである可能性がある場合は、それを としてモデル化する方が適切な場合がありますRule.isFailed()

編集: 失敗は、ルールの変形ではなく、状態に非常によく似ています。その場合は、Rule.isFailed()優先することもできます。本当に失敗しないルールがある場合、次のようにモデル化できます。

           Rule
         /      \
         |       \
    FailableRule  RuleC
     /     |   
 RuleA    RuleB

うーん... 失敗しやすいルールは、実際には失敗しやすいルールですか? ぐう… 言語学。

于 2010-12-03T16:00:29.533 に答える
0

これほど簡単な方法はありません。あなたはこれを正しく行っています。

多くの場合、次のようなプライベート メソッドを記述します。

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

このようにして、このようにコンストラクターで呼び出すことができ、clone()メソッドを定義する必要がある場合はメソッドでも呼び出すことができます。

super.setRuleCodeもう 1 つのポイントは、電話をかけているのか、またはに電話しているのかを知ることですthis.setRuleCodeFailedRule明らかに、これら 2 つのことは、 if redefinesに応じて異なることを行いますsetRuleCode

于 2010-12-03T15:59:40.230 に答える
0

そのようなクラスをサブクラスにキャストすることはできません。サブクラスのメソッドや変数がないため、意味がありません。あなたがそれを正しくやっている方法。

于 2010-12-03T16:01:32.417 に答える
0

The way you are doing it is correct. The only comment I have to add is to move the copy code down to Rule itself.

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());
   ...
于 2010-12-03T16:17:42.983 に答える