Переопределение универсальных методов с неуниверсальными реализациями

java generics

4701 просмотра

2 ответа

35868 Репутация автора

Я экспериментировал с дженериками в Java и думал об этом примере.

Если у меня есть ClassA<T>, я могу переопределить его с помощью подкласса, который ссылается на конкретный класс, например ClassB extends ClassA<String>, тогда, где ClassA использует T, ClassB может использовать String.

Теперь, игнорируя предыдущий ClassAи ClassB, если у меня есть реферат ClassA, который имеет универсальный метод:

public <T> void doSomething(T data);

Есть ли способ, которым я могу ClassBпереопределить его с конкретным классом, как в предыдущем примере? Я придумал что-то, что работает, а именно параметризацию и класса, и метода, но мне интересно, есть ли другой способ.

class ClassA<T> {
    public void doSomething(T data) {};
}

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

ПРИМЕЧАНИЕ . Все подклассы ClassAявляются анонимными классами, что добавляет веселья.

Автор: Ed Marty Источник Размещён: 01.03.2010 05:47

Ответы (2)


12 плюса

16635 Репутация автора

Решение

Благодаря стиранию типа , это:

public <T> void doSomething(T data);

На самом деле означает это:

public void doSomething(Object data);

Так что нет, нет способа переопределить более ограничительный тип параметра.

Также в этом коде:

class ClassA<T> {
    public <T> void doSomething(T data) {};
}

Параметр type в имени вашего класса и параметр type в методе на самом деле являются разными параметрами. Это все равно что объявить локальную переменную с тем же именем, что и переменная в более широкой области видимости. Вы можете вызвать doSomething(123)экземпляр, ClassA<String>потому что второй Tявляется локальным для метода.

Автор: noah Размещён: 01.03.2010 06:02

2 плюса

2097 Репутация автора

Короче говоря, ответ - нет. Если вы определяете метод с универсальным параметром, то его сигнатура содержит универсальный, и любые «переопределения» должны соответствовать сигнатуре (содержать универсальный).

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

public void doSomething(Object data) {}

Универсальный бит мало что дает вам, если только он не используется для указания того, каким будет возвращаемое значение, как в:

public <T> T doSomething(T data) {}

Но зачем? Действительно ли существует проблема, вызывающая doSomething () в общем?

Автор: Matthew Flynn Размещён: 01.03.2010 06:22
Вопросы из категории :
32x32