java - 根据 2 个输入参数的子类型更改方法行为

标签 java oop design-patterns

我正在尝试创建一款具有简洁类设计的纸牌游戏。 我想比较两张卡并返回“值(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/

相关文章:

java - 社交身份验证 - 链接在 OAuth 2 中不起作用

PHP 面向对象 : Avoid Singleton/Static Methods in Domain Model Pattern

c++ - 我应该更喜欢点 (.) 还是箭头 (->) 运算符来访问 C++ 中的指针成员?

java - 如何在 OOP 中为 API 或框架设计一个健壮的 Status 类?

java - tomcat resteasy单例

C# - 这是一个 'good' 数据访问模式吗?它叫什么?

java - AVRO Mapreduce-ClassCastException:org.apache.avro.generic.GenericData $ Record无法转换为Avro

java - 具有扩展枚举泛型的通用接口(interface)

java - Android - 1 除以 2 = 0

oop - 在应用程序中与 Elastic 通信的最佳实践