Reputation: 15234
For example, let's say this is my abstract class:
abstract class A{
int x;
int y;
void foo(A fooMe);
}
...and B
and C
are two classes which extend A
.
What I want is for B
to only be able to call foo()
on other B
s, and for C
to only be able to call foo()
on other C
s. But I want this to be out of the hands of the programmer who's extending my A
class - that is, I want a way to ensure this functionality within A
s code alone.
What can I do? (If possible) I'd like to avoid any hack or generics solution that's too messy - I still want foo
to be able to be called like this, for example:
B b=new B();
B bb=new B();
bb.foo(b);
Edit: I'm now willing to accept a solution which uses generics, if anyone has any ideas... (I couldn't think of one)?
Upvotes: 0
Views: 146
Reputation: 308753
You could enforce such a thing if you use aspect-oriented programming. Before advice could check and throw an exception for those cases that violated your requirements.
Upvotes: 0
Reputation: 1
Here's a hack, but it's not compile time. I don't think Java generics don't have enough covariant/contravariant type support.
class B extends A {
@Override
void foo(A foome) {
if (foome.getClass() != getClass()) {
throw new UnsupportedOperationException("...");
}
}
}
Upvotes: 0
Reputation: 881595
You could make foo
be final
in A
, and implement it as follows: have it raise an exception unless fooMe.getClass()
equals this.getClass()
, and otherwise call abstract method fooHook
. Of course, subclasses will have to override fooHook
, not foo
.
I believe the final-plus-hook approach is inevitable: if a subclass could override foo
, there's no way A
's code alone could guarantee that any checks performed in its foo
aren't just going to be blithely bypassed by a subclass.
Upvotes: 1