Reputation: 3257
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
Upvotes: 0
Views: 1868
Reputation: 11020
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();
}
Upvotes: 1
Reputation: 844
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)
Upvotes: 1
Reputation: 494
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.
Upvotes: 1
Reputation: 23624
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.
Upvotes: 1