首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Liskov替代原理与界面隔离原理

Liskov替代原理与界面隔离原理
EN

Stack Overflow用户
提问于 2019-12-17 10:26:27
回答 1查看 748关注 0票数 3

我在理解这两个原则方面有一些困难。这是个读起来有点长的问题,所以耐心点。

假设我们有一个类

代码语言:javascript
复制
abstract class Shape {
    abstract void onDraw();
}

和接口

代码语言:javascript
复制
interface SideCountable {
  int getSidesCount();
}

然后我们创建了两个子类

代码语言:javascript
复制
class Quad extends Shape {

   @Override
   public void onDraw() {
   //some draw logic here
   }
}

class Triangle extends Shape {

   @Override
   public void onDraw() {
   //some draw logic here
   }
}

现在我们将让Shape实现SideCountable

代码语言:javascript
复制
abstract class Shape implements SideCountable{
    abstract void onDraw();
}

在儿童班做些改变

代码语言:javascript
复制
class Quad extends Shape {

   @Override
   public int getSidesCount() {
       return 4;
   }

   @Override
   public void onDraw() {
   //some draw logic here
   }
}

class Triangle extends Shape {

   public int getSidesCount() {
       return 3;
   }

   public void onDraw() {
   //some draw logic here
   }
}

并为该结构创建测试函数(以下LSP):

代码语言:javascript
复制
public void printSidesCount(List<Shape> shapes) {
    for(int i=0; i < shapes.size(); i++) {
        System.out.println(shapes.get(i).getSidesCount());
    }
}

在这里,我想停下来,因为实际上,在下一步,我被塞了下来。如果我们要创建一个三级Circle呢?

代码语言:javascript
复制
class Circle extends Shape {

   public int getSidesCount() {
       return ???;
   }

   @Override
   public void onDraw() {
   //some draw logic here
   }
}

圆圈没有任何方面,所以为这个孩子实现SideCountable听起来很可笑。好的,我们只可以将实现移到Quad和三角形,但在这种情况下,LSP将不再工作。有人能描述一下我该怎么做吗?

principle?

  • Move
  • Shape类中离开SideCountable,返回0表示Circle和中断接口隔离,SideCountableQuadTriangle,破坏LSP原则?

F 222

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2019-12-17 10:34:33

首先,您的方法printSidesCount只需要知道列表中包含SideCountable对象。因此,给出它的参数,类型List<Shape>比必要时更具体。给它一个List<SideCountable>代替:

代码语言:javascript
复制
public void printSidesCount(List<SideCountable> sideCountables) {
    for(int i=0; i < (); i++) {
        System.out.println(sideCountables.get(i).getSidesCount());
    }
}

甚至还有List<? extends SideCountable>,意思是“实现SideCountable的任意未知类型的列表”:

代码语言:javascript
复制
public void printSidesCount(List<? extends SideCountable> sideCountables) {
    for(int i=0; i < sideCountables.size(); i++) {
        System.out.println(sideCountables.get(i).getSidesCount());
    }
}

如果不是所有形状都有可数个边框,那么类Shape不应该实现接口SideCountable。相反,使类QuadTriangle除了扩展类Shape之外,还实现接口SideCountable

代码语言:javascript
复制
class Quad extends Shape implements SideCountable {
    // ...
}

class Triangle extends Shape implements SideCountable {
    // ...
}

使类Circle扩展Shape,但不实现SideCountable

代码语言:javascript
复制
class Circle extends Shape { // Not SideCountable
    // ...
}

当您这样做时,类型系统将帮助您:

因为实现SideCountable

  • you不能将List<Circle>传递给printSidesCount,所以您可以将List<Quad>List<Triangle>传递给printSidesCount,这是很好的,因为尝试这样做对圆圈

列表没有意义。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/59372197

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档