Java设计模式七大原则-里氏代换原则

简介: Java设计模式七大原则-里氏代换原则

里氏代换原则

1、里氏代换原则介绍


里氏代换原则(Liskov Substitution Principle, LSP):子类型必须能够替换掉它们的父类型。


一个软件实体如果使用的是一个父类的话,那么一定适用于其子类,而且它察觉不出父类对象和子类对象的区别。也就是说,在软件里面,把父类都替换成它的子类,程序的行为没有变化,简单地说,子类型必须能够替换掉它们的父类型。

这个原则主要是为了保证在使用继承时,子类能够替换掉父类,并且在不影响系统原有功能的前提下,增加新的功能。也就是说,如果一个程序是建立在一个父类的基础上,那么通过替换成其子类,程序仍然能够正常运行,并达到预期的结果。

里氏代换原则的关键在于子类重写父类的方法必须保证父类所定义的方法的前置条件、后置条件以及副作用在子类中仍然成立。也就是说,子类对父类的方法进行重写时,不应该改变原有的约定、规范和契约,否则可能会破坏原有的功能。

2、案例说明

class Rectangle {
    protected int width = 0;
    protected int height = 0;
    public void setWidth(int width) {
        this.width = width;
    }
    public void setHeight(int height) {
        this.height = height;
    }
    public int getWidth() {
        return width;
    }
    public int getHeight() {
        return height;
    }
    public int getArea() {
        return width * height;
    }
}
class Square extends Rectangle {
    public void setWidth(int width) {
        this.width = width;
        this.height = width;
    }
    public void setHeight(int height) {
        this.width = height;
        this.height = height;
    }
}
public class Main {
    public static void main(String[] args) {
        Rectangle r = new Square();
        r.setWidth(5);
        r.setHeight(10);
        System.out.println(r.getArea());
    }
}


在这个程序中,我们定义了一个矩形类和它的子类正方形。正方形是矩形的一种特殊情况,只不过长和宽相等而已。显然,正方形可以替换矩形的位置,但是,在这个例子中,如果我们以正方形对象来创建一个矩形对象的话,就会出现问题。因为矩形的宽和高是可以分别设置的,而正方形必须保证宽和高相等。由于正方形重写了父类矩形的设置宽、高的方法,因此矩形作为父类被替换成正方形的时候,就会出现宽高不符合期望的情况。


这个例子违反了LSP原则,因为父类与子类之间的行为不是完全一致的,父类中允许的某些操作在子类中并不适用。

3、使用LSP改进代码

abstract class Quadrilateral{
    protected int width = 0;
    protected int height = 0;
    public void setWidth(int width) {
        this.width = width;
    }
    public void setHeight(int height) {
        this.height = height;
    }
    public int getWidth() {
        return width;
    }
    public int getHeight() {
        return height;
    }
    public abstract int getArea();
}
class Rectangle extends Quadrilateral {
    public int getArea() {
        return width * height;
    }
}
class Square extends Quadrilateral {
    public void setWidth(int side) {
        this.width = side;
        this.height = side;
    }
    public void setHeight(int side) {
        this.width = side;
        this.height = side;
    }
    public int getArea() {
        return width * height;
    }
}
public class Main {
    public static void main(String[] args) {
        Quadrilateral q1 = new Rectangle();
        q1.setWidth(5);
        q1.setHeight(10);
        Quadrilateral q2 = new Square();
        q2.setWidth(5);
        System.out.println(q1.getArea());
        System.out.println(q2.getArea());
    }
}



在这个程序中,我们定义了一个抽象的四边形类Quadrilateral,并且让Rectangle和Square分别继承这个类。因为两个类都共享了它们所包含的行为(getArea)。Square类重写了setWidth和setHeight方法以确保高度和宽度相等。这样,我们就能够根据需要使用Rectangle或Square对象来进行运算而不会改变程序的表现和结果。


这个程序遵循了LSP原则,因为Quadrilateral类和它的子类之间所共享的行为是完全一致的。在使用子类时,程序得到的结果与使用父类时是一样的。

4、总结

