Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/oop/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 根据2个输入参数的子类型更改方法行为_Java_Oop_Design Patterns - Fatal编程技术网

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

Java 根据2个输入参数的子类型更改方法行为,java,oop,design-patterns,Java,Oop,Design Patterns,我试图创建一个干净的类设计的纸牌游戏。 我想比较两张卡片并返回“值”最高的那张 我有一个抽象卡片类和从中继承的两个类: public abstract class Card { ... //common method public int getCardValue() { return this.cardValue; } //comparison methods public abstract Card compare(Colo

我试图创建一个干净的类设计的纸牌游戏。 我想比较两张卡片并返回“值”最高的那张

我有一个抽象卡片类和从中继承的两个类:

    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"
我需要访问整个子类接口来执行我的每个比较,但也要保持比较调用“generic”(通过卡超类)

如果可能,我希望避免使用
instanceOf
指令或反射


谢谢,

如果可能的话,我会在基类上定义一个抽象方法,让子类提供它们的绝对值。然后,您可以使基类
具有可比性
,并实现使用此值的
compareTo()
方法。价值甚至不需要公开披露

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

如果可能的话,我会在基类上定义一个抽象方法,让子类提供它们的绝对值。然后,您可以使基类
具有可比性
,并实现使用此值的
compareTo()
方法。价值甚至不需要公开披露

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

所以我找到了一种使用访问者模式的方法:

public interface ICardVisitor {
    public Card visit(TrumpCard card);
    public Card visit(ColoredCard card);
    public void setSecondCard(ColoredCard card);
    public void setSecondCard(TrumpCard card);
}

public class ComparisonVisitor implements ICardVisitor {
    private TrumpCard trumpCard;
    private ColoredCard coloredCard;
    ...
    //contains comparison logic & instances of card subtypes
}
我还必须在我的抽象卡类中添加一个额外的函数(除了经典的accept(Visitor v)方法):

public abstract void setThisCardAsParameter(ICardVisitor v);
在具体的卡实现中:

public Card accept(ICardVisitor visitor) {
    return visitor.visit(this);
}

public void setThisCardAsParameter(ICardVisitor v) {
    v.setSecondCard(this);
}
通过这种方式,比较类知道每张卡的每个子类型,因此他可以访问给定子类的所有特定方法。 电话如下所示:

public static void main(String [] args) {
    ICardVisitor cmp = new ComparisonVisitor();
    Card c = new TrumpCard(1);
    Card c2 = new ColoredCard(CardTypes.SPADES,1);
    ICardVisitor cmp = new ComparisonVisitor();
    c.setThisCardAsParameter(cmp);
    Card winningCard = c2.accept(cmp);
}

如果设计不好或者可以改进,请告诉我

所以我找到了一种使用访问者模式的方法:

public interface ICardVisitor {
    public Card visit(TrumpCard card);
    public Card visit(ColoredCard card);
    public void setSecondCard(ColoredCard card);
    public void setSecondCard(TrumpCard card);
}

public class ComparisonVisitor implements ICardVisitor {
    private TrumpCard trumpCard;
    private ColoredCard coloredCard;
    ...
    //contains comparison logic & instances of card subtypes
}
我还必须在我的抽象卡类中添加一个额外的函数(除了经典的accept(Visitor v)方法):

public abstract void setThisCardAsParameter(ICardVisitor v);
在具体的卡实现中:

public Card accept(ICardVisitor visitor) {
    return visitor.visit(this);
}

public void setThisCardAsParameter(ICardVisitor v) {
    v.setSecondCard(this);
}
通过这种方式,比较类知道每张卡的每个子类型,因此他可以访问给定子类的所有特定方法。 电话如下所示:

public static void main(String [] args) {
    ICardVisitor cmp = new ComparisonVisitor();
    Card c = new TrumpCard(1);
    Card c2 = new ColoredCard(CardTypes.SPADES,1);
    ICardVisitor cmp = new ComparisonVisitor();
    c.setThisCardAsParameter(cmp);
    Card winningCard = c2.accept(cmp);
}

如果设计不好或者可以改进,请告诉我

不应该只接受两张
卡片
compare
吗?不,因为每次比较我都需要访问我的子类的具体方法。那么,你设计类的方式就有问题了。这将有助于了解相关部分是如何实现的,以及您希望如何比较它们。换句话说,
compare
方法不必知道如何根据两张卡的类型进行比较。它应该是
类型,公开
比较器
方法,并且它应该能够自己处理不同类型的卡。好的,感谢您的反馈!我已经在我的原始帖子中添加了一些关于我的课程设计的附加信息。我会尝试你的设计建议,并保持这个线程更新!我做了你推荐的。似乎我必须在我的每个卡片子类中实现每个“compare(CardSubtype card)”方法!不应该只接受两张
卡片
compare
吗?不,因为每次比较我都需要访问我的子类的具体方法。那么,你设计类的方式就有问题了。这将有助于了解相关部分是如何实现的,以及您希望如何比较它们。换句话说,
compare
方法不必知道如何根据两张卡的类型进行比较。它应该是
类型,公开
比较器
方法,并且它应该能够自己处理不同类型的卡。好的,感谢您的反馈!我已经在我的原始帖子中添加了一些关于我的课程设计的附加信息。我会尝试你的设计建议,并保持这个线程更新!我做了你推荐的。似乎我必须在我的每个卡片子类中实现每个“compare(CardSubtype card)”方法!谢谢,但是这样不行。在每种情况下,我都需要使用特定的子类方法来比较卡片-我不能简单地比较valuesOkay,因此没有办法根据两个卡片子类型自动分配到给定的比较方法?使用“Kind”enum的解决方案很容易实现,应该可以工作,但我觉得它并不好:它是一个重复的信息,因为每个子类总是有一个不同的“Kind”(等价关系)。正如我提到的,有一种方法可以在没有
instanceof
的情况下进行调度,您可以使用Visitor模式将重载方法(每种卡类型一个)分派给访问者。但我从来没有觉得它特别优雅。谢谢,但这行不通。在每种情况下,我都需要使用特定的子类方法来比较卡片-我不能简单地比较valuesOkay,因此没有办法根据两个卡片子类型自动分配到给定的比较方法?使用“Kind”enum的解决方案很容易实现,应该可以工作,但我觉得它并不好:它是一个重复的信息,因为每个子类总是有一个不同的“Kind”(等价关系)。正如我提到的,有一种方法可以在没有
instanceof
的情况下进行调度,您可以使用Visitor模式将重载方法(每种卡类型一个)分派给访问者。但我从未觉得它特别优雅。