Are you trying to suppress redefinition in each case?

I understand why the polymorphism achieved through method overrides is very useful. I ask what problems can arise when trying to suppress it in certain situations when a polymorphic object is taken as an argument (and not during its definition!).

class Car describes the behavior of a car. FlyingCar class describes the behavior of a car that can transform and fly.

I got an object of class Car or its subclass from somewhere. I can’t control what they pass on to me.

I know that due to the technical limitations of my graphics engine, I cannot display a flying machine. Or maybe I want the player to complete a specific mission without using the flight capabilities. Thus, I thought to simply disable the ability of the car to fly, making it look like an object of class Car. I was thinking about using downcasting , but it doesn't seem to work.

It may not be possible, but if I find a way to do it in the language I use, is this a bad design? If so, why and what is the alternative?

I can’t use something like a copy constructor to create an object of class Car from what I got, because the resulting copy of all data is too expensive (the Car object is huge).

Thanks!

EDIT:

I want to avoid choosing a specific language in this matter. When I choose a language, the answer may be “technically impossible” or “possible, but the required hack is too dangerous”, etc.

I want to understand if this design is bad for reasons other than the ability (in) of a particular language to support it.

0
source share
4 answers

My opinion, as a rule, will not.

The reason is that even if you could somehow make your FlyingCar behave as if it were a car from this point forward, it was still working on as if it were a FlyingCar, and maybe more not be in the correct condition for the car.

Perhaps the reason your graphics engine cannot display the FlyingCar is due to the textures it uses. But someone already called the load_appropriate_textures method on it, which saved their texture data in it. Changing the FlyingCar to the car will change what happened if you load_appropriate_textures again, but FlyingCar does not override the render_car method, it just puts the data where render_car finds it. Therefore, some other bad programmers in your organization just end up trying to debug why the car cannot display with some FlyingCar error message.

Perhaps this will not happen in this particular case. But it could be. And someone can modify Car and FlyingCar later in a way to introduce such a problem.

In general, for FlyingCar “as if” it was a car, you really need to repeat all initialization (and subsequent modifications) again. Repetition of later changes is usually impossible (because they are not recorded), and repetition of initialization means nothing more than the creation of a new car.

So it seems that “in general” is a bad idea. In any case, if you can find a way to do this, you may decide that this is acceptable. Programmers make compromises every day, this happens. But if this cannot be done with complete generality, then you always risk that quite reasonable changes will be made in Car and / or FlyingCar later that will make your hacks more inoperative.

Indeed, it seems that FlyingCar needs functionality to disable its flight functionality. Something like this is always very difficult to fix after the fact.

+1
source

You can use composition instead of inheritance (it looks like your Car object should be reorganized into smaller classes: the Car object is huge ).

A Car object may contain a component that enables it to fly. To disable the car’s flying abilities, you just need to temporarily (or permanently, if you want) remove the flying component from the Car object.

0
source

In general, when we create a FlyingCar, we guarantee that we will expand the car so that it works correctly. Hopefully we rely only on the Car interface that Car promises will remain unchanged; if we also rely on some other code in Car, we do this because we have code.

On the other hand, this does not work in the opposite direction. When someone takes a FlyingCar, tries to change it to use it as a car, there is no guarantee that everything will not break, no matter how careful the user is. In the end, FlyingCar only promises that it will behave as an option for a car if it is used as is; not that he will behave like a car after someone tries to extract some pieces from him.

For example, FlyingCar may have changed the functions of various controls during construction. If his methods were disabled, it would not become Auto; it will just be broken.

0
source

To answer the question directly: yes, that would be wrong, because suppressing some subclasses passed inside would violate the Liskov replacement principle

The fact that you need to do this is a strong odor that can be in a gunshot state ...

0
source

Source: https://habr.com/ru/post/1390701/


All Articles