我的目标是理解接口隔离原则,同时实现多态性。
我的预期结果是:我可以用接口分离原理实现多态。
我的实际结果是:不,我不能。我被迫创建样板并使用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");
}
}
我被告知将接口分成两部分。
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 {
}
我建议使用抽象类,而不是接口。如果您需要每个都可行
,那么您可以将方法抽象化。如果他们只能选择吃东西,你就不吃。例如:
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();
}
}
}
我不确定我是否正确理解了你的问题,所以请让我知道这是否对你有帮助。
第二步看起来不错,您已经将接口拆分为两个更具体的接口。机器人“吃”是没有意义的。(我真的不懂第三步)
在调用方,您现在可以使用您的抽象:
//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
如果你想在同一件事情上同时拥有两种行为,那么你的抽象/设计似乎是错误的,因为机器人不能根据定义进食(由未实现方法的代码气味指示)。
机器人不是IWorker(您的第一个代码),因为它不会完全满足(完整的)合同(接口、eat方法),无论它看起来有多相似。
Liskov替代原则(LSP)和界面分离原则(ISP)之间有什么核心区别吗?最终,这两种方法都是为了设计具有通用功能的界面,并在您具有特殊功能时引入新的界面。
前言 我们都知道当单库系统遇到性能瓶颈时,读写分离是首要优化手段之一。因为绝大多数系统读的比例远高于写的比例,并且大量耗时的读操作容易引起锁表导致无发写入数据,这时读写分离就更加重要了。 EF Core如何通过代码实现读写分离,我们可以搜索到很多案例。总结起来一种方法是注册一个DbContextFactory,读操作注入ReadDcontext,写操作注入WriteDbcontext;另外一种是动
本文向大家介绍java中多态概念、实现原理详解,包括了java中多态概念、实现原理详解的使用技巧和注意事项,需要的朋友参考一下 一.什么是多态? 1.多态的定义 指允许不同类的对象对同一消息做出响应。即同一消息可以根据发送对象的不同而采用多种不同的行为方式(发送消息就是函数调用) 2.多态的作用 消除类型之间的耦合关系 3.多态的说明 近代网络小说泛滥,我们可以用它来举一个例子 某日你看见你手机上
本文向大家介绍详解php实现页面静态化原理,包括了详解php实现页面静态化原理的使用技巧和注意事项,需要的朋友参考一下 1,file_put_contents()函数 2,使用PHP内置缓存机制实现页面静态化:output_buffering php中output_buffering内置函数,简称ob函数,主要会用到的下面几个: ob_start #打开输出控制缓冲 ob_get_contents
本文向大家介绍PyQt5 如何让界面和逻辑分离的方法,包括了PyQt5 如何让界面和逻辑分离的方法的使用技巧和注意事项,需要的朋友参考一下 前言 我们已经知道利用QtDesigner来设计界面,并通过Pycharm外部工具PyUIC将其转化成py源文件。不过由于要响应事件操作,往往会将相应的槽函数写在ui的py文件中,这样,界面和逻辑开发就混合在一起了,每一次的ui更新都会伴随着转换后py文件的槽
我尽可能地保持我的服务接口,通常它们是@functionalinterface。我试图遵循界面分离原则。 如果我的服务实现实现多个接口,如果它们共享其中的大部分依赖关系,这是一个好的实践吗?或者我应该为每个接口创建一个单独的实现? 在我的例子中;TaskService实现这两个接口是一个好的做法吗?或者我应该为每个接口有一个单独的类?