Is it wrong trying to suppress overriding on a case by case basis? [closed]

99封情书 提交于 2019-12-02 11:41:16

My opinion would be generally no.

The reason is that it even if you could somehow make your FlyingCar behave only like it would if it were a Car from this point forward, it's still already been operated on as if it were a FlyingCar, and may no longer be in a valid state for a Car.

Maybe the reason your graphics engine can't display a FlyingCar is because of the textures it uses. But someone's already called a load_appropriate_textures method on it, which has stored its texture data inside it. Changing the FlyingCar into a Car would change what happened if you called load_appropriate_textures again, but FlyingCar doesn't override the render_car method, it just puts data where render_car will find it. So some other poor programmer in your organisation will just end up trying to debug why a Car is failing to render with some error message about FlyingCar textures.

Maybe that won't happen in this one particular case. But it could. And someone could modify Car and FlyingCar later in a way that introduces this sort of problem.

In general, to a FlyingCar "as if" it were a Car, you really have to repeat all the initialisation (and subsequent modifications) again. Repeating later modifications is generally not possible (because they're not recorded), and repeating the initialisation means nothing more than constructing a new Car.

So it seems like "in general" it's a bad idea. In any particular case, if you can find a way to do it, maybe you'll decide it's acceptable. Programmers make compromises every day, it happens. But if it's not possible to do this with full generality, then you always run the risk that later perfectly reasonable changes will be made to Car and/or FlyingCar that make your hacks no longer work.

Really, it sounds like FlyingCar needs to have the functionality to disable its flying functionality. Something like that is always really hard to bolt on after the fact.

You could use composition instead of inheritance (it sounds like your Car object needs to be refactored into smaller classes anyway: the Car object is huge).

The Car object could then contain a component that gives it the capability to fly. To disable the flying ability of the car you then just need to temporarily (or permanently if you want) remove the flying component from the Car object.

In general, when we create a FlyingCar, we ensure that we extend Car in a way that would work correctly. Hopefully we only rely on Car's interface that Car promises to keep unchanged; if we also rely on some other code in Car, we do it because we own the code.

On the other hand, this doesn't work in the opposite direction. When someone takes a FlyingCar tries to modify it to use it as a Car, there's no guarantee that things won't break, regardless of how careful the user is. After all, FlyingCar only promises that it will behave as a variant of Car if used as is; not that it will behave as Car after someone tries to takes some pieces out of it.

For example, FlyingCar might have modified the functions of various controls at construction. If its methods have been disabled, it won't become Car; it will be just broken.

To answer the question directly: yes, it would be wrong because suppressing certainn subclasses from being passed in would violate Liskov Substitution Principle

The fact that you are needing to do that is a strong smell that refractory may be in order...

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!