我正在尝试创建一款具有简洁类设计的纸牌游戏。 我想比较两张卡并返回“值(value)”最高的一张。
我有一个抽象卡类和从它继承的 2 个类:
public abstract class Card {
...
//common method
public int getCardValue() { return this.cardValue; }
//comparison methods
public abstract Card compare(ColoredCard card);
public abstract Card compare(TrumpCard card);
}
public class ColoredCard extends Card {
//specific attribute
private Color cardColor;
...
//specific method
public Color getColor() { return this.cardColor; }
public Card compare(ColoredCard card) {
if(this.getColor() == card.getColor())
return this.getCardValue() > card.getCardValue() ? this : card;
return this;
}
public Card compare(TrumpCard card) {
return card;
}
}
public class TrumpCard extends Card {
...
public Card compare(ColoredCard card) {
return this;
}
public Card compare(TrumpCard card) {
return this.getCardValue() > card.getCardValue() ? this : card;
}
}
但每当我尝试时它仍然会抛出错误:
Card c = new ColoredCard(5);
Card c2 = new TrumpCard(1);
c.compareTo(c2); //error method compareTo not applicable to type of argument "Card"
我需要访问整个子类接口(interface)来进行每次比较,但也要保持比较调用“通用”(通过 Card 父类(super class))。
如果可能的话,我想避免使用 instanceOf
指令或反射。
谢谢,
最佳答案
如果可能的话,我会在基类上定义一个抽象方法,让子类提供它们的绝对值。然后,您可以使基类Comparable
并实现使用该值的compareTo()
方法。该值(value)甚至不需要公开披露。
public static abstract class Card implements Comparable<Card> {
@Override
public int compareTo(Card other) {
return Integer.compare(this.value(), other.value());
}
protected abstract int value();
}
public static class ColoredCard extends Card {
@Override
protected int value() {
return 1;
}
}
public static class TrumpCard extends Card {
@Override
protected int value() {
return 10;
}
}
public static void main(String... args) throws Exception {
System.out.println(new TrumpCard().compareTo(new ColoredCard()));
System.out.println(new ColoredCard().compareTo(new TrumpCard()));
}
打印:
1
-1
如果这不好,那么您将需要使用 instanceof
或类似 Visitor pattern 的东西。或者重新考虑设计。
例如,您可以重新设计,这样您就可以将卡片类型保存为字段(可能使用枚举),而不是为每张卡片设置一个单独的类。然后,当您比较两张卡时,您可以比较两张卡的类型,不需要使用 instanceof
并且可以合并您喜欢的任何逻辑。
例如
public static enum Kind {
COLORED,
TRUMP;
}
public static class Card {
private final Kind kind;
public Card(Kind kind) {
this.kind = kind;
}
public Kind kind() {
return kind;
}
}
public static void main(String... args) throws Exception {
Card trumpCard = new Card(Kind.TRUMP);
Card coloredCard = new Card(Kind.COLORED);
int i = compare(trumpCard, coloredCard);
}
public static int compare(Card card, Card other) {
if (card.kind().equals(other.kind())) {
return 0;
}
if (card.kind().equals(Kind.TRUMP)) {
return 1;
}
return -1;
}
关于java - 根据 2 个输入参数的子类型更改方法行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59106643/