在java中使用接口中的实现类型
我想为实现的类的类型创建一个接口,强制实现它的每个类都具有特定的功能 假设我有MyClassA、MyClassB、MyClassC等类,它们都需要自己类型的函数: 在MyClassA中:在java中使用接口中的实现类型,java,generics,interface,Java,Generics,Interface,我想为实现的类的类型创建一个接口,强制实现它的每个类都具有特定的功能 假设我有MyClassA、MyClassB、MyClassC等类,它们都需要自己类型的函数: 在MyClassA中: public class MyClassA implements MyClass { MyClassA function(MyClassA x) { doSomethingImplementedInMyClassA(x); } } 在MyClassB中: public clas
public class MyClassA implements MyClass {
MyClassA function(MyClassA x) {
doSomethingImplementedInMyClassA(x);
}
}
在MyClassB中:
public class MyClassB implements MyClass {
MyClassB function(MyClassB x) {
doSomethingImplementedInMyClassB(x);
}
}
问题是,如何编写接口MyClass
来要求这样的功能
public interface MyClass {
MyClass function(MyClass x);
}
显然不起作用,因为返回的类型是MyClass,而不是它的实现。如何在Java中正确执行此操作?您可以使用泛型:
public interface MyClass<V extends MyClass<V>> {
V function(V x);
}
public class MyClassA implements MyClass<MyClassA>
公共接口MyClass{
V函数(vx);
}
公共类MyClassA实现MyClass
这就是所谓的
这并不完美;它仍然允许这样的事情发生
public class MyClassB implements MyClass<MyClassA>
公共类MyClassB实现MyClass
要正确地执行此操作,您需要更高类型的[引文需要],Java不支持这种类型。如果实现总是对参数调用方法,为什么不将该方法添加到接口中
interface MyClass {
MyClass doSomething();
}
class MyClassA implements MyClass {
MyClassA doSomething() {
//implementation here
}
}
class MyClassB implements MyClass {
MyClassB doSomething() {
//implementation here
}
}
在Java中执行所需操作的正确方法如下: 首先,定义包含抽象方法的接口,该方法尚未定义。 请注意,接口不是类
public interface Animal {
public Animal reproduceWith(Animal someAnimal);
}
然后定义实现接口的类并重写抽象方法,但现在使用您选择的代码实现它。这样,类中唯一相同的就是方法名。
这有效地迫使类实现某种方法
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();
}
}
之后,您可以创建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));
}
List List=new ArrayList();
添加(新的Cat());
添加(新狗());
动物猫=新猫();
动物狗=新狗();
用于(动物:列表){
系统输出打印LN(动物繁殖(cat));
系统输出打印(带狗的动物繁殖);
}
我希望这对您有所帮助。您可能需要的是一个接口之外的父类 我发现界面是定义行为的理想方式,因此
GroupElementA
是一个GroupElement
听起来在概念上比GroupElementA
更准确
<>我会考虑使用一个父类来实现你想要的。
/**
* 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;
}
}
啊哈,使用类作为自己的泛型,这很聪明!谢谢@USE1111929:BTW,你的意思是“作为它自己的通用参数”。这是一个C++习语,所以它与问题完全无关,java有这个功能。检查我的答案。有什么原因不能将
doSomethingImplementedInMyClass()
添加到接口中吗?我不确定这会有什么帮助?通过创建一个“强制实现它的每个类都具有特定功能的接口,对于实现的类“类型”,您想实现什么?你是如何试图解决这个问题可能是不可能的,但替代方案应该存在;以及类似的方法。因此,我将创建一个接口GroupElement
,并要求GroupElement
的每个实现都将乘法例程定义为GroupElement multiplyBy(GroupElement b的实现){…}
。。。我应该怎样做才能获得a.剂量(b)的效果代码>在您的代码中?公共MyInterface myAbstractMethod();在接口和类中实现它。我将编辑答案。我仍然不知道这是怎么做的a.doSomething(b)代码>。您的代码中的a
和b
是什么?a是MyClassA,b是MyClassB。因此,您可以调用接口的方法并将接口作为参数提供给它,但类可以不同。诀窍在于,您知道方法是相同的,因此可以调用它,而无需检查类型。我编辑了我的答案,让它更清楚。不客气,但这也给了你同样的可能性;)在本例中,基本上您的泛型类型是接口本身。MyInterface a=新的MyClassA();MyInterface b=新的MyClassB();a、 剂量测定法(b);这是一个有趣的方法。然而,如果需要类型转换,那么它仍然比SLaks建议的通用参数方法快?它当然不会产生更短的代码。你的方法到底有什么好处?我倾向于尽可能地使用接口,因为它们不会导致继承速度减慢(甚至抽象类也会这样做,iirc)。实际上,这也是我第一次了解CRTP(多亏SLaks),所以我无法真正比较我的方法。是的,它确实占用了更多的LOC,但这是一个很好的OO解决方案。我不是一个真正的表演迷,但我也读过关于表演的书,唯一主要的问题似乎是打字。