Java - подстановочный знак enum - PullRequest
1 голос
/ 25 марта 2011

У меня проблемы с реализацией функции Java.

У меня есть список Sensors.У меня их разные, все они расширяют базовый класс Sensor.У меня есть некоторые абстрактные функции в базовом классе, и я хочу, чтобы эти функции принимали Enum в качестве параметра.Проблема заключается в том, что Enum уникален для каждого подкласса, и поэтому я не могу объявить Enum в базовом классе.

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


private Vector<Sensor> sensors;

public abstract class Sensor {  
    public Sensor() {}  
    public abstract int getParam(Enum param);  
    public abstract void setParam(Enum param, int value);  
}

public class TempSensor extends Sensor {
    // Parameter names
    public static enum TEMP_PARAMETERS{ PARAM_ALARM_HI, PARAM_ALARM_LO }

    public TempSensor() {}

    @Override
    public int getParam(TEMP_PARAMETERS param) {
            // Will do some stuff here
            return 0;
    }

    @Override
    public void setParam(TEMP_PARAMETERS param, int value) {
            // Will do some stuff here
    }
}

Если различные Enums реализуют интерфейсЯ могу использовать интерфейс в качестве типа параметра в абстрактных методах, но затем я могу передать в качестве параметра перечисления, которые не принадлежат соответствующему классу.Есть ли способ избежать этого?

Ответы [ 3 ]

3 голосов
/ 25 марта 2011

Похоже, вы хотите противоречивых вещей.Весь смысл использования полиморфизма заключается в использовании принципа замены .Если вы хотите иметь иерархию классов и быть уверенным, что правильный тип введен для правильного объекта, вы можете использовать фабричный шаблон.Я настоятельно рекомендую против наследования на Enums;Java не справляется с этим хорошо.

2 голосов
/ 25 марта 2011

Вы на правильном пути.Предполагая, что у вас есть интерфейс маркера с именем MyEnumTypeInterface, просто используйте различные перечисления для реализации этого интерфейса.Затем используйте MyEnumTypeInterface в качестве типа формального параметра для ваших методов, которые принимают перечисление.Однако вам необходимо убедиться, что вы получаете перечисление, которое реализует MyEnumTypeInterface, а не просто любой другой класс, который реализует MyEnumTypeInterface:

public <E extends Enum<E> & MyEnumTypeInterface>void getParam(E e)

Это гарантирует, что формальный параметр - enumи что он реализует MyEnumTypeInterface;Метед не примет в качестве параметра другой класс, который также реализует MyEnumTypeInterface.

Так что ваши классы в конечном итоге будут выглядеть так:

public interface MyEnumTypeInterface {
}

public abstract class Sensor {  
    public Sensor() {}  
    public abstract <E extends Enum<E> & MyEnumTypeInterface>int getParam(E param);  
    public abstract <E extends Enum<E> & MyEnumTypeInterface>void setParam(E param, int value);  
}

public enum TempEnum extends MyEnumTypeInterface {
    PARAM_ALARM_HI, 
    PARAM_ALARM_LO
}


public class TempSensor extends Sensor {

    public TempSensor() {}

    @Override
    public<E extends Enum<E> & MyEnumTypeInterface>int getParam(E param) {
            return 0;
    }

    @Override
    public <E extends Enum<E> & MyEnumTypeInterface>void setParam(E param, int value) {
            // Will do some stuff here
    }
}
0 голосов
/ 25 марта 2011

То есть вы хотите, чтобы каждый Sensor работал с определенным типом параметра?Это означало бы сделать Sensor универсальным.

public abstract class Sensor<P extend Enum<P>> {  
    public Sensor() {}  
    public abstract int getParam(P param);  
    public abstract void setParam(P param, int value);  
}

Возможно, у вас больше проблем с дизайном.Исправление этих ошибок может отменить требование получения и установки.

...