如何通过它实现的接口在具体类中强制实现类型构造函数?

时间:2009-10-15 11:53:07

标签: java generics interface

让我描述一下情况,我确定我只是错误地思考这个问题。我有一个实现接口的具体类。我想在合同中强制该类必须具有特定类型的构造函数。例如:

interface MyInterface {}
public class MyClass implements MyInterface {
    public MyClass(HashMap<String, String> params) {

    }
}

我想确保使用单个HashMap参数实例化MyClass,看起来它会像这样做:

interface MyInterface<T>

除了在方法签名上使用泛型之外,我从来没有将它们用于类或接口,我真的是初学者,所以请解释与解决方案有关的任何泛型......或者如果我是替代解决方案我在考虑错误(从架构上讲)。谢谢!

5 个答案:

答案 0 :(得分:4)

您无法在Java中使用接口强制执行构造函数。您可以获得的最佳近似值是为工厂定义一个接口,create()方法只需一个HashMap ...

此外,您可以使用构造函数需要HashMap的抽象类替换接口,这将强制子类提供一个,但不能更多(子类不一定具有HashMap参数)。

答案 1 :(得分:4)

添加上述答案,构造函数是一个实现细节。接口定义了一个描述其行为方式的合同,而不是如何组装。

因此,您无法强制实现者拥有特定的构造函数。我认为无论你想做什么,界面都不是这样的。


更新:这篇Annotation Processing Tool文章描述了如何创建一个注释和注释处理器,它在编译时生效 并验证一个类是否为no -arg构造函数。

它可以适用于采用地图实例的1参数构造函数。

引用该文章,其用法类似于:

@NoArgsConstructor
public abstract class NoArgsSuperClass {
  public NoArgsSuperClass() {
  }
}

// Passes
public class PublicNoArgsConstructor extends NoArgsSuperClass {
  public PublicNoArgsConstructor() {
  }
}

// Fails
public class NonPublicConstructor extends NoArgsSuperClass {
  NonPublicConstructor() {
  }
}

答案 2 :(得分:0)

您必须创建一个抽象类,而不是接口,在那里声明构造函数,然后从中继承的任何类都必须调用基础构造函数。也可以将基类中的默认构造函数设为private。

安德鲁

答案 3 :(得分:0)

Java中不可能强制类实现具有特定参数类型的构造函数。你为什么想做这个?通常,这样做没有用。

您可以强制非抽象类通过使类实现接口或扩展声明该方法(但未定义)的抽象类来实现某个方法。由于多态性,这很有用;你可以创建一个超类类型的变量引用子类的一个实例,并调用方法:

interface Animal {
    void makeSound(); }
}

class Dog implements Animal {
    void makeSound() {
        System.out.println("Woof!");
    }
}

// Later:

Animal a = new Dog();
a.makeSound();

现在,您可以在不知道makeSound()引用a的情况下致电Dog;您知道a引用的对象具有makeSound()方法,因为它在接口Animal中声明(并且aAnimal)。< / p>

在构造函数的情况下,你永远不会以多态方式调用构造函数;你总是通过提到要实例化的具体类的名称来调用它。因此,强制类使用具有某些参数的构造函数并不是非常有用。

唯一可能有用的情况是通过反射动态实例化类。通过反射,您可以找出一个类具有哪些构造函数,并动态调用其中一个。如果该类没有您需要的特定构造函数,则可以抛出异常 - 但是无法在编译时检查它。

答案 4 :(得分:0)

您是否尝试通过反射创建MyInterface类型的对象?

工厂界面是一种更简单,更好的替代方案。

定义工厂界面(您甚至可以将其定义为MyInterface中的内部接口)。

interface MyInterface {
  public static interface Factory {
    create( HashMap< String, String > params );
  }
}

无论在何处创建MyInterface的新对象,都要确保只通过MyInterface.Factory完成。

关于泛型的问题。从您提供的代码MyInterface看起来并不是通用的