如何在JAVA中使用带有compareTo的双分派?
Java初学者。。。我对如何在JAVA中将双重分派(和访问者模式)与compareTo方法一起应用感到有点困惑
示例场景:
假设我有一个Animal
接口,我将在其中实现4个类:狗、猫、老鼠和兔子
我想确定,如果我对这些动物的列表进行排序,鼠标<;小兔子<;猫<;狗
想知道我将如何实现它
现在我能想到的最好办法就是在比较中加入一些if-elseif。。。但这显然不是派遣。。。
谢谢
Animal
接口
package animals;
public interface Animal extends Comparable<Animal> {
void makeSound();
}
Dog
类
package animals;
public class Dog implements Animal {
@Override public void makeSound() {
System.out.println("wow");
}
@Override public int compareTo(Animal o) {
return 0; // ???? if (o instanceof Cat) {return 1}
}
}
# 1 楼答案
我担心visitor模式在这里不适用,因为它需要两个接口(父类型/类):visitor和Element。但您只有一个父类型
在您的例子中,您只需创建一个整数属性
size
,并将其用于比较# 2 楼答案
这个Answer by Barskov是正确和明智的。对于您的场景来说,最好的解决方案可能是简单地向四个类中的每个类添加一个最终的静态
relativeSize
字段为了好玩,让我们看看另一种使用Java特性的方法
密封类
新的sealed classes特性是Java 16中的previewed,这使得这个过程更简单
当所有允许的具体类型在编译时都已知时,可以将该事实告知编译器。将类或接口标记为
sealed
。用实现/扩展类的名称添加permits
。然后,编译器执行您的声明,验证所有指定类和仅指定类是否扩展/实现了密封类/接口我们也使用default methods。现代Java允许接口包含代码,如果实现类缺少
default
方法,则可以运行该方法下面是一些示例代码
注意关键词:
sealed
、permits
和default
具体的类如下所示。我们在这里使用
record
,其中编译器隐式地创建构造函数、getter、equals
&hashCode
和toString
。你也可以使用传统的课程看看它的实际效果
跑步的时候
不要仅仅使用内置的类比较
compareTo
上面的代码很有效,而且很有趣。但在实际工作中,您不应该这样做,也不应该构建这样一个
compareTo
实现,它只查看类阅读^{} Javadoc。您将看到关于
compareTo
方法应如何与equals
保持一致的讨论不考虑两个{{CD17>}实例是相等的,因为它们都是同一个类。您还可以比较它们的内容和包含的数据的状态。在
record
的情况下,equals
(和hashCode
)的默认实现检查每个成员字段。在传统类中,您可以实现类似的功能,检查id
字段或name
字段或类似的字段如果您确实希望仅按类进行比较,请使用外部^{} ,而不是在内部实现^{} 。比如:
或者使用更短的lambda语法