Java Generics: метод интерфейса, который получает аргумент типа реализующего класса

В 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) {
       ...
    }

}    







Edit:

Хорошо, я пытаюсь описать по-другому то, чего хочу достичь. Я хочу иметь несколько классов, у которых есть метод, который принимает аргумент этого типа класса. Таким образом, дополнительно к классу A сверху можно сказать, что следующий класс B выглядит следующим образом:

public class B implements MyInterface {

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

}

у каких классов кабин A и B есть общий метод - метод, который получает аргумент типа самого класса.

В моем проекте я хочу добиться следующего. Я пишу небольшую игру и хочу реализовать какое-то обнаружение столкновения. в основном я хочу это сделать, выполняя некоторые "умные" полиморфические вызовы.

Я определил интерфейс 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, поскольку игрок получает столкновений и обрабатывает их. Это должно быть сделано в общем виде, поэтому, например, у меня есть поля и круг, теперь Player реализует ICollisionReceiver <Box> и ICollisionReceiver < Круг > поэтому у меня есть оба метода

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

и

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

В моем классе box и circle я могу зарегистрировать 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;
    }

это в основном проверяет, сталкивается ли это поле с определенным приемником, а затем вызывает метод colliders() получателей.

Теперь дело в том, что я хочу убедиться, что оба класса и круг классов реализуют интерфейс 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);
}

Как вы можете видеть, объявление Generic немного похоже на бесконечную рекурсию, и я уверен, что если бы у Java не было стирания типа, это было бы - к счастью (?) все Generics на самом деле 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!

Ответ 3

Что вы хотите сделать, вероятно, что-то вроде этого:

public interface MyInterface <T extends A> {
    public void method(T object) {
        ...
    }
}

public class A implements MyInterface<A_or_class_extending_A>
{ ... }

Я надеюсь, что это помогло!