Использование вложенного типа в качестве аргумента общего типа в объявлении супертипа класса include

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

public abstract class Abstrct <T> {

}

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

public class Outer extends Abstrct<Inner> {
    public class Inner {

    }
}

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

Ответы

Ответ 1

Inner не является объектом для объявления класса Outer. Это не известное имя типа при использовании в предложении extends. Используйте квалифицированную ссылку:

class Outer extends Abstract<Outer.Inner>

Или импортируйте его:

import com.example.Outer.Inner;

Из спецификации, касающейся Область действия:

Область объявления члена m, объявленного или унаследованного тип класса C (§8.1.6) является всем телом C, включая любые вложенные типа.

Предложение extends является частью объявления класса < <29 > , как описано в Спецификация. Это не часть тела класса.

Объем типа, используемого в инструкции import, однако,

[..] - это все объявления класса и интерфейса (§7.6) в блоке компиляции в котором появляется декларация импорта, а также любые аннотации на объявление пакета (если есть) блока компиляции.

Ответ 2

Вы можете использовать Abstrct<Outer.Inner>, делая тип недвусмысленным и действительным.

Ответ 3

Вы должны быть явными, поскольку внутренний класс, который вы определили, не является статическим, поэтому он существует только в пределах класса класса. (См. https://docs.oracle.com/javase/tutorial/java/javaOO/nested.html)

В вашем случае попробуйте следующее:

public class Outer extends Abstrct<Outer.Inner> {
    public class Inner {

    }
}