5

While learning about OOP, I have noticed that a lot of the tutorials give examples of objects such as Car objects and Dog objects, but I don't know if these kind of objects are used in real life programs.

I think they may be used in a game for example, so if a game have cars and dogs in it, it would use Car objects and Dog objects, but other than games, are these kind of objects used in real life programs?

2
  • 4
    The biggest problem with learning OOP is that only "toy systems" are small enough to explain without a lot of domain-specific knowledge or information. So the usual examples in textbooks are in danger of being trivialized to the level where they are almost pointless. A "real-world" application may have hundreds of classes representing objects (or parts of objects) and thousands of methods.
    – alephzero
    Oct 18, 2020 at 21:46
  • Hi, Car and Dog are not important, what is important is that they are concepts/things see here: people.cs.aau.dk/~normark/oop-csharp/html/notes/… Nov 11, 2020 at 20:30

6 Answers 6

11

Yes. Software is used in all sorts of fields of endevour. People who work with dogs or with cars may well use software to help them manage the information they need for their jobs, and in some cases those software programs will include Car and Dog objects.

For instance software to manage a car repair shop, or a vetinary surgery or kennel, or to design road systems.

Of course in many of these business cases the objects do not attempt to simulate the dog or the car, but to model how it actually exists in the world and how it relates to the organisation running the software.

8

Object Oriented programming was initially created for the purpose of simulations. If you have something like a simulation of traffic patterns, you might have Car-objects in the simulation. But outside the scope of simulation software, you probably wouldn't.

In my opinion, OO tutorials is just creating confusion by using simulation examples, since most OO software is not about simulations. For example the management software for a car dealership might have a Car-object, but the car object wouldn't have drive() or turn() methods, since these objects are not actual cars, just records for inventory management.

2
  • 4
    I would say the Car objects in the management software of a car dealership do represent actual cars. It is just that within the context of that software, it is not relevant that a car can drive. Oct 18, 2020 at 13:08
  • I bet there are turn and drive methods in this codebase: theverge.com/2020/10/23/21530411/…
    – dmcgill50
    Oct 23, 2020 at 19:09
4

No, Car and Dog are usually just used for illustrative purposes, especially for explaining inheritance.

However, programs must model the real world, or more precisely: relevant aspects of the problem domain. Object-Oriented Analysis and Design and Domain-Driven Design often involve taking concepts from the problem domain and representing them as objects. For example, an inventory management system for car dealerships might very well have different Vehicle and Car classes.

But object-oriented techniques are most appropriate not to describe is-a inheritance relationships, but behaves-like compatibility. That is: just looking at data like “A vehicle has wheels. A car is-a vehicle and thus inherits wheels” is not that useful in practice. Describing behaviour like “A dog can makeNoise(). A cat can makeNoise(). Both dog and cat behave like an animal” is often more useful.

So OOP shines more in systems with complex behaviours, in particular GUIs and business rules. But there are alternatives:

  • pure data modelling is often better suited to a relational model (as in SQL databases) than to an object-oriented model
  • very complex and dynamic behaviours do not benefit from language-level OOP support as implemented in Java, but often have to be implemented manually – especially in games
  • nowadays, data flows and events in complex GUI applications are often managed with reactive programming instead of OOP
2

I come originally from games programming and while it might seem to fit to have mammals and animals and so forth as abstract concepts in a game engine, I've found fewer worst cases than games where you want to obliterate all those abstractions and reach around them.

The problem in my opinion is with the concept of "is". A proper inheritance hierarchy that conforms to principles like Lisksov substitution revolves around the concept of substitutability. Yet we don't want to downcast away the abstraction down to the concrete, but we don't want the concrete details to leak into the abstraction. So we're trying to determine what something can do based on what it roughly is, but not what it actually is. Yet what is "roughly is" isn't often enough information to do what we want to do with it (ex: determine if two animals can reproduce with each other), but what "actually is" gets us too far, since there might be many things that aren't "actually "are that thing but have the same functionality available, so why should we have to check and sprinkle redundant code in our codebase?

If we want to model human intuition, then the functionality that things have are never based on what they "are". It's based on what they "have". A biped with crippled legs can't walk upright. It doesn't matter that is a form of biped, or that bipeds can usually walk. A broken microwave can't heat food up even if it's a type of microwave. A mute human can't talk. It doesn't matter that they are human. It's based on what things "have", not what they "are", that determines what they are capable or incapable of doing. It's based on having functional legs that can allow something to walk.

The broad problem I find with inheritance which narrows its most natural applicability to limited contexts is that it wants to say what things can do based on what they "are", not what they "have". And that can get us reaching for the most granular concept of determing is something is a form of "IWalkable", to determine if something can walk, when we're really just concerned if they "have" functional legs. And inheriting/implementing from IWalkable typically removes the ability from being able to remove it at runtime if a person trips over a rock and breaks both of their legs.

What is a dragon, you know? Is it a type of bird? A type of reptile? Both? Neither? If we have an established inheritance hierarchy, we might debate for ages. Or maybe we don't and still try to base it on interfaces like it's "IQuadruped", and "IFlyable", and "IFireBreathable". But what if its wings are crippled? We can debate endlessly, and we're trying to reach a wavelength with the rest of the team. And in my opinion, the reason that connection is elusive is that we're focusing on what it "is". How about we talk about what a dragon "has"? It can have, at least initially, super-strong scales, wings that allow it to fly, four legs that can allow it to walk on the ground, some internal engine that allows it to breathe fire. We probably won't debate too much on what it "has". And we can leverage much more in the way of polymorphism if we revolve it all around what it "has", not what it "is", without changing our minds later.

1
  • But to answer the question, in my domain, not so much. When we use inheritance hierarchies, they're usually shallow and designed to benefit from virtual dispatch in cases where subtype states vary in terms of size. We don't use deep inheritance hierarchies, and we don't use them so much to try to map to human intuitions.
    – user377672
    Oct 19, 2020 at 19:43
0

The only real reason in OO software to specialise a type is to change its behaviour.

It seems unlikely that the IT system of a garage will have any difference in behaviour between a car, a van or a truck, or that a vet's system will have a difference in behaviour between dog or other animals. Usually there will be differences in values in a field to indicate vehicle type or species.

Simulation systems tend to break entities into multiple facets, so again the difference between a vehicle which is a car and a vehicle which is a truck would be in value, but often those values will be specialised decorators

If you had a software specialised to a very specific car or dog related purpose, you might call the entity 'car' or 'dog' rather than 'customer's vehicle' or 'patient animal', but you then wouldn't have any inheritance, as the domain you're dealing with is narrowed to just cars or dogs.

That said, I have seen OO inheritance used for other purposes, for example a model of the space shuttle where multiple inheritance was used to combine components, so the shuttle inherited from its left wing and its right wing and so on. I'm sure such a programmer could come up with a real world case where dog and car inherit from something else, or maybe each other.

0

As others have said, Car and Dog are simplified examples for illustration--real world examples are going to be far too complex to be in your textbook.

Consider a real world example--my job involves a program that has an object Report. A Report has a bunch of logic for reading in reports off disk and for obtaining information from what it has read--but a Report can't actually read anything nor store anything. There are half a dozen different types of Report each with their own parser, storage and lookup routines, but the exact type is read from a configuration file and used to decide which subclass to create, then never looked at again. All the code that uses the data simply works with a Report with no idea what type of report it is. Reports have a number of items in them, some report-wide named fields and each line has named fields. The field names likewise come from the configuration.

Not the answer you're looking for? Browse other questions tagged or ask your own question.