我对Java很新,所以我可能使用了不正确的术语。我试图优雅地将类扩展到一个新类,该类包含超类的多个实例。例如,假设我有一个班级
class Rose{
String smell;
Rose(String smell){this.smell=smell;}
void sniff(){ println("smells "+smell);}
}
我想要定义一个类......
class Bouquet extends Rose{
ArrayList<Rose> roses;
...
}
抱着多朵玫瑰。我的实际代码有20种方法,对于大多数方法,扩展方法是
void sniff(){
for( Rose one: roses) one.sniff();
}
有没有办法以这样的方式构建bouquet
,以至于我不需要明确定义这些愚蠢的循环?我没有与ArrayList
联系在一起,我甚至可以创建一个新的超级课程,如果这样做的话。但是,重要的是我可以向外部编写的方法发送bouquet
而不是rose
参数。
编辑: 哈哈,我觉得我的花比喻是一个很大的失败。 :)但你的输入是好的;你们已经澄清了我的想法了。
在我的实际问题中,有一组操作定义了如何将基类的实例一起添加到基类的新实例中。或许更好的比喻就是将一些小织物绳索扭成一根绳子。外部方法应该对绳索和绳索进行完全相同的处理。
看起来似乎extends
错了,还有其他任何建议吗?
答案 0 :(得分:1)
你真的不需要从玫瑰花束延长花束。只有在存在IS A关系时才会延伸,就像你有Flower类而Rose是Flower。但是花束不是玫瑰。理想情况下,你应该有一个花束类,有许多玫瑰。如果存在1:N的关系,那么您将不得不循环以获取单个项目。
答案 1 :(得分:1)
虽然我们可以按照自己的意愿实现任何目标,但是在抽象方面,你的班级设计中存在一些缺陷。
bouquet
是玫瑰的集合,所以它不应该延伸玫瑰,而是将它作为一个列在其中,无论如何。延伸上玫瑰并将其作为花束内的属性没有多大意义。相反,请创建一个名为Base class
的{{1}},然后创建Flower
以创建玫瑰。
在Flower Class中定义sniff函数,如果你需要那么在派生类中为extend
提供它。
答案 2 :(得分:1)
如果他没有介绍花类,我会投票给Shamims回答,这不是你问题的合理假设。
ArrayList <Rose> bouquet;
可能就是您所需要的一切。但你不能使用Bouquet作为玫瑰。 Bouquet.split();可能有意义,但Rose.split将是一个非常不同的东西。
is-a
问题让您大致了解,继承是否合理。它并不总是最终答案,但如果不合适,则不然。
答案 3 :(得分:1)
好吧,如果我错了,请纠正我,但对我而言,真正的问题似乎与鲜花或玫瑰无关,但作者只是想创造一个例子。
在实际应用中, 可以是一个关系,问题是有效的。例如,我在处理回调时不得不使用这种模式:你有一个MyCallback
接口,几个具体的实现,并且为了能够注册多个回调,你有一个MultipleMyCallback
类,它有一个MyCallback
列表委托所有来电。在每种方法中,你都会得到完全相同的循环。
我认为您可以通过Java动态代理执行此操作。或者,即使您使用像CGLIB这样的东西,您也会感到冒险,但我建议不要这样做。 接受这是Java的生活中的事实,并编写了20种方法并完成了它。
答案 4 :(得分:0)
没有很多黑客攻击,没有,没有简单的方法可以做到这一点。我强烈建议您阅读this。基本上,您只想使用继承来强制执行is-a
关系 - 这意味着您的子类在所有情况下都应该可替代您的基类。因此,自然的问题是,花束是玫瑰花,答案是否定的,不是,因此遗传不适合这项工作。
答案 5 :(得分:0)
在发布的答案的附录中,当命名你的方法时,如果用getSmell()替换sniff()方法会更好。