Как вы объявляете абстрактный метод, чтобы тип параметра (класс) всегда был классом детей? - PullRequest
4 голосов
/ 28 июня 2011

РЕДАКТИРОВАТЬ: см. Внизу

Прежде всего, я искал ответ, прежде чем спрашивать его, но, как вы можете видеть из заголовка, я понятия не имею, как это называется, и я буду редактировать вопрос, когда смогу. Пожалуйста, прости меня за это.

У меня есть следующий абстрактный класс:

public abstract class ValidableDTO implements Serializable {
    public abstract boolean isValid();
    public abstract boolean equals(ValidableDTO compared);
    // EDIT : new solution
    public abstract <T extends ValidableDTO> boolean equals(T compared);
}

Я бы хотел получить похожую реализацию:

public class MyDTO extends ValidableDTO {

    private String myValue; //With a getter and setter of course

    public MyDTO() {
        // ...
    }

    @Override
    public boolean isValid() {
        return true; // Validation
    }

// __________ LOOK AT THE FOLLOWING PARAMETER TYPE __________­­
    @Override
    public boolean equals(MyDTO compared) {
        return true; // Comparison
    }
}

Самое близкое, что я мог получить, это

@Override
public boolean equals(ValidableDTO compared) {
    boolean isEqual = false;

    if (compared instanceof MyDTO) {
        isEqual = getValue().equals(compared.getValue());
    }

    return isEqual;
}

Я пытался использовать public abstract boolean equals(<? extends ValidableDTO> compared);, но это не работает.

Возможно ли даже возможно (это должно быть ИМО)? Спасибо за ваше время и ... я до сих пор не знаю, как описать это в 1 предложении ... (смеется)

С уважением. - я

На шаг ближе, благодаря пользователю: aps!

следующие работы в определении класса Abstract (ValidableDTO)

public abstract <T extends ValidableDTO> boolean equals(T compared);

__ НО __

реализация в MyDTO все еще не в порядке, и, в конце концов, это точно так же, как использование моего решения «if instanceof», поскольку ValidableDTO является абстрактным классом и ДОЛЖЕН наследоваться.

Как это выглядит сейчас, используя решение Aps:

public <T extends ValidableDTO> boolean equals(T compared) { ... }

Мне все еще нужно проверить, является ли это экземпляром MyDTO ...

НА СТОРОНЕ ПРИМЕЧАНИЕ: Google, похоже, не знает, настоящие ли слова "Validable" или "Validatable" ... какое из них правильное?

1 Ответ

9 голосов
/ 28 июня 2011

Этого можно добиться, используя обобщенные формы в объявлении сигнатуры вашего метода в абстрактном классе:

public abstract class ValidableDTO<T extends ValidableDTO> implements Serializable {
    public abstract boolean isValid();
    public abstract boolean equals(T compared);
}

public class MyDTO extends ValidableDTO<MyDTO> {

    @Override
    public boolean isValid() {
        ...
    }


    @Override
    public boolean equals(MyDTO compared) {
        return true; // Comparison
    }
}

[EDIT]

Краткое изложение комментариев ниже:

Что касается стиля и принципов кодирования Java, было бы более разумно переопределить метод public boolean equals(Object other) по умолчанию вместо использования обобщенной конструкции, чтобы попытаться ограничить тип параметра. Стандартная практика для равенства (...) заключается в использовании оператора instaceof для проверки совместимости параметров, выполнения приведения и использования более детальных сравнений на уровне конкретной структуры объекта. Это похоже на предложенную альтернативную реализацию в исходном посте.

 @Override
public boolean equals(Object other) {
    if (this == other) return true;
    if (other instanceof MyDTO) { 
        MyDTO otherDTO = (MyDTO) other; 
        return this.getValue().equals(otherDTO.getValue()); // mind null values
    } 
    return false; 
}

У этого подхода есть дополнительная ценность: готовность класса к использованию в коллекции, что является очень распространенным случаем для классов DTO (например, List<UserDTO>)

...