Is there any better solution for abstract class A<T extends A>?

694 Views Asked by At

I want to override a method and replace a parameter it takes with a subclass of that parameter.

For return type there is no problem, because they are not a part of method signature and can be replaced with subclasses (called "covariant return type"). For arguments this is not working, because they are a part of signature.

So I came out with solution to use generic parameter of the same type:

public abstract class A<T extends A> {

  public void loadValuesFrom(T source) {
    ...
  }

}

public class B extends A<B> {

  public void loadValuesFrom(B source) {
    super.loadValuesFrom(source);
    ...    
  }

}

But the statement "public abstract class A" looks odd to me. Are there any other ways to achieve this? Any "covariant parameter type"? :-)

1

There are 1 best solutions below

0
On BEST ANSWER

If it must be a parameter type, using generics is probably the best option. I'd only do a minor correction to avoid the raw type in the class declaration:

public abstract class A<T extends A<T>> {

If however you have the special case where the object being initialized needs to be freshly created, you might include creation in a method, thereby removing the need to pass that object as parameter:

public abstract class A {
    public A clone() {

    }
}

public class B extends A {
    public B clone() {
        // copy state
    }
}