Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is the benefit of extending a generic by specifying the new type as actual type of generic

Tags:

java

generics

I saw this pattern somewhere:

class A extends B<A> {

}

This structure is a little unusual to extend a generic by specifying the new type as actual type of generic. What is the use? Is there a name for this pattern? Is there any alternative pattern?

Example: https://code.google.com/p/selenium/wiki/LoadableComponent

Jump to: public class EditIssue extends LoadableComponent<EditIssue> {

Edit: After reading the responses, it seems that I need to alter my understanding of type checking by the compiler. At the back of my mind, my beef with this pattern was, if the two A's need to be same then is there a way to not repeat them? But it seems that there is no better way to propagate the derived class's type to the parent.

like image 918
Asad Iqbal Avatar asked Jun 14 '13 00:06

Asad Iqbal


2 Answers

Of course the OOP answer is that A is a B. If A were not a B than A should merely compose itself with a B to make use of B's functionality.

Presumably B also has some general implementations which take advantage of restrictions placed on the generic type.

Another use case would be for B to look something like:

abstract class B<T extends B<T>> {
    public T createCopy(T t);
}

Now subclasses can implement createCopy and client code can safely use it without having to cast... e.g.

class A extends B<A> {
    public A createCopy(A t) {
        return new A(t); //copy constructor
    }
}

Compare the above to:

abstract class B {
    public B createCopy(B t);
}
class A extends B {
    public B createCopy(B t) { //Is the copy an A or a different subtype of B? We don't know.
        return new A(t); //copy constructor
    }
}
like image 50
Tim Bender Avatar answered Sep 19 '22 12:09

Tim Bender


You might do something like this when dealing with recursive data structures. For example, nodes in a graph or a tree could be defined as a collection of other nodes:

class Node extends AbstractList<Node> {
    ...
}

Equally you might see something like this if the abstract/generic type is meant for comparing objects of a similar type, such as is the case with java.lang.Comparable:

class MyObject implements Comparable<MyObject> {
    public int compareTo(MyObject other) { ... }
}
like image 31
Richard JP Le Guen Avatar answered Sep 20 '22 12:09

Richard JP Le Guen