如何在Java中对接口声明应用更多约束?

如何在Java中对接口声明应用更多约束?,java,generics,interface,Java,Generics,Interface,假设我有以下接口: interface Mammal { void marry(Mammal m); Mammal giveBirthTo(); } 然而,这并没有完全说明我想要什么 显然,人不能和狗结婚,也不能生猫。那么,如何将这些信息嵌入到接口中,以便在实现时自动更改输入类型和输出类型?您可以使用泛型并更改设计 类似于: interface Marriable<T extends Mammal> { void marry(T sweetHalf);

假设我有以下接口:

interface Mammal {
    void marry(Mammal m);
    Mammal giveBirthTo();
}
然而,这并没有完全说明我想要什么


显然,人不能和狗结婚,也不能生猫。那么,如何将这些信息嵌入到接口中,以便在实现时自动更改输入类型和输出类型?

您可以使用泛型并更改设计

类似于:

interface Marriable<T extends Mammal> {
    void marry(T sweetHalf);
    T giveBirthTo();
}
接口可修改{
无效结婚(一半不结婚);
T给予();
}
。。。其中,
哺乳动物
是您的顶级接口或抽象类,
人类
独角兽
等。扩展/实现它

泛型。试一试

 private static interface Race {
}

private static class Human implements Race {}
private static class Canine implements Race {}

private static interface Being<R extends Race> {
    void marry(Being<R> other);
    Being<R> giveBirthTo();
}

private void tryMe() {
    Being<Human> aHuman = new Being<Human>() {

        @Override
        public void marry(Being<Human> other) {
        }

        @Override
        public Being<Human> giveBirthTo() {
            return null;
        }
    };

    Being<Canine> aCanine = new Being<Canine>() {

        @Override
        public void marry(Being<Canine> other) {
        }

        @Override
        public Being<Canine> giveBirthTo() {
            return null;
        }
    };

    aHuman.marry(aCanine); // not possible
}
私有静态接口竞争{
}
私有静态类人类实现种族{}
私有静态类{}
正在使用的私有静态接口{
无效结婚(作为他人);
被赋予();
}
私有无效tryMe(){
成为人类=新的存在(){
@凌驾
公开无效婚姻(其他){
}
@凌驾
公众被给予{
返回null;
}
};
成为阿卡宁=新的存在(){
@凌驾
公开无效婚姻(其他){
}
@凌驾
公众被给予{
返回null;
}
};
啊人类。结婚(阿卡宁);//不可能
}

您可以使用递归类型变量来生成接口:

interface Mammal<T extends Mammal<T>> {
  void marry(T m);
  T giveBirthTo();
}
界面哺乳动物{ 无效婚姻(TM); T给予(); } 这样,Java编译器可以为您提供一定的验证级别。然而,请注意,这种方法仍然可能被滥用。例如:

class Cat implements Mammal<Cat> {
  @Override void marry(Cat cat) { ... }
  @Override Cat giveBirthTo() { ... }
}

class Dog implements Mammal<Cat> { // implements wrong interface
  @Override void marry(Cat cat) { ... }
  @Override Cat giveBirthTo() { ... }
}
类Cat实现哺乳动物{ @无效婚姻(猫){…} @将Cat giveBirthTo()重写为({…} } 类Dog实现了哺乳动物{//实现了错误的接口 @无效婚姻(猫){…} @将Cat giveBirthTo()重写为({…} }
编译器只能确保您通过同一接口的某些子类型实现
哺乳动物
接口,而不是通过实现它的特定类。后一种类型的约束不能用Java编程语言表示。

接口是否应该不命名为
哺乳动物
?没有理由再添加一个。@RafaelWinterhalter正如我提到的,您可以有一个
哺乳动物
接口或抽象类来抽象该特定遗传链中的顶级动物。
Marriable
接口将定义与您的一个物种结婚的合同。您不需要
Marriable
接口来实现此目的。您只需按照我刚才添加的答案中的建议创建一个递归类型。@RafaelWinterhalter您的方法中的问题是它混合了结婚和物种的范围。“哺乳动物”的例子并不能最好地解释这一点,但可以想象一个
快乐的人类
或者一个
普通的人类
。他们将扩展/实现
哺乳动物
,但不
可结婚
。但这不是OP要求的,也与问题解决方案无关,因为即使不使用泛型,也可以将
哺乳动物
接口重构成这样的层次结构。。我要说的是,你的解决方案增加了一个额外的间接性。为了你在谷歌上搜索的乐趣,这被称为F-有界量化。