在超类中定义泛型类型,它指的是它所在的子类的类型

时间:2018-03-20 15:34:30

标签: java generics

问题
有没有办法在超类中实现泛型类型或类似的东西,它总是引用它所在的子类?

我需要的解释

我有超类

public abstract class MySuperclass{

   public abstract *magicalTypeReference* getInstance();

}

当我创建它的子类时,我希望* magicalTypeReference *成为它所在的子类的类型。

public class FirstSubclass extends MySuperclass{

  @Override
  public FirstSubclass getInstance(){return this;}

}

public class SecondSubclass extends MySuperclass{

  @Override
  public SecondSubclass getInstance(){return this;}

}

为什么正常的通用类型不会完成这项工作

在技术上可以使用泛型类型进行类似的操作。

public abstract class MySuperclass<E extends MySuperclass>{

   public abstract E getInstance();

}

public class FirstSubclass extends MySuperclass<FirstSubclass>{

  @Override
  public FirstSubclass getInstance(){return this;}

}

public class SecondSubclass extends MySuperclass<SecondSubclass>{

  @Override
  public SecondSubclass getInstance(){return this;}

}

但是泛型类型并不能保证以后的类型被强制为子类。从技术上讲,您可以使用另一个子类作为泛型类型来创建子类。喜欢这个

public class SecondSubclass extends MySuperclass<FirstSubclass>{

  @Override
  public FirstSubclass getInstance(){return this;}

}

java中是否有一些构造可以提供&#34;类型安全&#34;实现这个的方式?

2 个答案:

答案 0 :(得分:0)

这在Java中是不可能的。

如果假设你想要什么是可能的,你可以像这样实现FirstSubclass

public class FirstSubclass extends MySuperclass {

  @Override
  public FirstSubclass getInstance() { return new FirstSubclass(); }

}

然后你可以拥有一个不会覆盖getInstance()方法的子类:

public class SubSubclass extends FirstSubclass { }
由于继承,

SubSubclass还实现了MySuperclass接口。但是,SubSubclass的{​​{1}}方法继承自getInstance(),后者返回FirstSubclass。因此,FirstSubclass不符合SubSubclass接口的合同,因为其MySuperclass方法未返回getInstance()

答案 1 :(得分:-1)

而不是声明你的public abstract class MySuperClass<E extends MySuperClass> 喜欢

public abstract class MySuperClass<E extends MySuperClass<E>>

如果你声明像

public class SecondSubclass extends MySuperclass<FirstSubclass>{

@Override
public FirstSubclass getInstance(){return this;}

}

public class FirstSubclass extends MySuperclass<SecondSubclass>{

@Override
public SecondSubclass getInstance(){return this;}

}

你可以让子类避免在某种意义上引用彼此

此解决方案肯定会避免像这样的情况

ConstraintSet

其中一个类包含另一个类,反之亦然。