java - 在参数上强制执行子类 Java 类型

标签 java generics inheritance parameters

<分区>

有没有办法在编译时强制参数的子类类型?

类似于 this 但不是实例 - 类?

我有类(class):

public abstract class Animal {

  public abstract void follow(Animal a); // <-- how to declare it?

}

但我希望子类永远不要使用 Animal 基类,而是只使用它本身(派生类)作为参数:

public class Fish extends Animal {

  @Override
  public void follow(Fish f) { // error here, since it expects Animal
    tagAlong(f);
  }

  private void tagAlong(Fish f) {
    // do something  
  }

}

我想要一个 Fish 只使用 Fish 类型的参数,而不是 Animal 类型的参数,就像另一个子类 Parrot 将仅在方法 follow() 上使用一个 Parrot 参数。

我强烈希望在编译时强制执行此操作,但如果没有其他可能,运行时是一个(不太理想的)选项。

最佳答案

这有一个窍门。

从设计的角度来看,它很丑陋,但它适用于您的情况。

首先要注意的是:使用 Animal 进行参数化并没有什么错,并在运行时检查类型。

以下是如何使用与方法签名相同类型的参数强制继承:

// made class generic
public abstract class Animal<T extends Animal<T>> {

    public abstract void follow(T a);

}

// parametrizes with own type
public class Fish extends Animal<Fish> {

    @Override
    public void follow(Fish a) {
        // compiles
    }

}

您还可以声明一个泛型方法 follow相反,参数化为 <T extends Animal> (签名中只有 T),但您不能强制执行 Fish在签名中Fish类(class)。

关于java - 在参数上强制执行子类 Java 类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49859903/

相关文章:

java - 具有上限的未知类型的类

c# - 指定多个泛型类型来实现

ios - Swift:将子类类型的对象分配给具有泛型的基类类型的变量会产生错误

java - 将 SOAPMessage 对象转换为 Java 中 XmlType 注释类的实例

java - LdapContextSource 关闭连接

Android:如何使 Kotlin 中所有对象列表的类型转换器(用于 Room)通用

Java SuperClass 重写子类变量

c++ - 覆盖基类成员变量的初始值

java - TreeSet 算法交集的 BigO 复杂度是多少?

java.lang.IllegalStateException : BeanFactory not initialized or already closed - call 'refresh' before accessing beans via the ApplicationContext