[英]use implementation type in interface in java
I want to make an interface that forces each class that implements it to have a certain functionality, for the implemented class' type. 我想创建一个接口,强制实现它的每个类具有某个功能,用于实现的类的类型。
So say I have classes MyClassA, MyClassB, MyClassC, etc. that all need a function on their own type: 所以说我有类MyClassA,MyClassB,MyClassC等都需要一个自己类型的函数:
in MyClassA: 在MyClassA中:
public class MyClassA implements MyClass {
MyClassA function(MyClassA x) {
doSomethingImplementedInMyClassA(x);
}
}
in MyClassB: 在MyClassB中:
public class MyClassB implements MyClass {
MyClassB function(MyClassB x) {
doSomethingImplementedInMyClassB(x);
}
}
The question is, how to write the interface MyClass
to require such function? 问题是,如何编写接口
MyClass
来要求这样的功能?
public interface MyClass {
MyClass function(MyClass x);
}
obviously doesn't work, since the returning type is MyClass and not its implementation. 显然不起作用,因为返回类型是MyClass而不是它的实现。 How to do this properly in Java?
如何在Java中正确地做到这一点?
You can use generics: 你可以使用泛型:
public interface MyClass<V extends MyClass<V>> {
V function(V x);
}
public class MyClassA implements MyClass<MyClassA>
This is called the CRTP . 这称为CRTP 。
This is not perfect; 这并不完美; it would still allow things like
它仍然会允许这样的事情
public class MyClassB implements MyClass<MyClassA>
To do this correctly, you need higher-kinded types [citation needed] , which Java does not support. 要正确执行此操作,您需要更高级的类型[需要引证] ,Java不支持。
If the implementation always calls a method on the argument, why not just add that method to the interface? 如果实现总是在参数上调用方法,为什么不直接将该方法添加到接口?
interface MyClass {
MyClass doSomething();
}
class MyClassA implements MyClass {
MyClassA doSomething() {
//implementation here
}
}
class MyClassB implements MyClass {
MyClassB doSomething() {
//implementation here
}
}
The proper way to do what you want to do in Java is like this: 在Java中执行您想要执行的操作的正确方法是这样的:
1st you define your interface containing a abstract method , that is a method that is not defined yet. 首先,您定义包含抽象方法的接口,这是一种尚未定义的方法。 Remind that an interface is not a class!
提醒一个界面不是一个类!
public interface Animal {
public Animal reproduceWith(Animal someAnimal);
}
Then you define the classes that implements the interface and you override the abstract method but now you implement it with the code of your choice. 然后定义实现接口的类,并覆盖抽象方法,但现在使用您选择的代码实现它。 That way the only thing that is the same in the class is the method name.
这样,类中唯一相同的是方法名称。 This effectively forces a class to implement a certain method.
这有效地迫使类实现某种方法。
public class Dog implements Animal {
@Override
public Animal reproduceWith(Animal someAnimal) {
return new Dog();
}
}
public class Cat implements Animal {
@Override
public Animal reproduceWith(Animal someAnimal) {
return new Cat();
}
}
After that you could for example make a list of MyInterface and iterate over it calling the same method even if its a different class. 之后你可以创建一个MyInterface列表并迭代它调用相同的方法,即使它是一个不同的类。
List<Animal> list = new ArrayList<Animal>();
list.add(new Cat());
list.add(new Dog());
Animal cat = new Cat();
Animal dog = new Dog();
for (Animal animal : list) {
System.out.println(animal.reproduceWith(cat));
System.out.println(animal.reproduceWith(dog));
}
I hope that helps you out. 我希望能帮到你。
What you probably need is a parent class apart from an interface. 您可能需要的是除了接口之外的父类。
I find an interface is ideally used to define behavior thus GroupElementA
is a GroupElement
sounds conceptually more accurate rather than GroupElementA
behaves like a GroupElement
. 我发现接口理想地用于定义行为,因此
GroupElementA
是一个 GroupElement
声音在概念上更准确,而GroupElementA
行为就像 GroupElement
。
I would consider using a parent class to achieve what you want to have. 我会考虑使用父类来实现你想要的东西。
/**
* An abstract group element.
*/
abstract class GroupElement
{
// attributes of all group elements
}
/**
* Defines behavior for objects that can be multiplied with
* GroupElements.
*/
interface GroupElementMultipliable
{
public GroupElement multiplyBy(GroupElement groupElement);
}
/**
* Defines behavior for objects that can be divided by
* GroupElements.
*/
interface GroupElementDivisible
{
public GroupElement divideBy(GroupElement groupElement);
}
/**
* An abstract GroupElement that can perform operations like
* multiplication and division.
*
* Then again this class may not be necessary. The interfaces
* implemented here may actually be directly implemented by
* GroupElementA. GroupElementA will also be the one to inherit
* GroupElement.
*/
abstract class OperableGroupElement extends GroupElement
implements GroupElementMultipliable, GroupElementDivisible
{
// attributes of all operable group elements
}
/**
* A concrete GroupElement that can perform operations like
* multiplication and division.
*/
class GroupElementA extends OperableGroupElement
{
@Override
public GroupElementA multiplyBy(GroupElement groupElement)
{
// Since we expect to multiply with another GroupElementA
// we attempt to typcast the groupElement
GroupElementA groupElementA = (GroupElementA) groupElement;
// do multiplication operation -- this * groupElementA
// then return new self
return this;
}
@Override
public GroupElementA divideBy(GroupElement groupElement)
{
// Since we expect to divide by another GroupElementA
// we attempt to typcast the groupElement
GroupElementA groupElementA = (GroupElementA) groupElement;
// do division operation -- this / groupElementA
// then return new self
return this;
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.