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

时间:2015-05-13 13:01:24

标签: java generics interface

假设我有以下界面:

file="/u01/MyFile.txt"
count=0

while read line
do
  ((count++))
  if [[ $line == *"[search]"* ]]
  then 
    sed -i.bak "$((count-1))s/true/false/" $file
  fi
done < $file

然而,这并不完全是我想要的。

显然,一个人不能嫁给一只狗,也不能生一只猫。那么如何将这些信息嵌入到界面中,以便输入类型和输出类型可以在实现时自动更改?

3 个答案:

答案 0 :(得分:47)

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

以下内容:

interface Marriable<T extends Mammal> {
    void marry(T sweetHalf);
    T giveBirthTo();
}

...其中Mammal是您的顶级界面或抽象类,HumanDogUnicorn等扩展/实施它。

答案 1 :(得分:23)

您可以使用递归类型变量来验证您的界面:

interface Mammal<T extends Mammal<T>> {
  void marry(T m);
  T giveBirthTo();
}

这样,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() { ... }
}

编译器只能确保您通过同一接口的某个子类型实现Mammal接口,而不是由实现它的特定类实现。后一种类型约束不能用Java编程语言表示。

答案 2 :(得分:1)

泛型。试试

 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
}