繁体   English   中英

Java中带有子类型参数的多态性

[英]Polymorphism with parameters of child types in Java

我有一个与 Java 编程相关的问题。 我有以下课程:

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);
    }
}

请注意,我正在使用 lombok 来摆脱样板代码。 有什么办法可以去掉 Mouse 和 Tiger 类的 walk 方法中的铸件吗? 我想做这样的事情:

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

    }
}

但我收到编译器错误。 谢谢大家的任何想法。

这就是 Java 的工作方式,但您可以做的是在代码中开始使用泛型,例如,它会是这样的

abstract class Animal <T extends AbstractWalkData > {
    abstract void walk(T walkData);
}

然后,例如,您的鼠标类将是这样的

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

    }
}

它会起作用

要了解有关泛型的更多信息,我建议阅读它们以及它如何帮助避免某些 java 样板代码https://www.baeldung.com/java-generics

您可以使用 'instanceof' 关键字在 Java 中执行此操作。 如果您像您提到的那样在 walk 方法中使用具体类作为参数,则它不再是多态性。 您应该在参数中使用抽象类或接口。 然后将任何具体的子对象传递给该方法。

if(abstractWalkData instanceof MouseWalkData) {
   System.out.println((MouseWalkData)abstractWalkData.getMouseSpecific());
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM