继承优于标签

来源:互联网 发布:软件导刊 核心期刊 编辑:程序博客网 时间:2024/04/30 11:25

在开发中,我们经常会遇到一种情形:有的类,根据不同的属性(Tag),可以表现出不同的行为。比如:我们有一个图形类Figure,它可以表现圆形Circle、矩形Rectangle。你会怎么设计呢?

标签

一般情况下,我们会显式的添加一个额外的标签,来表示此时的Figure需要表现的行为

/** * 使用标签 */public class TagFigure {    private enum Shape {        RECTANGLE,        CIRCLE    }    private Shape shape;    //RECTANGLE    private double length;    private double width;    //CIRCLE    private double radius;    public TagFigure(double radius) {        this.radius = radius;        this.shape = Shape.CIRCLE;    }    public TagFigure(double length, double width) {        this.length = length;        this.width = width;        this.shape = Shape.RECTANGLE;    }    public double area() {        switch (shape) {            case CIRCLE:                return length * width;            case RECTANGLE:                return Math.PI * radius * radius;            default:                throw new AssertionError();        }    }}

这里,我们是给Figure添加了一个标签Shape通过不同的Shape值,来表现出不同的行为area

继承

实际上,我们还可以有另一种更有拓展性的做法,那就是使用继承\

设计一个基类BaseFigure

/** * 使用继承 */public abstract class BaseFigure {    public abstract double area();}

子类Circle

public class Circle extends BaseFigure {    private double radius;    public Circle(double radius) {        this.radius = radius;    }    @Override    public double area() {        return Math.PI * radius * radius;    }}

子类Rectangle

public class Rectangle extends BaseFigure {    private double length;    private double width;    public Rectangle(double length, double width) {        this.length = length;        this.width = width;    }    @Override    public double area() {        return length * width;    }}

总结

通过将一个TagFigure分解成了三个类:BaseFigure、Circle、Rectangle。可以更好的表示类型之间本质上的层次关系

如果之后需要一个三角形Triangle:
使用标签的话,你可能要改的地方就很多了,需要修改已有代码。
使用继承的话,只需要再写一个类继承BaseFigure即可,无需修改已有代码。

以后,当你想要编写一个带有标签的类时,不妨考虑用继承来替代

不过,使用继承时,一定要考虑好类之间的关系:

表示是什么类型,用继承
表示有什么行为,用接口

天然鱼的简书

0 0
原创粉丝点击