LSP原则:子类应该能够完全替代父类,并且拥有父类所有的行为和属性。


优点:


提高了代码的复用性。由于子类可以完全替代父类,所以可以通过继承来实现代码的共享和复用。

增加了代码的可扩展性。如果需要添加新的功能或修改现有功能,可以通过创建新的子类或重写父类的方法来实现,而不必修改原有的代码。

方便了代码的维护。由于子类和父类之间具有一致性,所以在修复父类代码时,也会自动修复所有的子类。

降低了代码的耦合性。由于子类依赖于父类,而不是具体的实现,所以在修改父类时,不必担心会影响到其他的子类。

缺点:


可能导致代码过度设计。为了满足LSP原则,可能需要创建大量的抽象类和接口,这可能会导致代码过于复杂和难以理解。

可能导致性能下降。由于过多的抽象层次和接口,可能会导致程序的运行效率降低。

可能会出现类型转换问题。在某些情况下,子类可能无法完全替代父类,需要进行类型转换,这可能会导致运行时错误。

目录
相关文章
|
5天前
|
设计模式
设计模式七大原则
这篇文章介绍了设计模式中的七大原则,特别强调了单一职责原则,即一个类应该只有一个引起其行为变化的原因,以确保类功能的高内聚和低耦合。
|
4天前
|
设计模式 存储 前端开发
React开发设计模式及原则概念问题之自定义Hooks的作用是什么,自定义Hooks设计时要遵循什么原则呢
React开发设计模式及原则概念问题之自定义Hooks的作用是什么,自定义Hooks设计时要遵循什么原则呢
|
3天前
|
设计模式 算法 Java
Java编程中的设计模式:简化复杂性的艺术
在Java的世界中,设计模式如同一位智慧的导师,指引着开发者们在复杂的编码迷宫中找到出口。本文将深入浅出地探讨几种常见的设计模式,通过实例演示如何在Java项目实践中运用这些模式,从而提升代码的可维护性和扩展性。无论你是新手还是资深开发者,这篇文章都将为你打开一扇通往高效编码的大门。
12 1
|
6天前
|
设计模式 安全 Java
|
9天前
|
设计模式 算法 Java
Java中的设计模式:探索与实践
【8月更文挑战第10天】在Java开发中,设计模式是提升代码可读性、可维护性和扩展性的关键所在。本文将深入探讨几种常见的设计模式及其在实际项目中的应用,帮助开发者更好地理解和运用这些模式,以编写出更高质量的代码。
25 2
|
2天前
|
设计模式 存储 Java
掌握Java设计模式的23种武器(全):深入解析与实战示例
掌握Java设计模式的23种武器(全):深入解析与实战示例
|
4天前
|
设计模式 算法 开发者
设计模式问题之最小知识原则(迪米特法则)对代码设计有何影响,如何解决
设计模式问题之最小知识原则(迪米特法则)对代码设计有何影响,如何解决
|
4天前
|
设计模式 前端开发 JavaScript
React开发设计模式及原则概念问题之什么是HOC(Higher-order component),HOC遵循的设计原则都有哪些
React开发设计模式及原则概念问题之什么是HOC(Higher-order component),HOC遵循的设计原则都有哪些
|
4天前
|
设计模式 前端开发 JavaScript
React开发设计模式及原则概念问题之什么是设计模式,单一职责原则如何理解
React开发设计模式及原则概念问题之什么是设计模式,单一职责原则如何理解
|
5天前
|
设计模式 安全 Java
怎样才能学好 Java 设计模式?
本文探讨了在软件开发中对设计模式的常见误解。许多人认为设计模式过于抽象难以学习,或是应用场景有限难以在复杂的业务环境中应用,甚至有人误以为所有问题都能通过设计模式解决。实际上,设计模式旨在解决特定范围内的面向对象设计问题,如提高代码的可复用性。为了正确理解和应用设计模式,需要摆正心态、深入了解其背景知识、培养独立思考的习惯,并坚持不懈地学习和实践。通过这些方法,开发者可以更好地掌握设计模式,从而在实际项目中做出更加合理的设计决策。