Обобщения Java с параметром - наследование - PullRequest
2 голосов
/ 14 апреля 2019

У меня есть следующий код:

public class Inheritance {

    class A<T,U,V>{

    }

    class B<T,U,V> extends A<T,U,T>{        

    }
}

Может кто-нибудь объяснить мне, как это на самом деле работает?Класс B расширяет только класс A, параметрами которого являются "T, U, T", или он расширяет фактический класс A "T, U, V"?

Ответы [ 4 ]

4 голосов
/ 14 апреля 2019

A * T = B * T
A * U = B * U
A * V = B T

B<String, Integer, Void> b = null;
A<String, Integer, String> a = b;
3 голосов
/ 14 апреля 2019

Расширяет ли класс B только класс A, параметры которого "T, U, T"

Да, именно так.

или это расширяет фактический класс "T, U, V"?

Это шаблон, нет общих параметров. Это способ сопоставления ваших собственных типов параметров с родительскими. Если есть экземпляр B<String, Integer, Long>, будет родительский объект A<String, Integer, String>, поддерживающий его.

2 голосов
/ 14 апреля 2019

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

public class Inheritance {
    class A<T,U,V> { }

    class B<I,J,K> extends A<I,J,I>{ }
}

Код такой же, как и раньше.Вы можете видеть, что нет никакой «именной» корреляции между I, J, K и T, U, V.

Здесь типы I и J перенаправляются в A. С точки зрения A, замена выполняется с помощью: T = I, U = J, V = I.

2 голосов
/ 14 апреля 2019

Позвольте привести это в реальный пример:

 public class Inheritance {
        public static class A<T,U,V>{
             T t;
             U u;
             V v;

             A(T t, U u, V v) {
                this.t = t;
                this.u = u;
                this.v = v;
            }

            T getT() {return t;}
            U getU() {return u;}
            V getV() {return v;}
        }

        public static class B<T,U,V> extends A<T,U,T>{
            public B(T t, U u, V v) {
                super(t, u ,t);
            }
        }

        public static void main(String[] args) {
            B<Boolean, Integer, String> b = new B<>(false, 1, "string");
           // 't' attribute is Boolean 
           // since type parameter T of class B is Boolean
           Boolean t = b.getT(); 
           // 'v' attribute is Boolean 
           // since type parameters T and V of class A must have the same type as 
           // type parameter T of class B 
           Boolean v = b.getV(); 
        }
    }

По сути, класс B расширяет класс A (который имеет три общих параметра).Объявляя B<T,U,V> extends A<T,U,T>, вы просто связываете первый и третий универсальный параметр A с тем же типом первого параметра B

Как показано в примере в конструкторе класса B, у нас есть три различных типа - Boolean, Integer, String, но в конструкторе класса A у нас есть только два различных типа Boolean, Integer, поскольку 1-й и 3-й параметры конструктора класса A связаны с булевым типом

Подробнее об обобщениях и наследовании можно узнать здесь: https://docs.oracle.com/javase/tutorial/java/generics/inheritance.html

...