在Java接口声明中使用模板参数

时间:2018-11-23 00:11:52

标签: java templates interface prototype-pattern

我来自C ++,现在正在上Java类,更加专门地研究设计模式。上一堂课,教授给了我们一个示例项目,以帮助我们开始使用Prototype模式,并且项目中有一个接口声明,我不太了解(也没有问过教授:/)

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();
}

有人可以给我一些关于在T上下文中使用参数IPrototype<T extends IPrototype>的解释。它的目的是什么?是有必要还是仅仅是一种方法?

谢谢

4 个答案:

答案 0 :(得分:1)

这称为“好奇地重复发生的模板模式”。顾名思义,它是使用C ++编写的使用模板的代码的发现,但是,该模式也适用于Java中的泛型。

在这里,我可以实现以下接口:

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

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

注意重写方法的方法签名。基本接口IPrototype不了解ConcretePrototype,但是,通过使用CRTP,我们可以强制ConcretePrototype返回其自身类型的值。

答案 1 :(得分:1)

它不是模板参数,而是Java通用类型,它代表实现给定接口的任何类。在原型模式的情况下,没有必要,只需一种可能的实现。

答案 2 :(得分:1)

T是类型参数,也是泛型。

T扩展了IPrototype:要声明一个有界的类型参数,T可以是IPrototype的子类的任何类型

公共T clone(); 返回类型将是通用的。

public T deepClone(); 返回类型将是通用的(意味着可以是任何类型)

答案 3 :(得分:1)

顺便说一句,我很确定您使用的语法是错误的,因此无论如何最好还是通知您的老师。

问题在于,IPrototype在这里用作原始类型。第二次在网上使用它,只是IPrototype,没有类型变量。在Java中是不行的。

对于正在发生的事情,这意味着IPrototype的类型参数必须是IPrototype的类型,即IProtoType的某个子类。看一下Java的Enum类型,它使用完全相同的模式: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();
}