2

我的目标是理解接口隔离原理,同时实现多态。

我的预期结果:我可以通过接口隔离原则实现多态性。

我的实际结果:不,我不能。我被迫创建样板并使用 Liskov 替换原则(如果有 Worker,则必须有一个不能吃的 Worker,所以为 Worker 创建一个可以吃的接口,扩展 Worker)。我想我误解了接口隔离原则。

这是违反接口隔离原则的代码。

public interface IWorker {
  void work();
  void eat();
}

class Human implements IWorker {
  public void work() {
    System.out.println("Human is working.");
  }

  public void eat() {
    System.out.println("Human is eating.");
  }
}

class Robot implements IWorker {
  public void work() {
    System.out.println("Robot is working.");
  }

  public void eat() {
    throw new UnsupportedOperationException("Robot cannot eat");
  }
}

我被告知将接口分成2。

public interface IEatable {
  void eat();
}

interface IWorkable {
  void work();
}

class Human implements IWorkable, IEatable {
  public void work() {
    System.out.println("Human is working.");
  }

  public void eat() {
    System.out.println("Human is eating.");
  }
}

class Robot implements IWorkable {
  public void work() {
    System.out.println("Robot is working.");
  }
}

解决方案是使用 Liskov 替换原则。

public interface IWorkable {
  void work();
}

interface IEatable {
  void eat();
}

interface IWorker extends IWorkable {
}

interface IHumanWorker extends IWorker, IEatable {
}
4

2 回答 2

1

您的第二步看起来不错,您已将界面拆分为两个更具体的界面。机器人“吃”没有意义。(我真的没有得到第三步)

在调用方,您现在可以使用抽象:

//Polymorphism
List<IWorkable> workers = Arrays.asList(new Robot(), new Human());
//do some work

List<IEatable> eaters = Arrays.asList(new Human(), new Human());
//send for lunch break

如果你想在同一件事上同时拥有这两种行为,那么你的抽象/设计似乎是错误的,因为机器人不能按照定义吃东西(由未实现方法的代码气味表明)。

Robot 不是 IWorker(您的第一个代码),因为它不会完全填充(完整)合约(接口,eat 方法),无论它看起来多么相似。

于 2021-05-25T06:27:04.347 回答
0

我建议使用抽象类而不是接口。如果您需要每个Workable工作,那么您将方法抽象化。如果他们吃的只是可选的,那么你不会。一个例子是:

abstract class Workable {

    protected String name;

    public Workable(String name) {
        this.name = name;
    }

    protected abstract void work();

    public void eat() {
        System.err.println("\"" + name + "\" can't eat");
    }
}

class Human extends Workable {
    public Human(String name) {
        super(name);
    }
    @Override
    public void work() {
        System.out.println("Human " + name + " is working!");
    }

    @Override
    public void eat() {
        System.out.println("Human " + name + " is eating!");
    }
}

class Robot extends Workable {
    public Robot(String name) {
        super(name);
    }

    public void work() {
        System.out.println("Robot " + name + " is working!");
    }
}


public class Test {
    public static void main(String[] args) {
        Workable[] workers = new Workable[] {
                new Human("Jerry"),
                new Robot("XAE12")
        };
        for (Workable worker : workers) {
            worker.work();
            worker.eat();
        }
    }
}

我不确定我是否正确理解了你的问题,所以如果这对你有帮助,请告诉我。

于 2021-05-24T17:49:09.230 回答