Java中的强制向下广播

Java中的强制向下广播,java,class,object,casting,downcast,Java,Class,Object,Casting,Downcast,我想强制一个不能向下投射的物体向下投射,我想知道正确的方法是什么。 用例是我有一个被检查的规则列表,以及将生成失败规则列表的内容。失败的规则是规则的子类。但是像 FailedRule FailedRule=(FailedRule)规则 将失败,因为规则对象不是FailedRule的实例 为了解决这个问题,我实例化了一个克隆 FailedRule FailedRule=新的FailedRule(规则) 我的FailedRule课程是这样的 public class FailedRule exten

我想强制一个不能向下投射的物体向下投射,我想知道正确的方法是什么。 用例是我有一个被检查的规则列表,以及将生成失败规则列表的内容。失败的规则是规则的子类。但是像
FailedRule FailedRule=(FailedRule)规则

将失败,因为规则对象不是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){
  ..

没有比这更简单的方法了。您这样做是正确的。

很多时候,我会编写一个私有方法,类似这样:

private void copyFromRule(Rule otherRule) { this.setRuleCode(otherRule.getRuleCode()); this.setType(otherRule.getType()); ... } 私有void copyFromRule(规则其他规则){ this.setRuleCode(otherRule.getRuleCode()); this.setType(otherRule.getType()); ... } 这样,我可以在这样的构造函数中调用它,如果需要定义一个方法,也可以在
clone()
方法中调用它


另一点是要知道您是在调用
super.setRuleCode
还是
this.setRuleCode
。显然,这两件事的作用不同,这取决于
FailedRule
是否重新定义了
setRuleCode

您所拥有的看起来是合理的解决方案。如果任何规则可能是失败的规则,那么将其建模为
rule.isFailed()
可能更合适

编辑:失败听起来很像一种状态,而不是规则的变体。如果是这样的话,
Rule.isFailed()
也将是首选。如果存在真正不会失败的规则,我们可以将其建模为:

           Rule
         /      \
         |       \
    FailableRule  RuleC
     /     |   
 RuleA    RuleB

嗯。。。一个失败的规则实际上是一个容易犯错的规则吗?Gaawgh。。。语言学。

你不能把一个类转换成这样的子类。它没有意义,因为它没有子类中的任何方法或变量。这可能是继承层次结构设计薄弱的一个症状。您试图通过继承引入属性的可变性(如果是
FailedRule
的实例,则
规则已“失败”)。继承对这类事情不是很好


我想说您应该使用组合(FailedRule有一个规则作为源),或者
failed
应该是
规则的一个实例的布尔属性,您这样做是正确的。我要添加的唯一注释是将复制代码向下移动到规则本身

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

使用将任何规则转换为失败规则的方法:

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

(如果规则已经是一个
FailedRule
,则强制转换并返回它,否则使用它来构造一个
FailedRule

我想知道你如何在一个不能强制向下转换的对象上强制向下转换。告诉我们你真正想做什么。我想我做了:-)。我循环浏览一个规则列表并返回一个失败的规则列表。检查过程会根据规则返回相当数量的信息,包括失败原因、失败时间以及失败方式。马克的回答是正确的,我的设计是错误的,我不能说失败的规则就是失败的规则。它“有一个”规则。我编辑了这个问题,因为我不能在这些注释中添加代码。这是一个好主意,即使该方法只包含
returnfalse打开
规则
,并在
FailedRule
中重写为
返回true。实际上只是想到了另一件事。失败听起来很像规则的状态,而不是规则的变体。如果是这样的话,
FailedRule
就不是一个好的oo。不过,问题是关于降级,而不是评估他的设计选择。一秒钟也不要同意。很明显,出现的问题中有很大一部分是关于人们不了解技术或他们正在处理的问题。如果我看到明显的遗漏或有问题的想法,我显然会尽力帮助解决整个问题,尽管问题是关于一个具体的问题。这就是为什么用户应该提供尽可能多的上下文。提交此问题的用户可能永远不会回来查看它。大多数来这里的人都会寻找悲观情绪。因此,我们应该专注于回答问题,而不是评估用户的体验,因为用户懒得回来澄清。好的,FailedRule不是规则的子类,因为失败的规则不是规则。FailedRule类是将规则作为属性的失败规则;failedRule.setRule(规则);failedRule.setReason(reason)等@Meindert:我不确定这是不是一个好方法,因为我没有太多的上下文。
FailedRule
甚至还提供了哪些额外方面?规则失败后,其内部状态会发生什么变化?如果是我,我会说“如果规则出现在失败规则列表中,那么它就失败了。”将规则的概念与其执行结果分开似乎是合乎逻辑的。就像你不会把一辆汽车在最后一场比赛中得分的位置储存在汽车本身一样;你有一个<代码> RraceCordRD 引用了汽车。如果构图是这样的话,我会考虑改名<代码> FailedRule < /代码>。这不是规则,是吗?这只是规则失败的上下文/记录。我会称之为
RuleFailure
或类似的东西。在用户眼中,这是一个失败的规则列表。。。但是你是对的,我将失败的规则存储在一个名为RuleFail的表中。谢谢,这是一种更干净的克隆方法。我正在寻找一种“自动克隆”方法,它可以将ruletopy的所有属性都放在“this”中。但我同意马克的回答,我的设计有缺陷