一文讲解Java中的重载、重写及里氏替换原则

提到重载和重写,Java小白应该都不陌生,接下来就通过这篇文章来一起回顾复习下吧!

重载和重写有什么区别呢?

  • 如果一个类有多个名字相同但参数不同的方法,我们通常称这些方法为方法重载Overload。如果方法的功能是一样的,但参数不同,使用相同的名字可以提高程序的可读性;
  • 如果子类具有和父类一样的方法,也就是参数相同、返回类型相同、方法名相同, 但方法体可能不同,我们就将其称为重写Override。方法重写用于提供父类已经声明的方法的特殊实现,是实现多态的基础条件;
  • 方法重载发生在同一个类中,同名的方法如果有不同的参数,也就是参数类型不同、参数个数不同或者二者都不同;
  • 方法重写发生在子类与父类之间,要求子类与父类具有相同的返回类型,方法名和参数列表,并且不能比父类的方法声明更多的异常,遵守里氏替换原则;

OK,那么接下来就普及下里氏替换原则;

  • 里氏替换原则Liskov Substitution Principle, LSP,这个原则规定任何父类可以出现的地方,子类一定也可以出现;
  • LSP是继承复用的基石,只有当子类可以替换掉父类,并且单位功能不受到影响时,父类才能真正被复用,而子类也能够在父类的基础上增加新的行为;
  • 这意味着子类在扩展父类时,不应该改变父类原有的行为。例如,如果有一个方法接受一个父类对象作为参数,那么传入该方法的任何子类对象也应该能正常工作;
java 复制代码
class Bird {
    void fly() {
        System.out.println("鸟正在飞");
    }
}

class Duck extends Bird {
    @Override
    void fly() {
        System.out.println("鸭子正在飞");
    }
}

class Ostrich extends Bird {
    // Ostrich违反了LSP,因为鸵鸟不会飞,但却继承了会飞的鸟类
    @Override
    void fly() {
        throw new UnsupportedOperationException("鸵鸟不会飞");
    }
}

在这个例子中,Ostrich(鸵鸟)类违反了 LSP 原则,因为它改变了父类 Bird 的行为(即飞行)。设计时应该更加谨慎地使用继承关系,确保遵守 LSP 原则。

除了李氏替换原则外,还有其他几个重要的面向对象设计原则,它们共同构成了 SOLID 原则,分别是:

  1. 单一职责原则(Single Responsibility Principle, SRP),指一个类应该只有一个引起它变化的原因,即一个类只负责一项职责。这样做的目的是使类更加清晰,更容易理解和维护。

  2. 开闭原则(Open-Closed Principle, OCP),指软件实体应该对扩展开放,对修改关闭。这意味着一个类应该通过扩展来实现新的功能,而不是通过修改已有的代码来实现。

    举个例子,在不遵守开闭原则的情况下,有一个需要处理不同形状的绘图功能类。

    java 复制代码
    class ShapeDrawer {
        public void draw(Shape shape) {
            if (shape instanceof Circle) {
                drawCircle((Circle) shape);
            } else if (shape instanceof Rectangle) {
                drawRectangle((Rectangle) shape);
            }
        }
        
        private void drawCircle(Circle circle) {
            // 画圆形
        }
        
        private void drawRectangle(Rectangle rectangle) {
            // 画矩形
        }
    }

    每增加一种形状,就需要修改一次 draw 方法,这违反了开闭原则。正确的做法是通过继承和多态来实现新的形状类,然后在 ShapeDrawer 中添加新的 draw 方法。

    java 复制代码
    // 抽象的 Shape 类
    abstract class Shape {
        public abstract void draw();
    }
    
    // 具体的 Circle 类
    class Circle extends Shape {
        @Override
        public void draw() {
            // 画圆形
        }
    }
    
    // 具体的 Rectangle 类
    class Rectangle extends Shape {
        @Override
        public void draw() {
            // 画矩形
        }
    }
    
    // 使用开闭原则的 ShapeDrawer 类
    class ShapeDrawer {
        public void draw(Shape shape) {
            shape.draw();  // 调用多态的 draw 方法
        }
    }
  3. 接口隔离原则(Interface Segregation Principle, ISP),指客户端不应该依赖它不需要的接口。这意味着设计接口时应该尽量精简,不应该设计臃肿庞大的接口。

  4. 依赖倒置原则(Dependency Inversion Principle, DIP),指高层模块不应该依赖低层模块,二者都应该依赖其抽象;抽象不应该依赖细节,细节应该依赖抽象。这意味着设计时应该尽量依赖接口或抽象类,而不是实现类。

相关推荐
夏天的味道٥4 小时前
使用 Java 执行 SQL 语句和存储过程
java·开发语言·sql
冰糖码奇朵5 小时前
大数据表高效导入导出解决方案,mysql数据库LOAD DATA命令和INTO OUTFILE命令详解
java·数据库·sql·mysql
好教员好5 小时前
【Spring】整合【SpringMVC】
java·spring
浪九天6 小时前
Java直通车系列13【Spring MVC】(Spring MVC常用注解)
java·后端·spring
堕落年代7 小时前
Maven匹配机制和仓库库设置
java·maven
功德+n7 小时前
Maven 使用指南:基础 + 进阶 + 高级用法
java·开发语言·maven
香精煎鱼香翅捞饭8 小时前
java通用自研接口限流组件
java·开发语言
ChinaRainbowSea8 小时前
Linux: Centos7 Cannot find a valid baseurl for repo: base/7/x86_64 解决方案
java·linux·运维·服务器·docker·架构
囧囧 O_o8 小时前
Java 实现 Oracle 的 MONTHS_BETWEEN 函数
java·oracle
去看日出8 小时前
RabbitMQ消息队列中间件安装部署教程(Windows)-2025最新版详细图文教程(附所需安装包)
java·windows·中间件·消息队列·rabbitmq