Reputation: 23
I have a java programming related problem. I have the following classes:
public abstract class Animal {
abstract void walk(AbstractWalkData abstractWalkData);
}
public class Mouse extends Animal{
@Override
void walk(AbstractWalkData abstractWalkData) {
System.out.println(abstractWalkData.getWalkSound());
System.out.println(abstractWalkData.getWalkSpeed());
System.out.println(((MouseWalkData) abstractWalkData).getMouseSpecific());
}
}
public class Tiger extends Animal{
@Override
void walk(AbstractWalkData abstractWalkData) {
System.out.println(abstractWalkData.getWalkSound());
System.out.println(abstractWalkData.getWalkSpeed());
System.out.println(((TigerWalkData) abstractWalkData).getTigerSpecific());
}
}
@Data
@SuperBuilder
public abstract class AbstractWalkData {
private String walkSound;
private int walkSpeed;
}
@Getter
@Setter
@ToString(callSuper = true)
@EqualsAndHashCode(callSuper = true)
@SuperBuilder
public class MouseWalkData extends AbstractWalkData {
private String mouseSpecific;
}
@Getter
@Setter
@ToString(callSuper = true)
@EqualsAndHashCode(callSuper = true)
@SuperBuilder
public class TigerWalkData extends AbstractWalkData {
private String tigerSpecific;
}
public class MainClass {
public static void main(String[] args) {
Animal mouse = new Mouse();
MouseWalkData mouseData = MouseWalkData.builder()
.walkSound("mouse walk sound")
.walkSpeed(5)
.mouseSpecific("mouse specific string")
.build();
mouse.walk(mouseData);
Animal tiger = new Tiger();
TigerWalkData tigerWalkData = TigerWalkData.builder()
.walkSound("tiger walk sound")
.walkSpeed(8)
.tigerSpecific("tiger specific string")
.build();
tiger.walk(tigerWalkData);
}
}
Note that I am using lombok to get rid of boilerplate code. Is there any way to get rid of the castings in the walk method of the Mouse and Tiger class? I would like to do something like this:
public class Mouse extends Animal{
@Override
void walk(MouseWalkData mouseWalkData) {
System.out.println(mouseWalkData.getWalkSound());
System.out.println(mouseWalkData.getWalkSpeed());
System.out.println(mouseWalkData.getMouseSpecific());
}
}
But i get a compiler error. Thank you all for any ideas.
Upvotes: 2
Views: 327
Reputation: 111
You can use 'instanceof' keyword to do that in Java. If you use concrete classes as parameter in your walk method as you mentioned, it is not polymorphism anymore. You should use an abstract class or interface in the parameter. Then pass any concrete child object to that method.
if(abstractWalkData instanceof MouseWalkData) {
System.out.println((MouseWalkData)abstractWalkData.getMouseSpecific());
}
Upvotes: 0
Reputation: 1034
That's how Java works but what you can do is start using generics in your code, for example, it will be something like this
abstract class Animal <T extends AbstractWalkData > {
abstract void walk(T walkData);
}
and then, for example, your mouse class will be something like this
public class Mouse extends Animal <MouseWalkData>{
@Override
void walk(MouseWalkData mouseWalkData) {
System.out.println(mouseWalkData.getWalkSound());
System.out.println(mouseWalkData.getWalkSpeed());
System.out.println(mouseWalkData.getMouseSpecific());
}
}
and it will work
to learn more about generics I recommend to read about them and how it helped to avoid some of java's boilerplate code https://www.baeldung.com/java-generics
Upvotes: 2