java - 如何避免使用实现多个接口(interface)的类来破坏 Liskov 替换原则?

标签 java liskov-substitution-principle

给定以下类:

class Example implements Interface1, Interface2 {
    ...
}

当我使用 Interface1 实例化类时:

Interface1 example = new Example();

...那么我只能调用 Interface1 方法,而不能调用 Interface2 方法,除非我强制转换:

((Interface2) example).someInterface2Method();

当然,为了使这个运行时安全,我还应该用 instanceof 检查包装它:

if (example instanceof Interface2) {
    ((Interface2) example).someInterface2Method();
}

我知道我可以有一个包装器接口(interface)来扩展这两个接口(interface),但是我最终可以使用多个接口(interface)来满足同一类可以实现的所有可能的接口(interface)排列。有问题的接口(interface)不会自然地相互扩展,因此继承似乎也是错误的。

当我询问运行时实例以确定其实现时,instanceof/cast 方法是否会破坏 LSP?

我使用的任何实现似乎在设计或使用方面都有一些副作用。

最佳答案

I'm aware that I could have a wrapper interface that extends both interfaces, but then I could end up with multiple interfaces to cater for all the possible permutations of interfaces that can be implemented by the same class

我怀疑,如果您发现许多类实现了不同的接口(interface)组合,那么:您的具体类做得太多;或者(不太可能)你的界面太小太专业,以至于单独使用时毫无用处。

如果您有充分的理由让某些代码同时需要 Interface1Interface2 的东西,那么绝对可以继续制作一个扩展两者的组合版本。如果您很难为此想一个合适的名称(不,不是 FooAndBar),那么这表明您的设计是错误的。

绝对不要依赖转换任何东西。它只能作为最后的手段使用,并且通常只用于非常具体的问题(例如序列化)。

我最喜欢和最常用的设计模式是装饰器模式。因此,我的大多数类只会实现一个接口(interface)(除了更通用的接口(interface),例如 Comparable)。我会说,如果您的类经常/总是实现多个接口(interface),那么这就是代码异味。


如果您要实例化对象并在同一范围内使用它,那么您应该只是编写

Example example = new Example();

很清楚(我不确定这是否是你的建议),在任何情况你应该永远写这样的东西: p>

Interface1 example = new Example();
if (example instanceof Interface2) {
    ((Interface2) example).someInterface2Method();
}

关于java - 如何避免使用实现多个接口(interface)的类来破坏 Liskov 替换原则?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54184354/

相关文章:

Java,双向链表 : Is my logic wrong?

java - 在java中进行字符与字符匹配时出错

java - 可以将二维 double 组更改为输出字符串吗?

java - Java异常层次结构背后的基本原理

java - 对 Liskov 替换原则的合规性进行单元测试是一种好的做法吗?

java - 更改 ObjectMap 以存储在 json Libgdx 中

java - KeyListener/KeyListener 方法的标识符预期错误

C#接口(interface)实现关系只是 "Can-Do"关系?

oop - 导数的前置条件/​​后置条件规则

inheritance - 弱化前置条件和增强后置条件不也违反里氏替换原则吗?