让我描述一下情况,我确定我只是错误地思考这个问题。我有一个实现接口的具体类。我想在合同中强制该类必须具有特定类型的构造函数。例如:
interface MyInterface {}
public class MyClass implements MyInterface {
public MyClass(HashMap<String, String> params) {
}
}
我想确保使用单个HashMap参数实例化MyClass,看起来它会像这样做:
interface MyInterface<T>
除了在方法签名上使用泛型之外,我从来没有将它们用于类或接口,我真的是初学者,所以请解释与解决方案有关的任何泛型......或者如果我是替代解决方案我在考虑错误(从架构上讲)。谢谢!
答案 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
中声明(并且a
是Animal
)。< / p>
在构造函数的情况下,你永远不会以多态方式调用构造函数;你总是通过提到要实例化的具体类的名称来调用它。因此,强制类使用具有某些参数的构造函数并不是非常有用。
唯一可能有用的情况是通过反射动态实例化类。通过反射,您可以找出一个类具有哪些构造函数,并动态调用其中一个。如果该类没有您需要的特定构造函数,则可以抛出异常 - 但是无法在编译时检查它。
答案 4 :(得分:0)
您是否尝试通过反射创建MyInterface类型的对象?
工厂界面是一种更简单,更好的替代方案。
定义工厂界面(您甚至可以将其定义为MyInterface中的内部接口)。
interface MyInterface {
public static interface Factory {
create( HashMap< String, String > params );
}
}
无论在何处创建MyInterface的新对象,都要确保只通过MyInterface.Factory
完成。
关于泛型的问题。从您提供的代码MyInterface看起来并不是通用的