如何向类添加方法并在其超类的 for 样式循环中使用它们?
假设我有一个像这样的通用数组:
ArrayList<Fruit> fruits = new ArrayList<Fruit>();
然后我添加很多不同的水果,它们都扩展了水果类,并循环它们
for (Fruit f : fruits) {
}
如果水果是香蕉,我想检查它有多圆,所以..
for (Fruit f : fruits) {
if (f instanceof Bannana)
f.checkHowRoundBannanaIs();
}
我将有将 checkHowRoundBannaIs()
方法放在水果类中,即使水果可能不是香蕉,因为如果 f 不在水果类中,我就无法在 f 上使用该函数,否则我收到未定义的方法错误(或类似的错误) 那)。
这对于一两个方法来说是没问题的,但过了一段时间,它就会使类变得笨重且丑陋。所以我的问题是,如何向类添加方法并在其超类的 for 样式循环中使用它们?
Say I have a generic array like this:
ArrayList<Fruit> fruits = new ArrayList<Fruit>();
Then I add lots of different fruits, which all extends the class fruit, and loop through them
for (Fruit f : fruits) {
}
If the fruit is a banana, I want to check how round it is, so..
for (Fruit f : fruits) {
if (f instanceof Bannana)
f.checkHowRoundBannanaIs();
}
I will have to put the checkHowRoundBannnaIs()
method in the fruit class, even though the fruit may not be a banana, because I can't use the function on f if it isn't in the fruit class, otherwise I get a undefined method error (or something like that).
This is fine for one or two methods, but after a while it makes the class bulky and ugly. So my question is, how can I add methods to a class and use them in a for-style loop of its super class?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
简短的回答,你真的不能。
如果你想调用for循环体中的方法,
instanceof
和向下转换是我能想到的唯一方法:instanceof
和向下转换但通常被认为是不好的做法。为了避免这种情况,您可以实施访问者模式。以下是您需要执行的步骤:创建如下访问者界面:
让所有水果接受访问者:
创建一个对每种水果采取适当操作的访问者,并将其作为参数传递给
accept
列表中每种水果的方法:Short answer, you can't really.
If you want to call the methods in the body of the for-loop,
instanceof
and down-casting is the only way I can think of:Both
instanceof
and down-casting are usually considered bad practice though. To avoid it, you could implement the visitor pattern. Here are the steps you would need to take:Create a visitor interface like this:
Let all fruits accept a visitor:
Create a visitor that takes the appropriate action for each type of fruit, and pass it as argument to the
accept
method of each fruit in your list:与您尝试的最相似的技术是将
f
转换为Banana
:但我不确定这是否真的是您想要的。
The technique most similar to what you tried there would be to cast
f
as aBanana
:I'm not sure whether this is really what you want or not though.
您不必将
checkHowRoundBanannaIs()
放入Fruit
类中。一旦您知道f
是Banana
的实例,您就可以安全地将f
向下转换为Banana
类型。现在您已经有了一个Banana
实例,您可以调用任何Banana
特定方法(包括checkHowRoundBananaIs()
)。You don't have to put
checkHowRoundBanannaIs()
in theFruit
class. Once you know thatf
is an instance ofBanana
you can safely down-castf
to the typeBanana
. Now that you have aBanana
instance, you can call anyBanana
specific method (includingcheckHowRoundBananaIs()
.既然您已经在检查它是否是香蕉,您可以将其投射到香蕉上然后进行检查。
Seeing as you are already checking if it's a banana, you could cast it to a banana then do the check..
...这不是“其超类的 for 样式循环”。从逻辑上来说。
ASA,您执行
instanceof Bannana
时,必须导入Bannana
(尽管我想您想输入 Banana)。导入后,没有理由不将f
转换为Banana
。只要您这样做,您就可以访问Banana
的所有方法。简而言之,通常您不会执行
obj1 instanceof XXX
检查,除非您确实想将obj1
用作XXX
。当然,还有更好的方法,例如访问者模式(请参阅其他帖子)或将函数提取到超类。尽管我猜你已经接受了设计上存在一些问题并且你不想修复它。
... that is NOT a "for-style loop of its super class". Logically speaking.
ASA you do
instanceof Bannana
you have to importBannana
(though I suppose you wanted to type Banana instead). Once imported, there is no reason not to castf
toBanana
. One you do that you have access to all methods ofBanana
.In short, usually you don't do
obj1 instanceof XXX
check unless you actually want to useobj1
asXXX
.Of course there are better ways like the visitor pattern (see other posts) or extracting the function to super class. Though I guess you have accepted that you have some problem with design and you don't wanna fix it.