Classes can extend generic classes, and provide values for type parameters or add new type parameters by in doing so. For example, all the following are legal:
class MyStringList extends ArrayList<String> { ... }
class A<X, Y, Z> { ... }
class B<M,N> extends A<N, String, Integer> { ... }
The addition of generics does, however, change the rules of method overriding slightly. Note in the first example above (MyStringList) the effective signatures of the 'get' method in ArrayList and our subclass:
ArrayList:
public Object get(int i);
MyStringList:
public String get(int i);
Through inheritance, the return type has changed. Prior to Java 1.5, this would not have been legal; however, with the addition of parameterized types, the rule has change from "the return types must be identical" to "the return type of the method must be a subtype of all the methods it overrides." As such, the following, which would not compile in a 1.4 environment, is perfectly acceptable in 1.5:
public class Parent {
public Number getX() { ... }
}
public class Child extends Parent {
public Integer getX() { ... }
}
class MyStringList extends ArrayList<String> { ... }
class A<X, Y, Z> { ... }
class B<M,N> extends A<N, String, Integer> { ... }
The addition of generics does, however, change the rules of method overriding slightly. Note in the first example above (MyStringList) the effective signatures of the 'get' method in ArrayList and our subclass:
ArrayList:
public Object get(int i);
MyStringList:
public String get(int i);
Through inheritance, the return type has changed. Prior to Java 1.5, this would not have been legal; however, with the addition of parameterized types, the rule has change from "the return types must be identical" to "the return type of the method must be a subtype of all the methods it overrides." As such, the following, which would not compile in a 1.4 environment, is perfectly acceptable in 1.5:
public class Parent {
public Number getX() { ... }
}
public class Child extends Parent {
public Integer getX() { ... }
}