7

我想为实现的类的类型创建一个接口,强制实现它的每个类具有一定的功能。

因此,假设我有类 MyClassA、MyClassB、MyClassC 等,它们都需要自己类型的函数:

在 MyClassA 中:

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 中正确执行此操作?

4

4 回答 4

11

您可以使用泛型:

public interface MyClass<V extends MyClass<V>> {
    V function(V x);
}

public class MyClassA implements MyClass<MyClassA> 

这称为CRTP


这并不完美。它仍然允许像

public class MyClassB implements MyClass<MyClassA> 

要正确执行此操作,您需要Java 不支持的更高种类的类型[需要引用] 。

于 2012-09-02T02:16:39.847 回答
1

如果实现总是在参数上调用一个方法,为什么不将该方法添加到接口中呢?

interface MyClass {
    MyClass doSomething();
}

class MyClassA implements MyClass {
    MyClassA doSomething() {
        //implementation here
    }
}

class MyClassB implements MyClass {
    MyClassB doSomething() {
        //implementation here
    }
}
于 2012-09-02T02:40:07.420 回答
1

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

我希望这可以帮助你。

于 2012-09-02T02:45:50.313 回答
1

您可能需要的是除了接口之外的父类。

我发现一个接口理想地用于定义行为,因此GroupElementA GroupElement概念上听起来更准确,而不是GroupElementA 表现得像 GroupElement.

我会考虑使用父类来实现你想要的。

/**
 * 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;
    }
}
于 2012-09-02T04:01:21.103 回答