это проблема, которую вам, возможно, придется решить в будущем.
отаю над проектом, который имеет обширное дерево общего наследования и зависимостей. Перейти к редактированию, чтобы увидеть лучший пример.Основы выглядят примерно так:
class A {
...
}
class B {
...
}
class C extends B {
...
}
class D<T extends B> extends A {
...
}
class StringMap<T extends A> {
HashMap<String, T> _elements;
...
}
Так что теперь я собираюсь написать класс, который содержит определенныйStringMap
тип.
class X {
StringMap<D<C>> _thing = new StringMap<D<C>>;
...
}
Пока все это работает нормально.D<C>
на самом деле это очень длинное имя, и определенная комбинация будет появляться очень часто в других частях кода, поэтому я решил создать класс для конкретной комбинации, чтобы он был более понятным и имел более короткое имя.
class DC extends D<C> {
}
//and go to update X
class X {
StringMap<D<C>> _thing = new StringMap<D<C>>(); //still works fine
StringMap<DC> _thing = new StringMap<DC>(); //error
...
}
Затмение дает ошибку
Связанное несоответствие: типDC
не является допустимой заменой ограниченного параметра<T extends A>
типаStringMap<T>
Итак, вопрос в том, почему это не просто работает?DC
ничего не делает, но расширяетD<C>
и повторить конструкторы. ПочемуStringMap
видетьDC
как отличается, когда это просто дочерний класс чего-то, что он исключает?
РЕДАКТИРОВАТЬ:
Хорошо, переработал пример, чтобы быть ближе к тому, что я на самом деле делаю. Я проверил это, и он выдает ошибку. Здесь я использую универсальный тип, чтобыclone()
возвращает правильный класс для тех, кто реализует его в дереве наследования. Тогда в подклассах я используюB<T extends B<T>>
чтобы гарантировать, что подклассыB
переходят в подкласс B как универсальный типT
.
public abstract class Undoable<T> implements Comparable<T> {
public abstract T clone();
public abstract void updateFields(T modified);
}
abstract public class A<T extends A<T, U>, U extends Comparable<U>>
extends Undoable<T> {
abstract U getKey();
@Override
public int compareTo(T element)
{
return getKey().compareTo(element.getKey());
}
}
public class B<T extends B<T>> extends A<T, String> {
@Override
public T clone()
{
// TODO Auto-generated method stub
return null;
}
@Override
public void updateFields(T modified)
{
// TODO Auto-generated method stub
}
@Override
String getKey()
{
// TODO Auto-generated method stub
return null;
}
}
public class C extends B<C> {
}
public class D<T extends B<T>> extends A<D<T>, String> {
@Override
String getKey()
{
// TODO Auto-generated method stub
return null;
}
@Override
public D<T> clone()
{
// TODO Auto-generated method stub
return null;
}
@Override
public void updateFields(D<T> modified)
{
// TODO Auto-generated method stub
}
}
public class DC extends D<C> {
}
public class StringMap<T extends Undoable<T>> {
HashMap<String, T> _elements;
}
public class Main {
public static void main(String[] args)
{
StringMap<D<C>> _thing = new StringMap<D<C>>(); //works
StringMap<DC> _thing1 = new StringMap<DC>(); //error
//Bound mismatch: The type DC is not a valid substitute for
//the bounded parameter <T extends Undoable<T>> of the type StringMap<T>
}
}