Исследование обобщённого программирования: различия между версиями

Материал из Вики проекта PascalABC.NET
Перейти к навигацииПерейти к поиску
Строка 1: Строка 1:
== Java Generics ==
== Java Generics ==


Особенность Java Generics — ''подчистка типов''. Обобщенный класс <code>A<T></code> транслируется в обычный класс <code>A</code>, где везде вместо типа <code>T</code> используется <code>Object</code>. Если на параметр типа есть ограничение, например, <code>A<T extends Comparable<T> ></code>, то в подчищенном коде вместо <code>T стоит <code>Comparable</code>.
Особенность Java Generics — ''подчистка типов''. Обобщенный класс <code>A<T></code> транслируется в обычный класс <code>A</code>, где везде вместо типа <code>T</code> используется <code>Object</code>. Если на параметр типа есть ограничение, например, <code>A<T extends Comparable<T> ></code>, то в подчищенном коде вместо <code>T</code> стоит <code>Comparable</code>.


Из-за подчистки типов возникает неприятное для нас ограничение: ''параметр шаблона не может реализовывать разные специализации одного интерфейса'' '''[*]'''. Что это и чем оно нам грозит?
Из-за подчистки типов возникает неприятное для нас ограничение: ''параметр шаблона не может реализовывать разные специализации одного интерфейса'' '''[*]'''. Что это и чем оно нам грозит?

Версия от 19:08, 13 июня 2013

Java Generics

Особенность Java Generics — подчистка типов. Обобщенный класс A<T> транслируется в обычный класс A, где везде вместо типа T используется Object. Если на параметр типа есть ограничение, например, A<T extends Comparable<T> >, то в подчищенном коде вместо T стоит Comparable.

Из-за подчистки типов возникает неприятное для нас ограничение: параметр шаблона не может реализовывать разные специализации одного интерфейса [*]. Что это и чем оно нам грозит?

Концепты хороши тем, что позволяют нам устанавливать связи между разными типами. Например, можно иметь концепт

Convertible<S, U>

который содержит функцию

U convert(S x)

или

U S::convert()

Можем ли мы реализовать нечто подобное на Java? У нас ведь есть обобщённые интерфейсы, может это выход?

public interface Convertible<S> {
	public S convert();
}

public class A1 {}

public class A implements Convertible<A1> {
	public A1 convert() {
		return new A1();
	}
}

Здорово! Но мы хотим, чтобы класс A мог быть преобразован и в какой-нибудь A2.

public interface Convertible<S> {
	public S convert();
}

public class A1 {}
public class A2 {}

public class A implements Convertible<A1>, Convertible<A2> {
	public A1 convert() {
		return new A1();
	}
	public A2 convert() {
		return new A2();
	}
}

А вот это уже не работает. Причина — ограничение [*], которое даёт подчистка типов. Класс A может реализовывать только какой-нибудь один Convertible.