0

我想创建一个可以为我提供卡片的课程,即

Card c = new Card(1) // where the builder should get values 1 to 4, representing 1=spade, 2=heart, 3=diamond, 4=clubs 
c.getType() // spade

我希望班级在编译期间检查卡片的类型是否为黑桃、红心、钻石或梅花,如果不是 - 它会引发错误并且不会让我编译。该类不应使用枚举

编辑:问这个问题的目的仅仅是为了了解在预枚举时代人们将如何回答这类问题。几年前的一次求职面试中,我被问到了这个问题

4

3 回答 3

4

更新:没有很好的方法来强制值在 1 和 4 之间(也许使用一些自定义的复杂编译时注释会起作用,但我对此表示怀疑),正如已经指出的那样。这只是强制Card在不使用枚举的情况下不允许实例化的一种方法,并且value由于每个子类都设置了自己的值,因此它隐式地保持在 1 和 4 之间。

一种方法是进行Card抽象(也可以使用接口):

public abstract class Card {

    // should be 1 to 4
    protected int value;

    public int getValue() {
        return value;
    }
}

然后为每种类型创建子类:

public class Spade extends Card {
    public Spade() {
        this.value = 1;
    }
}

public class Heart extends Card {
    public Spade() {
        this.value = 2;
    }
}

如果有人试图Card直接创建一个,这将引发编译时错误:

Card c = new Card();

在枚举存在之前,这是大多数 Java 代码处理枚举的方式:使用一个很容易出错且不易执行的预设整数列表。那是一段黑暗的时光,我们不要回去了:)

于 2020-05-06T16:47:31.107 回答
1

Java 没有使new Card(4)编译正常和new Card(5)导致编译时失败的特性。做不到。

这里使用的显而易见的东西是枚举。如果你有一些疯狂的需求阻止你使用它,那么在面对疯狂的需求时做通常的事情:接受代码风格和工具将会受到影响。

您可以为每件西装制作子类型(如@Mike 的回答所示),但这并不适合。子类旨在代表不同的行为,Hearts 与 Spade 没有什么不同。

为了让我们清楚,让我重复一遍:你所要求的是不可能的

于 2020-05-06T16:54:24.640 回答
0

谢谢大家的回答,也谢谢@JoachimSauer,我检查了你给我的关于pre 1.5和Type Safe Enum Pattern的链接,我设法得到了我喜欢的答案:

class Solution {

    public static class Card {

        public static Card SPADE = new Card();
        public static Card HEART = new Card();
        public static Card DIAMOND = new Card();
        public static Card CLUB = new Card();

        public Card() {
        }

    }
    public static void main(String[] args) {
        Card c = new Card().SPADE; // Only Spade, Heart, Diamond, Club can be "manufactured"
    }
}

我知道这不是我所描述的,但只有在阅读后我才明白我到底在想什么

当然感谢@Mike 给了我我设法描述的答案

于 2020-05-06T17:47:20.773 回答