Inheritance 开闭原理与继承的区别
我知道开闭原理是指为扩展而开,为修改而关。考虑下面的例子:Inheritance 开闭原理与继承的区别,inheritance,polymorphism,abstraction,solid-principles,open-closed-principle,Inheritance,Polymorphism,Abstraction,Solid Principles,Open Closed Principle,我知道开闭原理是指为扩展而开,为修改而关。考虑下面的例子: public class Vehicle{ public void service(){ //vehicle servicing code } } public class Bike extends Vehicle{ public void service(){ // bike specific servicing } } 现在我了解到,Bike类扩展了Vehicl
public class Vehicle{
public void service(){
//vehicle servicing code
}
}
public class Bike extends Vehicle{
public void service(){
// bike specific servicing
}
}
现在我了解到,Bike
类扩展了Vehicle
,并使用开闭原理添加了新功能
考虑我创建
Vehicle
类的jar文件,然后Bike
类从jar扩展Vehicle
类。在这种情况下,我们不能修改Vehicle
类和Bike
扩展它。这是开闭原理的一个好例子吗?
我想知道OCP与继承有何不同OCP与继承没有什么不同,相反,OCP的“打开”部分是开放的,可以扩展,但应该关闭以进行修改。 也就是说,代码应该只针对错误/bug进行修改,但对于新的扩展或功能的更改,应该对其进行扩展
作为补充说明,我认为这最好放在programmers.stackexchange.com网站上。以下是我对解释OCP的看法: OCP指出,代码可以根据其更改的频率进行分类,“同一”代码的各个部分可以有不同的更改频率,我所说的更改不仅指随着时间的推移而更改,还指在运行时更改-例如,选择这段或那段特定的代码来执行某些操作 OCP要求将更稳定的代码与更可能更改的代码分开。但它并不止于此,它还要求更改频率较低的代码能够与更改频率较高的代码一起工作 那么OCP==继承呢?不,继承只是用于实现OCP的技术之一。策略模式、装饰模式、普通组合、参数多态性(又称泛型)和其他技术也可以用来实现这些目标 我所说的不同变化频率的例子。让我们设想一些集合实现。如果每次向语言中添加一些基元类型时,集合代码也需要更新,这不是很糟糕吗?因此,集合将其持有的项目视为不透明,从而实现OCP。下一个示例,让我们以上一个示例中相同的集合实现为例,设想我们要打印排序后的元素。简单。我们将只向集合中添加排序。。。。以及其他10种收集类型?而每一个新的集合也必须实现这种排序?可怕的。如果我们的排序算法只是将集合视为不透明类型,那么如果被要求,它会连续提供它的项,这不是更好吗?这是我们的排序需要集合做的唯一事情,一旦给出元素列表,它就可以进行实际的排序。好啊所以现在集合只需要支持一个连续返回所有项的操作。容易的。。。如果我们仔细想想,这是一个非常有用的行为,可以用于过滤、转换等 希望通过上面的例子,我展示了继承之外的一些OCP用法,并表明OCP还鼓励我们将代码视为不同抽象级别的组合(具有不同变化频率的代码组合)。问题:没有继承 让我们根据问题中给定的代码构建一个示例。不同的车辆以不同的方式进行维修。因此,我们对
自行车
和汽车
有不同的分类,因为维修自行车
的策略与维修汽车
的策略不同
车库
类接受各种车辆进行维修。遵守规范并查看车库
类如何违反开闭原则:
class Bike {
public void service() {
System.out.println("Bike servicing strategy performed.");
}
}
class Car {
public void service() {
System.out.println("Car servicing strategy performed.");
}
}
class Garage {
public void serviceBike(Bike bike) {
bike.service();
}
public void serviceCar(Car car) {
car.service();
}
}
正如您可能已经注意到的,无论何时维修诸如Truck
或Bus
之类的新车,都需要修改Garage
,以定义新方法serviceTruck()
和serviceBus()
。这意味着车库
类必须了解所有可能的车辆,如自行车
,汽车
,公共汽车
,卡车
等等。因此,它违反了开闭原则,开放进行修改。此外,它还不能扩展,因为要扩展新功能,我们需要更改它
解决方案:使用继承 抽象 为了解决上述代码中的问题并满足开闭原则,我们需要抽象出每种车型维修策略的实施细节。这意味着我们需要对
Bike
和Car
类进行抽象
多态性
我们还希望车库
类能够接受多种形式的车辆,比如公共汽车
,卡车
等等,而不仅仅是自行车
和汽车
。这意味着我们需要多态性(多种形式)
继承
因此,为了满足开闭原则,最重要的机制是抽象和多态性。在Java、C等静态类型语言中,提供抽象和多态性的重要工具是继承
为了抽象各种类型车辆维修策略的实施细节,我们使用了一个名为Vehicle
的接口
,并有一个抽象方法service()
对于Garage
类接受多种形式的Vehicle
,我们将其方法的签名更改为service(Vehicle-Vehicle){}
,以接受接口Vehicle
,而不是像Bike
这样的实际实现,Car
等。我们还从类中删除了多个方法,因为只有一个方法可以接受多种形式
interface Vehicle {
void service();
}
class Bike implements Vehicle {
@Override
public void service() {
System.out.println("Bike servicing strategy performed.");
}
}
class Car implements Vehicle {
@Override
public void service() {
System.out.println("Car servicing strategy performed.");
}
}
class Garage {
public void service(Vehicle vehicle) {
vehicle.service();
}
}
关闭以进行修改
正如您在上面的代码中所看到的,现在Garage
类已关闭以进行修改,因为现在它确实关闭了