Java - Создать объект Card без enum, с проверкой типа во время компиляции - PullRequest
0 голосов
/ 06 мая 2020

Я хочу создать класс, который предоставит мне карту, т.е.

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

Я хочу, чтобы класс проверял во время компиляции , имеет ли карта тип лопаты, сердце , алмаз или дубинка, а если нет - выдаст ошибку и не позволит мне скомпилировать. Класс должен НЕ использовать enum

Изменить: этот вопрос задается исключительно с целью понять, как можно было бы ответить на такой вопрос в эпоху pre-enum. Мне задали этот вопрос во время собеседования пару лет go

Ответы [ 3 ]

4 голосов
/ 06 мая 2020

Обновление: нет хорошего способа принудительно установить значение от 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 обрабатывало перечисления именно так: с использованием предустановленного списка целых чисел, которые были очень подвержены ошибкам и не могли быть легко реализованы. Было мрачное время, давайте не будем go назад :)

1 голос
/ 06 мая 2020

Java не имеет функций, позволяющих new Card(4) компилировать нормально, а new Card(5) вызывать сбой во время компиляции. Невозможно сделать.

Очевидно, что здесь можно использовать перечисления. Если у вас есть какое-то безумное требование, которое мешает вам его использовать, что ж, сделайте обычное дело, столкнувшись с сумасшедшими требованиями: примите, что стиль кода и инструменты будут страдать.

Вы можете создать подтипы для каждого костюма ( как показано в ответе @Mike), но это не совсем подходит. подклассы предназначены для представления различного поведения, и в черве против лопаты нет ничего особенного.

Просто чтобы все было понятно, позвольте мне повторить: *.

0 голосов
/ 06 мая 2020

Спасибо всем за ваши ответы, и спасибо @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 за то, что дал мне ответ Мне удалось описать

...