Foreach through various objects, but is it possible to implement the same interface all?

Suppose I have it

interface Movable {//some stuff} 

And I have

 class Car implements Movable {//some stuff} 

And also maybe with me

 class Bike implements Movable {//some stuff} 

I noticed that if I had this:

 ArrayList<Movable> movableThings = new ArrayList<Movable>(); movableThings.add(some kind of Car) movableThings.add(some kind of Bike) movableThings.add(some kind of Bike) 

It can be called:

 for(Movable m: movableThings) 

But if I call it, I get incompatible types:

 for(Bike b: movableThings) 

Can someone explain and maybe suggest a better way? I know I can use foreach Movable m: movableThings and then use instanceof to test bikes, but is there any other way?

Edit: ok thanks for clarifying the guys ... so I think I either use instanceof or redesign my game

+6
source share
4 answers

I would not recommend using instanceof . The whole point of the two types implementing the common interface is that when using the interface, the consumer code should not concern a specific implementation. I am very suspicious when I see instanceof outside equals() .

Use polymorphic dispatching instead of instanceof if you want different types of behavior to be executed from different implementations:

 interface Movable { void move(); } class Bike implements Movable { public void move() { // bike-specific implementation of how to move } } class Car implements Movable { public void move() { // car-specific implementation of how to move } } 

For each type, an implementation-specific method will be called:

 for (Movable m : movableThings) { m.move(); } 

If you only want to iterate over Bike types, create a collection consisting of only Bike s:

 List<Bike> bikes = new ArrayList<Bike>(); // etc... for (Bike bike : bikes) { // do stuff with bikes } 

NB You should almost always declare a collection as a List (interface), not an ArrayList (interface implementation).

see also

If you have not already done so, you can also read the Java Tutorials: Interfaces and Inheritance .

+7
source

You need to use instanceof . You can write a filter function to make it reusable.

This is probably the case when you want to use inheritance so that the same method is called on both classes in the same way.

+2
source

Since your ArrayList is defined as

  ArrayList<Movable> 

the get method of your ArrayList will return a Movable type. You need to cast it manually if you are sure about the type of runtime (use instanceof to check it).

 for(Movable m: movableThings){ if (m instanceof Car){ Car car = (Car)m; } } 
+2
source

Here Google Guava or a similar collection library can be really useful. You will find many other applications for this, therefore it is not difficult to justify, including in your project.

In Guava:

 for (Bike bike : Iterables.filter(movableThings, Bike.class) ) { //now you only have bikes } 
0
source

Source: https://habr.com/ru/post/890169/


All Articles