Java泛型:接收实现类的类型参数的接口方法

2022-09-01 10:46:55

在Java中,是否可以定义一个接口,该接口具有接收实现类的参数的方法?

接口:

public interface MyInterface {
   public <T is/extends of the type of the implementing class> void method(T object);
}

类:

public class A implements MyInterface {

    public void method(A object) {
       ...
    }

}

我想避免的是,一个类可以与另一个像它自己一样的类来实现MyInterface。

所以这不应该被允许:

public class A implements MyInterface<B> {

    public void method(B object) {
       ...
    }

}    





编辑:

好吧,我试着用另一种方式描述我想要实现的目标。我希望有几个类具有接受该类型类的arg的方法。因此,除了上面的A类之外,假设还有另一个B类看起来像这样:

public class B implements MyInterface {

    public void method(B object) {
       ...
    }

}

展位类 A 和 B 的共同点是一个名为“method”的方法,该方法接收类本身类型的参数。

在我的项目中,我想实现以下目标。我正在编写一个小游戏,并希望实现某种碰撞检测。基本上,我想通过做一些“智能”多态调用来做到这一点。

我定义了一个接口 ICollisionReceiver,如下所示:

public interface ICollisionReceiver<T extends IShape> extends IShape {

    public boolean collides(T t);

}

我定义了另一个这样的接口:

public interface ICollisionChecker<T extends ICollisionChecker<T>> extends IShape {

    public void addCollisionReceiver(ICollisionReceiver<T> receiver);

    public void removeCollisionReceiver(ICollisionReceiver<T> receiver);

}

例如,我的播放器在播放器接收碰撞并处理它们时实现接口 ICollisionReceiver。这应该以通用的方式完成,例如我有盒子和圆圈,现在玩家实现了ICollisionReceiver< Box >和ICollisionReceiver< Circle >所以我有两种方法

@Override
public boolean collides(final Box b) {        
    ...
    return false;
}

@Override
public boolean collides(final Circle c) {        
    ...
    return false;
}

在我的盒子和圈子类中,我可以注册ICollisionReceivers,然后在更新方法中执行以下操作:

    boolean conti = true;
    int i=0;
    while(conti && i<collisionReceivers.size()) {
        final ICollisionReceiver<Bonus> rec = collisionReceivers.get(i);               
        if(this.collidesWith(rec)) {
            conti = rec.collides(this);
        }            
        ++i;
    }

这基本上检查此框是否与某个接收器发生冲突,然后调用接收器collides()方法。

现在的关键是,我想确保类box和circle都仅使用自己的类型实现ICollisionChecker接口。

我明确地可以通过做这样的事情来做到这一点

public class Bonus extends AnimatedSprite implements ICollisionChecker<Bonus>...

但这对我来说不是很令人满意...

很抱歉这篇文章很长,我希望这能说清楚。


答案 1

你想要的东西在Java中是不可能的,也没有用。

所以这不应该被允许:

为什么不呢?这有什么用呢?泛型不是让你做出任意限制的。泛型仅用于消除您原本需要的强制转换,因为它可以证明强制转换始终是安全的。

只要类型安全,就没有必要进行任意限制以禁止它。public class A implements MyInterface<B>

您应该简单地将接口定义为

public interface MyInterface<T> {
   public void method(T object);
}

你可以定义你的类

public class A implements MyInterface<A> {
    public void method(A object) {
    }
}

以及如果其他人定义了一个类

public class B implements MyInterface<A> {
    public void method(A object) {
    }
}

那就这样吧。你为什么在乎?它会导致什么问题?


答案 2

好吧,这至少是可能的:

public interface SelfImplementer<T extends SelfImplementer<T>> {
    void method(T self);
}

正如你所看到的,泛型声明看起来有点像无限递归,我相当肯定,如果Java没有类型擦除,那将是 - 谢天谢地(?)所有的泛型实际上是在编译器处理它们之后,所以你可以这样做Objects

public class Impl implements SelfImplementer<Impl> {
    @Override
    public void method(Impl self) {
        System.out.println("Hello!");
    }
}

正如预期的那样,这个

public static void main(String[] args) {
    Impl impl = new Impl();
    impl.method(impl);
}

打印输出

Hello!