在没有泛型的代码中,参数类型不能随着子类型变化,而变化:
class OrdinarySetter{
void set(Base base){
System.out.println("OrdinarySetter.set(Base)");
}
}
class DerivedSetter extends OrdinarySetter{
void set(Derived derived){
System.out.println("DerivedSetter.set(DerivedSetter)");
}
}
public class OrdinaryArguments{
public static void main(String [] args){
Base base = new Base();
Derived derived = new Derived();
ds.set(derived);
ds.set(base);//Compiles:overloaded,not overridden;
}
}/*Output:
DerivedSetter.set(Derived)
OrdinarySetter.set(Base)
两个set方法都是合法的,DerivedSetter方法不是重写了OrdinarySetter.set(),而是重载了它,实际上在DerivedSetter中有两个方法,所以获取基类的方法是有效的。
在自限定类型中,在扩展类中只有一个方法,这个方法能使,而且仅使扩展类作为他的参数,而不是基类:
interface SelfBoundSetter<T extends SelfBoundSetter<T>>{
void set(T arg);
}
interface Setter extends SelfBoundSetter<Setter>{}
public class SelfBoundingAndCovariantArguments{
void testA(Setter s1,Setter s2,SelfBoundSetter sbs){
s1.set(s2);
//s1.set(sbs);//Error
//set(Setter) in SelfBoundSetter<Setter>
//cannot be applied to (SelfBoundSetter)
}
}
Compiler 不能通过基类型作为参数传递给set,因为没有基类方法的函数签名,实际上,这个参数已经被重写了
没有自限定了类型,原生类型的的继承机制就会介入,将会被重载,如下例:
class GenericSetter<T>{
void set(T arg){
System.out.println("GenericSetter.set(Base)");
}
}
class DerivedGs extends GenericSetter<Base>{
void set(Derived derived){
System.out.println("GenericSetter.set(Base)");
}
}
public class PlainGenericInheritance{
public static void main(String[] args){
Base base = new Base();
Derived derived = new Derived();
dgs.set(derived);
dgs.set(base);//Compiles:overloaded,not overridden
}
}//it's OK