
OOP with examples (part 2)
By fate, I have to read a special course on design patterns at a university. The special course is required, therefore, students come to me very different. Of course, there are practicing programmers among them. But, unfortunately, most have difficulty even understanding the basic OOP terms.
To do this, I tried on more or less lively examples to explain the basic concepts of OOP (class, object, interface, abstraction, encapsulation, inheritance, and polymorphism).
The first part is devoted to classes, objects, and interfaces.
The second part, presented below, illustrates encapsulation, polymorphism, and inheritance.
Imagine for a moment that we were at the end of the century before last, when Henry Ford had not yet come up with an assembly line, and the first attempts to create a car came across criticism from the authorities that these smoking monsters pollute the air and scare horses. Imagine that to control the first steam engine it was necessary to know how the steam boiler is arranged, constantly toss coal, monitor the temperature, water level. In this case, to turn the wheels, use two levers, each of which turns one wheel separately. I think we can agree with the fact that driving a car of that time was very uncomfortable and difficult.
Now back to the modern wonders of the car industry with automatic gearbox. In fact, in fact, nothing has changed. The gas pump still delivers gasoline to the engine, differentials provide rotation of the wheels at different angles, the crankshaft turns the translational movement of the piston into the rotational movement of the wheels. Progress is different. Now all these actions are hidden from the user and allow him to turn the steering wheel and step on the gas pedal, without thinking what happens to the injector, throttle and camshaft at this time. It is the concealment of the internal processes that take place in the car that makes it possible to use it effectively even for those who are not professional auto mechanics with twenty years of experience. This concealment in OOP is called encapsulation.
Encapsulation- This is a property of the system that allows you to combine data and methods that work with them in a class and hide
implementation details from the user.
Encapsulation is inextricably linked with the concept of a class interface. In fact, everything that is not included in the interface is encapsulated in the class.
Imagine a driver driving a car through a busy traffic area. It is clear that at this moment he will not think about the chemical composition of the car’s paint, the peculiarities of the interaction of gears in the gearbox or the influence of the body shape on speed (unless the car is in a dead traffic jam and the driver has absolutely nothing to do). However, he will use the steering wheel, pedals, direction indicator (and, possibly, an ashtray) regularly.
Abstraction is a way to highlight a set of significant characteristics of an object, excluding insignificant ones from consideration. Accordingly, abstraction is a collection of all such characteristics.
If we had to take into account the chemical composition of the body paint and the specific heat of the room light bulb to model the car’s behavior, we would never know what NFS is.
Any training in driving would not make sense if a person who had learned to drive, say, a VAZ 2106 could not then drive a VAZ 2110 or BMW X3. On the other hand, it is difficult to imagine a person who could normally drive a car in which the gas pedal is to the left of the brake pedal, and instead of the steering wheel is a joystick.
The thing is that the main controls of the car have the same design and principle of operation. The driver knows for sure that in order to turn left, he must turn the steering wheel, regardless of whether there is a power steering there or not.
If a person needs to get home from work, he will drive a car and perform the same actions, regardless of what type of car he uses. In fact, we can say that all cars have the same interface, and the driver, abstracting from the essence of the car, works with this interface. If the driver has to drive along the German autobahn, he will probably choose a fast car with a low landing, and if he has to return from a remote maralnik in Gorny Altai after rain, most likely an UAZ with army bridges will be chosen. But, regardless of how the movement and internal functioning of the machine will be implemented, the interface will remain the same.
Polymorphism- this is a property of the system to use objects with the same interface without information about the type and internal structure of the object.
For example, if you are reading data from a file, then obviously, in a class that implements a file stream, there will be a method similar to the following: byte [] readBytes (int n);
Suppose now that you need to read the same data from a socket. A class that implements a socket will also have a readBytes method . It is enough to replace in your system an object of one class with an object of another class, and the result will be achieved.
Moreover, the system logic can be implemented regardless of whether the data is read from a file or received over the network. Thus, we abstract from the specific specialization of data acquisition and work at the interface level. The only requirement is that each object used has a readBytes method .
Imagine yourself, for a moment, as the engineers of an automobile factory. Our task is to develop a modern car. We already have the previous model, which has proven itself over many years of use. Everything would be fine, but times and technologies are changing, and our modern plant should strive to increase the convenience and comfort of its products and meet modern standards.
We need to release a whole range of cars: sedan, station wagon and subcompact hatchback. Obviously, we are not going to design a new car from scratch, but, taking the previous generation as a basis, we will introduce a number of design changes. For example, add a power steering and reduce the gaps between the wings and the bonnet, put fog lights. In addition, the shape of the body will be changed in each model.
Obviously, all three modifications will have most of the properties of the previous model (the good old engine of 1970, an impenetrable chassis that has proven itself in excellent ways on domestic roads, a gearbox, etc.). In addition, each of the models will implement some new functionality or design feature. In this case, we are dealing with inheritance.
Inheritance is a property of the system that allows you to describe a new class on the basis of an existing one with partially or fully borrowed functionality. The class from which the inheritance is derived is called the base or parent. The new class is a descendant, descendant, or derived class.
It should be noted that the derived class fully meets the specification of the parent, but may have additional functionality. In terms of interfaces, each derived class fully implements the interface of the parent class. The converse is not true.
Indeed, in our example, we could perform the same actions with new cars as with the old one: increase or decrease speed, turn, turn on the turn signal. However, in addition, we would have the opportunity, for example, to turn on fog lights.
The lack of backward compatibility means that we should not expect from the old model a correct reaction to such actions as the inclusion of foglights (which simply are not in this model).
To do this, I tried on more or less lively examples to explain the basic concepts of OOP (class, object, interface, abstraction, encapsulation, inheritance, and polymorphism).
The first part is devoted to classes, objects, and interfaces.
The second part, presented below, illustrates encapsulation, polymorphism, and inheritance.
Encapsulation
Imagine for a moment that we were at the end of the century before last, when Henry Ford had not yet come up with an assembly line, and the first attempts to create a car came across criticism from the authorities that these smoking monsters pollute the air and scare horses. Imagine that to control the first steam engine it was necessary to know how the steam boiler is arranged, constantly toss coal, monitor the temperature, water level. In this case, to turn the wheels, use two levers, each of which turns one wheel separately. I think we can agree with the fact that driving a car of that time was very uncomfortable and difficult.
Now back to the modern wonders of the car industry with automatic gearbox. In fact, in fact, nothing has changed. The gas pump still delivers gasoline to the engine, differentials provide rotation of the wheels at different angles, the crankshaft turns the translational movement of the piston into the rotational movement of the wheels. Progress is different. Now all these actions are hidden from the user and allow him to turn the steering wheel and step on the gas pedal, without thinking what happens to the injector, throttle and camshaft at this time. It is the concealment of the internal processes that take place in the car that makes it possible to use it effectively even for those who are not professional auto mechanics with twenty years of experience. This concealment in OOP is called encapsulation.
Encapsulation- This is a property of the system that allows you to combine data and methods that work with them in a class and hide
implementation details from the user.
Encapsulation is inextricably linked with the concept of a class interface. In fact, everything that is not included in the interface is encapsulated in the class.
Abstraction
Imagine a driver driving a car through a busy traffic area. It is clear that at this moment he will not think about the chemical composition of the car’s paint, the peculiarities of the interaction of gears in the gearbox or the influence of the body shape on speed (unless the car is in a dead traffic jam and the driver has absolutely nothing to do). However, he will use the steering wheel, pedals, direction indicator (and, possibly, an ashtray) regularly.
Abstraction is a way to highlight a set of significant characteristics of an object, excluding insignificant ones from consideration. Accordingly, abstraction is a collection of all such characteristics.
If we had to take into account the chemical composition of the body paint and the specific heat of the room light bulb to model the car’s behavior, we would never know what NFS is.
Polymorphism
Any training in driving would not make sense if a person who had learned to drive, say, a VAZ 2106 could not then drive a VAZ 2110 or BMW X3. On the other hand, it is difficult to imagine a person who could normally drive a car in which the gas pedal is to the left of the brake pedal, and instead of the steering wheel is a joystick.
The thing is that the main controls of the car have the same design and principle of operation. The driver knows for sure that in order to turn left, he must turn the steering wheel, regardless of whether there is a power steering there or not.
If a person needs to get home from work, he will drive a car and perform the same actions, regardless of what type of car he uses. In fact, we can say that all cars have the same interface, and the driver, abstracting from the essence of the car, works with this interface. If the driver has to drive along the German autobahn, he will probably choose a fast car with a low landing, and if he has to return from a remote maralnik in Gorny Altai after rain, most likely an UAZ with army bridges will be chosen. But, regardless of how the movement and internal functioning of the machine will be implemented, the interface will remain the same.
Polymorphism- this is a property of the system to use objects with the same interface without information about the type and internal structure of the object.
For example, if you are reading data from a file, then obviously, in a class that implements a file stream, there will be a method similar to the following: byte [] readBytes (int n);
Suppose now that you need to read the same data from a socket. A class that implements a socket will also have a readBytes method . It is enough to replace in your system an object of one class with an object of another class, and the result will be achieved.
Moreover, the system logic can be implemented regardless of whether the data is read from a file or received over the network. Thus, we abstract from the specific specialization of data acquisition and work at the interface level. The only requirement is that each object used has a readBytes method .
Inheritance
Imagine yourself, for a moment, as the engineers of an automobile factory. Our task is to develop a modern car. We already have the previous model, which has proven itself over many years of use. Everything would be fine, but times and technologies are changing, and our modern plant should strive to increase the convenience and comfort of its products and meet modern standards.
We need to release a whole range of cars: sedan, station wagon and subcompact hatchback. Obviously, we are not going to design a new car from scratch, but, taking the previous generation as a basis, we will introduce a number of design changes. For example, add a power steering and reduce the gaps between the wings and the bonnet, put fog lights. In addition, the shape of the body will be changed in each model.
Obviously, all three modifications will have most of the properties of the previous model (the good old engine of 1970, an impenetrable chassis that has proven itself in excellent ways on domestic roads, a gearbox, etc.). In addition, each of the models will implement some new functionality or design feature. In this case, we are dealing with inheritance.
Inheritance is a property of the system that allows you to describe a new class on the basis of an existing one with partially or fully borrowed functionality. The class from which the inheritance is derived is called the base or parent. The new class is a descendant, descendant, or derived class.
It should be noted that the derived class fully meets the specification of the parent, but may have additional functionality. In terms of interfaces, each derived class fully implements the interface of the parent class. The converse is not true.
Indeed, in our example, we could perform the same actions with new cars as with the old one: increase or decrease speed, turn, turn on the turn signal. However, in addition, we would have the opportunity, for example, to turn on fog lights.
The lack of backward compatibility means that we should not expect from the old model a correct reaction to such actions as the inclusion of foglights (which simply are not in this model).