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

Java中具有子类型参数的多态性,java,parameters,polymorphism,Java,Parameters,Polymorphism,我有一个与java编程相关的问题。 我有以下课程: 公共抽象类动物{ 抽象void walk(AbstractWalkData AbstractWalkData); } 公共类鼠标扩展到动物{ @凌驾 void walk(AbstractWalkData AbstractWalkData){ System.out.println(abstractWalkData.getWalkSound()); System.out.println(abstractWalkData.getWalkSpeed()

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

公共抽象类动物{
抽象void walk(AbstractWalkData AbstractWalkData);
}
公共类鼠标扩展到动物{
@凌驾
void walk(AbstractWalkData AbstractWalkData){
System.out.println(abstractWalkData.getWalkSound());
System.out.println(abstractWalkData.getWalkSpeed());
System.out.println(((MouseWalkData)abstractWalkData.getMousSpecific());
}
}
公营虎类动物{
@凌驾
void walk(AbstractWalkData AbstractWalkData){
System.out.println(abstractWalkData.getWalkSound());
System.out.println(abstractWalkData.getWalkSpeed());
System.out.println(((TigerWalkData)abstractWalkData.getTigerSpecific());
}
}
@资料
@超级建筑商
公共抽象类AbstractWalkData{
私人弦乐;
私人步行速度;
}
@吸气剂
@塞特
@ToString(callSuper=true)
@EqualsAndHashCode(callSuper=true)
@超级建筑商
公共类MouseWalkData扩展了AbstractWalkData{
专用字符串mousspecific;
}
@吸气剂
@塞特
@ToString(callSuper=true)
@EqualsAndHashCode(callSuper=true)
@超级建筑商
公共类TigerWalkData扩展了AbstractWalkData{
私有字符串虎特异性;
}
公共类主类{
公共静态void main(字符串[]args){
动物老鼠=新老鼠();
MouseWalkData mouseData=MouseWalkData.builder()
.walkSound(“鼠标行走声音”)
.步行速度(5)
.mousspecific(“鼠标特定字符串”)
.build();
小鼠行走(mouseData);
动物虎=新虎();
TigerWalkData TigerWalkData=TigerWalkData.builder()
.步行声(“老虎步行声”)
.步行速度(8)
.老虎专用(“老虎专用字符串”)
.build();
虎步(虎步数据);
}
}
注意,我使用lombok来摆脱样板代码。有没有办法摆脱鼠标和老虎类的行走方法中的铸件? 我想这样做:

公共类鼠标扩展动物{
@凌驾
无效漫游(MouseWalkData MouseWalkData){
System.out.println(mouseWalkData.getWalkSound());
System.out.println(mouseWalkData.getWalkSpeed());
System.out.println(mouseWalkData.getmousspecific());
}
}
但是我得到了一个编译器错误。
谢谢大家的建议。

您可以使用'instanceof'关键字在Java中实现这一点。如果您在您提到的walk方法中使用具体类作为参数,那么它就不再是多态性了。您应该在参数中使用抽象类或接口。然后将任何具体的子对象传递给该方法

if(abstractWalkData instanceof MouseWalkData) {
   System.out.println((MouseWalkData)abstractWalkData.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());

    }
}
抽象类动物{
抽象的void-walk(T-walkData);
}
然后,例如,你的鼠标类将是这样的

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

    }
}
公共类鼠标扩展动物{
@凌驾
无效漫游(MouseWalkData MouseWalkData){
System.out.println(mouseWalkData.getWalkSound());
System.out.println(mouseWalkData.getWalkSpeed());
System.out.println(mouseWalkData.getmousspecific());
}
}
它会起作用的


要了解有关泛型的更多信息,我建议您阅读有关泛型的内容,以及泛型如何帮助避免一些java样板代码

谢谢您的回答。确切地说,如果我使用具体类型作为参数,我将丢失多态性。不管怎样,instanceof与casting相比有什么好处?instanceof是指定类型(类或子类)的实例,通常在casting之前,但通常你应该避免使用它们,因为这会让你的代码有异味,如果你绝对需要的话,可以使用它们。我的答案是完成你的代码。如果不想使用instanceof和casting,可以使用上面提到的泛型。但是如果你使用,你应该确定它的具体类,然后再施法。你似乎违反了,更多信息请参阅。@Sweeper我不这么认为。我的所有子类实例都可以替换父类实例。你能解释一下你认为我在哪里破坏了LSP吗?@GeordiLaForge注意到,实际上没有什么能阻止你制作一个
类鼠标扩展动物。