2010-12-03 73 views
3

我想迫使某個對象不高興,但不知道什麼是正確的方法。 用例是我有一個檢查規則的列表,以及將生成失敗規則列表的內容。失敗的規則是規則的子類。但向下傾斜如
FailedRule failedRule =(FailedRule)規則;Java中的強制向下轉換

將失敗,因爲該規則的對象不是一個instanceof FailedRule

若要解決此我實例化一個克隆;
FailedRule failedRule = new FailedRule(rule);

和我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){ 
    .. 
+0

我想知道你最終不得不對一個不能被擊倒的對象強制下注。向我們解釋你真正想做的事情。 – 2010-12-03 16:01:18

+0

雖然我做了:-)。我遍歷一系列規則並返回失敗的規則列表。檢查過程爲每個規則返回相當數量的信息爲什麼,何時以及如何失敗。馬克的回答是正確的,我的設計是錯誤的,我不能說失敗的規則是'規則'。它有一條規則。我編輯了這個問題,因爲我不能在這些註釋中放置代碼 – Meindert 2010-12-06 08:16:38

回答

2

這可能是您的繼承層次設計較差的一個症狀。您試圖通過繼承來引入屬性的可變性(如果Rule的實例爲FailedRule,則它具有「失敗」)。繼承對於這種事情並不是很好。

我會說你應該使用組合(一個FailedRule有一個規則作爲源)或failed應該是Rule的一個實例的布爾屬性。

0

有沒有更簡單的方法。你正在這樣做。

很多時候,我會寫一個私有方法,這樣的事情:

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

這樣一來,我可以把它在這樣的構造,以及呈clone()方法,如果我需要定義一。

另一點是要知道你是否打電話super.setRuleCodethis.setRuleCode。顯然,這兩件事情做不同的事情取決於FailedRule重新定義setRuleCode

+0

-1,問題在於設計。看Mark Peters的回答。 – 2010-12-04 18:00:44

1

你看起來像一個合理的解決方案。如果任何規則可能是失敗的規則,那麼將其作爲Rule.isFailed()進行建模可能更合適。

編輯:失敗聽起來很像一個國家,而不是一個規則的變種。如果是這樣的話,Rule.isFailed()也會更喜歡。如果有真的沒有失敗的規則,我們可以模型爲:

  Rule 
     / \ 
     |  \ 
    FailableRule RuleC 
    / | 
RuleA RuleB 

嗯...是failable規則實際上是一個會犯錯誤規則? Gaawgh ...語言學。

+0

這是一個好主意,即使該方法只在`Rule`中包含`return false;`並且在`FailedRule`中被覆蓋爲`return true;`。 – 2010-12-03 16:05:27

+0

其實只是想到了另外一件事。 *失敗*聽起來很像一個規則的狀態,而不是一個規則的變體。如果是這樣的話,`FailedRule`不是很好哦。 – 2010-12-03 17:02:18

0

您不能將類轉換爲這樣的子類。它沒有任何意義,因爲它沒有任何子類的方法或變量。你做對的方式是正確的。

0

你這樣做的方式是正確的。我必須添加的唯一註釋是將複製代碼向下移動到規則本身。

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

使用該功能可將任何規則的FailedRule的方法:

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

(如果該規則已經是FailedRule,演員和返回它,否則用它來構建一個FailedRule