Как я могу гарантировать, что функция моего абстрактного класса может работать только на расширителях того же типа, что и вызывающая сторона? - PullRequest
0 голосов
/ 29 марта 2010

Например, допустим, это мой абстрактный класс:

abstract class A{
    int x;
    int y;

    void foo(A fooMe);
}

... и B и C - это два класса, которые расширяют A.

Я хочу, чтобы B мог звонить foo() только на других B с, а C мог звонить foo() только на других C с. Но я хочу, чтобы это было в руках программиста, который расширяет мой класс A, то есть я хочу, чтобы этот функционал был обеспечен только в коде A.

Что я могу сделать? (Если это возможно) Я бы хотел избежать какого-либо слишком сложного хакерского или обобщенного решения - я все еще хочу, чтобы foo можно было вызывать так, например:

B b=new B();
B bb=new B();
bb.foo(b);

Редактировать : Теперь я готов принять решение, которое использует дженерики, если у кого-то есть идеи ... (я не мог придумать одну)?

Ответы [ 3 ]

1 голос
/ 29 марта 2010

Вы можете сделать foo быть final в A и реализовать его следующим образом: вызывать исключение, если fooMe.getClass() не равно this.getClass(), и в противном случае вызывать абстрактный метод fooHook. Конечно, подклассы должны будут переопределять fooHook, а не foo.

Я считаю, что подход «окончательный плюс крючок» неизбежен: если подкласс может переопределить foo, ни один код A не сможет гарантировать, что любые проверки, выполненные в его foo, не просто быть беспечно обойденным подклассом.

0 голосов
/ 29 марта 2010

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

0 голосов
/ 29 марта 2010

Вот хак, но это не время компиляции. Я не думаю, что в дженериках Java недостаточно ковариантных / контравариантных типов поддержки.


class B extends A {
    @Override
    void foo(A foome) {
        if (foome.getClass() != getClass()) {
            throw new UnsupportedOperationException("...");
        }
    }
}
...