提到重载和重写,Java小白应该都不陌生,接下来就通过这篇文章来一起回顾复习下吧!
重载和重写有什么区别呢?
- 如果一个类有多个名字相同但参数不同的方法,我们通常称这些方法为方法重载Overload。如果方法的功能是一样的,但参数不同,使用相同的名字可以提高程序的可读性;
- 如果子类具有和父类一样的方法,也就是参数相同、返回类型相同、方法名相同, 但方法体可能不同,我们就将其称为重写Override。方法重写用于提供父类已经声明的方法的特殊实现,是实现多态的基础条件;
- 方法重载发生在同一个类中,同名的方法如果有不同的参数,也就是参数类型不同、参数个数不同或者二者都不同;
- 方法重写发生在子类与父类之间,要求子类与父类具有相同的返回类型,方法名和参数列表,并且不能比父类的方法声明更多的异常,遵守里氏替换原则;
OK,那么接下来就普及下里氏替换原则;
- 里氏替换原则Liskov Substitution Principle, LSP,这个原则规定任何父类可以出现的地方,子类一定也可以出现;
- LSP是继承复用的基石,只有当子类可以替换掉父类,并且单位功能不受到影响时,父类才能真正被复用,而子类也能够在父类的基础上增加新的行为;
- 这意味着子类在扩展父类时,不应该改变父类原有的行为。例如,如果有一个方法接受一个父类对象作为参数,那么传入该方法的任何子类对象也应该能正常工作;
class Bird {void fly() {System.out.println("鸟正在飞");}
}class Duck extends Bird {@Overridevoid fly() {System.out.println("鸭子正在飞");}
}class Ostrich extends Bird {// Ostrich违反了LSP,因为鸵鸟不会飞,但却继承了会飞的鸟类@Overridevoid fly() {throw new UnsupportedOperationException("鸵鸟不会飞");}
}
在这个例子中,Ostrich(鸵鸟)类违反了 LSP 原则,因为它改变了父类 Bird 的行为(即飞行)。设计时应该更加谨慎地使用继承关系,确保遵守 LSP 原则。
除了李氏替换原则外,还有其他几个重要的面向对象设计原则,它们共同构成了 SOLID 原则,分别是:
-
单一职责原则(Single Responsibility Principle, SRP),指一个类应该只有一个引起它变化的原因,即一个类只负责一项职责。这样做的目的是使类更加清晰,更容易理解和维护。
-
开闭原则(Open-Closed Principle, OCP),指软件实体应该对扩展开放,对修改关闭。这意味着一个类应该通过扩展来实现新的功能,而不是通过修改已有的代码来实现。
举个例子,在不遵守开闭原则的情况下,有一个需要处理不同形状的绘图功能类。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 方法。
// 抽象的 Shape 类 abstract class Shape {public abstract void draw(); }// 具体的 Circle 类 class Circle extends Shape {@Overridepublic void draw() {// 画圆形} }// 具体的 Rectangle 类 class Rectangle extends Shape {@Overridepublic void draw() {// 画矩形} }// 使用开闭原则的 ShapeDrawer 类 class ShapeDrawer {public void draw(Shape shape) {shape.draw(); // 调用多态的 draw 方法} }
-
接口隔离原则(Interface Segregation Principle, ISP),指客户端不应该依赖它不需要的接口。这意味着设计接口时应该尽量精简,不应该设计臃肿庞大的接口。
-
依赖倒置原则(Dependency Inversion Principle, DIP),指高层模块不应该依赖低层模块,二者都应该依赖其抽象;抽象不应该依赖细节,细节应该依赖抽象。这意味着设计时应该尽量依赖接口或抽象类,而不是实现类。