Reputation: 720
Short version:
What is the correct syntax to make a class extends its generic argument:
class A<T> extends T {} // doesn't compile
Long version:
I have a base abstract class (the following code has been shortened just for this post purposes)
abstract class D {
abstract void f();
abstract void g();
}
Then, there is a set of possible combinations for each f() and each g(). The goal is to have all the possible combinations.
One solution is to make for each f_j() a class Fj that extends D and implements the f_j(), then for each g_i() we make a class GiFj which extends Fj and implements g_i(). For example
abstract class F1 extends D {
@Override
void f() { /* F1 Work */ }
}
abstract class F2 extends D {
@Override
void f() { /* F2 Work */ }
}
class G1F1 extends F1 {
@Override
void g() { /* G1 Work */ }
}
class G1F2 extends F2 {
@Override
void g() { /* G1 Work : Duplicated Code */ }
}
The problem is that the code for Gi is going to get duplicated many times.
The solution that I want to implement is to regroup all GFi into on generic class
class G1<F extends D> extends F {
@Override
void g() { /* G1 work */ }
}
So how to do this in java, or if it is impossible what is the good way to do it
Upvotes: 3
Views: 81
Reputation: 12942
Answer to short version
That is not possible in Java. A compiler needs to know at compile time which methods and fields the superclass of a class has. Thus, a class can only extend a concrete class (possible with type variables), but it cannot extend a type variable on its own.
Answer to long version (which on the surface seems to be unrelated to the short version)
You can use composition to achieve sort of what you want:
class Foo {
final FDelegate fDelegate;
final GDelegate gDelegate;
Foo(FDelegate fDelegate, Delegate gDelegate) {
this.fDelegate = fDelegate;
this.gDelegate = gDelegate;
}
void f() {
fDelegate.f(this);
}
void g() {
gDelegate.g(this);
}
}
interface FDelegate {
void f(Foo container);
}
interface GDelegate {
void g(Foo container);
}
Then you have classes F1
, F2
, G1
, G2
which contain the various method implementations. You pass a Foo
object so that you can access its (visible) members.
Upvotes: 1