Это можно проиллюстрировать простым примером и техникой, которая может быть использована для реализации цепных вызовов методов для подклассов. В примере ниже setName
возвращается значение Node
, поэтому цепочка City
не будет работать:
class Node {
String name;
Node setName(String name) {
this.name = name;
return this;
}
}
class City extends Node {
int square;
City setSquare(int square) {
this.square = square;
return this;
}
}
public static void main(String[] args) {
City city = new City()
.setName("LA")
.setSquare(100); // won't compile, setName() returns Node
}
. Таким образом, мы могли бы ссылаться на подкласс в общем объявлении, City
теперь возвращает правильный тип:
abstract class Node<SELF extends Node<SELF>>{
String name;
SELF setName(String name) {
this.name = name;
return self();
}
protected abstract SELF self();
}
class City extends Node<City> {
int square;
City setSquare(int square) {
this.square = square;
return self();
}
@Override
protected City self() {
return this;
}
public static void main(String[] args) {
City city = new City()
.setName("LA")
.setSquare(100); // ok!
}
}