using template parameters in java interface declaration

1.5k views Asked by At

I come from C++ and I'm taking a Java class right now, studying design patterns more specifically. Last class, the professor gave us an example project to help us get started with the Prototype pattern and there was an interface declaration in the project which I didn't understand very well (and didn't ask the professor either :/)

package pattern.prototype.impl;

public interface IPrototype<T extends IPrototype> extends Cloneable {

    //clone: Permite realizar una clonacion superficial del prototipo.
    public T clone();

    //deepClone: Permite realizar una clonación profunda del prototipo.
    public T deepClone();
}

could anyone give me some kind of explanation regarding the use of parameter T in this context IPrototype<T extends IPrototype>. What is its purpose there? Is it necessary or just one way of doing it?

Thank you

4

There are 4 answers

5
flakes On BEST ANSWER

This is called the "Curiously re-occurring template pattern". As the name suggests, it was discovered for code written in C++ which uses templates, however, the pattern works with Generics in Java as well.

Here I can implement the interface as follows:

public class ConcretePrototype implements IPrototype<ConcretePrototype > {
    @Override
    public ConcretePrototype clone() { ... }

    @Override
    public ConcretePrototype deepClone() { ... }
}

Notice the method signature of the overriden methods. The base interface IPrototype does not know about ConcretePrototype, however, by using CRTP we can enforce that ConcretePrototype returns values of its own type.

0
Nenad On

It’s not a template parameter, but a Java generic type, and it stands for any class implementing the given interface. In the context of prototype pattern it’s not necessary, just one possible implementation.

0
GauravRai1512 On

T is type parameter also a generic type.

T extends IPrototype : To declare a bounded type parameter,T can be any type that is subclass of IPrototype

public T clone(); return type would be generic.

public T deepClone(); return type would be generic(means can be any type)

0
markspace On

BTW, I'm pretty sure the syntax you are using is wrong, so it might be best to inform your instructor anyway.

The problem is that IPrototype is used as a raw type here. The second time it's used on the line, it's just IPrototype with no type variable. That's a no-no in Java.

As for what is going on, all it means is that the type parameter for IPrototype must be a type of IPrototype--that is, some subclass of IProtoType. Take a look at Java's Enum type, which uses exactly the same pattern: https://docs.oracle.com/javase/10/docs/api/java/lang/Enum.html

public interface IPrototype<T extends IPrototype<T>> extends Cloneable {
//                                              ^^^ add this

    //clone: Permite realizar una clonacion superficial del prototipo.
    public T clone();

    //deepClone: Permite realizar una clonación profunda del prototipo.
    public T deepClone();
}