I have the following hierarchy in java:
interface ObserverA {}
interface A {
void method1();
addObserver(Observer o);
}
And I want to extend it like this:
interface ObserverB extends ObserverA{}
interface B extends A {
void method2();
addObserver(ObserverB o);
}
in such a way that the addObserver()
method of B
would override the same method in A
.
As it is it doesn't work, implementations of B
would need to implement both versions of addObserver()
, I wan't to have just one.
Can this be done in a clever way that doesn't involve having to parameterize A
like:
interface A<O extends Observer> {
addObserver(O o);
}
Hackish solutions are most welcome!
You can't narrow method parameter types in subinterfaces or subclasses. You can only broaden them, since implementations of the subtype must be able to fulfill the contract of the supertype.
Similarly, you can narrow return types and exceptions, but not broaden them, for the same reason.
Although your example shows something different I suppose you would like to achive a generic interface implemented by different classes. Have a look at this:
public interface Observer<T> {
void addObserver(T t);
}
public class First implements Observer<First> {
@Override
public void addObserver(First t) {
}
}
public class Second implements Observer<Second> {
@Override
public void addObserver(Second t) {
}
}
As you can see both First and Second classes implement the same interface but with different types of parameters. They parametrize the implemented interface with themselved, but instead of writing Observer<Frist>
you could write Observer<Integer>
or whatever you would like.
EDIT
Taking into account your clarifications this would be a generic implementation of your code within the interface hierarchy you presented.
interface ObserverA {}
interface A<T> {
void method1();
void addObserver(T o);
}
interface ObserverB extends ObserverA {}
interface B extends A<ObserverB> {
void method2();
}
How about -
interface ObserverA {}
interface A {
<T extends ObserverA> void addObserver(T o);
}
and -
interface ObserverB extends ObserverA{}
interface B extends A{
// do nothing, or omit this interface entirely.
}
so that you'll be able to pass any type that inherits ObserverA
as argument to the addObserver
method.
If you are looking for a little explanation, then read on.
I have changed the method in the first interface to use Bounded Type Parameter. The way it's declared, it will allow any objects to be passed as argument to the addObserver
method as long as it's type is ObserverA
, or it inherits from ObserverA
. Since your ObserverB
is inheriting from ObserverA
, you can safely pass objects of both ObserverA
and ObserverB
types to this method as argument.
EDIT
From your clarification, it seems that you should create two different interfaces without any hierarchical relationship between them. They seem to be unrelated because you want to provide implementations for only the second method, while avoiding the first one. So, rather than forcing yourself to provide the implementation for the method from the first interface, you should separate them. There is also an OOP principle for this - Interface Segregation Principle.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With