JavaRush /Java Blog /Random EN /OOP principles

OOP principles

Published in the Random EN group
Hello! Have you ever wondered why Java is designed the way it is? In the sense that you create classes, based on them - objects, classes have methods, etc. But why is the structure of the language such that programs consist of classes and objects, and not of something else? Why was the concept of “object” invented and put at the forefront? Do all languages ​​work this way and, if not, what benefits does it give Java? As you can see, there are a lot of questions :) Let's try to answer each of them in today's lecture.

OOP principles:

  1. Inheritance
  2. Abstraction
  3. Encapsulation
  4. Polymorphism

What is object-oriented programming (OOP)

Of course, Java is made up of objects and classes for a reason. This is not a whim of its creators, or even their invention. There are many other languages ​​that are based on objects. The first such language was called Simula, and it was invented back in the 1960s in Norway. Among other things, Simula introduced the concepts of “ class ” and “ method ”. Principles of object-oriented programming - 2
Kristen Nygaard and Ole Johan Dahl - creators of Simula
It would seem that Simula is an ancient language by programming standards, but their “family” connection with Java is visible to the naked eye. Most likely, you can easily read the code written on it and explain in general terms what it does :)
Begin
  Class Rectangle (Width, Height); Real Width, Height;

   Begin
      Real Area, Perimeter;

      Procedure Update;
      Begin
        Area := Width * Height;
              OutText("Rectangle is updating, Area = "); OutFix(Area,2,8); OutImage;
        Perimeter := 2*(Width + Height);
              OutText("Rectangle is updating, Perimeter = "); OutFix(Perimeter,2,8); OutImage;
      End of Update;

      Update;
      OutText("Rectangle created: "); OutFix(Width,2,6);
      OutFix(Height,2,6); OutImage;
   End of Rectangle;

       Rectangle Class ColouredRectangle (Color); Text Color;

  Begin
      OutText("ColouredRectangle created, color = "); OutText(Color);
      OutImage;
        End of ColouredRectangle;


         Ref(Rectangle) Cr;
   Cr :- New ColouredRectangle(10, 20, "Green");
End;
The code example is taken from the article Simula - 50 years of OOP . As you can see, Java and its ancestor are not so different from each other :) This is due to the fact that the appearance of Simula marked the birth of a new concept - object-oriented programming. Wikipedia gives the following definition of OOP: Object-oriented programming (OOP) is a programming methodology based on representing a program as a collection of objects, each of which is an instance of a specific class, and the classes form an inheritance hierarchy. It is, in my opinion, very successful. You recently started learning Java, but there are hardly any words in it that are unfamiliar to you :) Today, OOP is the most common programming methodology. Besides Java, OOP principles are used in many popular languages ​​that you may have heard of. These are C++ (it is actively used by computer game developers), Objective-C and Swift (they write programs for Apple devices), Python (most in demand in machine learning), PHP (one of the most popular web development languages), JavaScript (simpler say what they don’t do on it) and many others. Actually, what are these “principles” of OOP? Let's tell you in more detail.

OOP principles

This is the basics. 4 main features that together form the object-oriented programming paradigm. Understanding them is the key to becoming a successful programmer. Principles of object-oriented programming - 3

Principle 1. Inheritance

The good news is that you are already familiar with some of the principles of OOP! :) We've already encountered inheritance a couple of times in lectures, and we've had time to work with it. Inheritance is a mechanism that allows you to describe a new class based on an existing (parent) one. In this case, the properties and functionality of the parent class are borrowed by the new class. Why is inheritance necessary and what benefits does it provide? First of all, code reuse. Fields and methods described in parent classes can be used in descendant classes. If all types of cars have 10 common fields and 5 identical methods, you just need to put them in the parent class Auto. You can use them in descendant classes without any problems. Solid advantages: both quantitatively (less code) and, as a result, qualitatively (classes become much simpler). At the same time, the inheritance mechanism is very flexible, and you can add the missing functionality in the descendants separately (some fields or behavior specific to a particular class). In general, as in ordinary life: we are all similar to our parents in some ways, but different from them in some ways :)

Principle 2. Abstraction

This is a very simple principle. Abstraction means highlighting the main, most significant characteristics of an object and vice versa - discarding secondary, insignificant ones. Let's not reinvent the wheel and remember an example from an old lecture about classes. Let's say we are creating a file cabinet of company employees. To create employee objects, we wrote a class Employee. What characteristics are important for their description in the company file? Full name, date of birth, social security number, tax identification number. But it’s unlikely that in a card of this type we need his height, eye and hair color. The company does not need this information about the employee. Therefore, for the class Employeewe will set the variables String name, int age, int socialInsuranceNumberand int taxNumber, and we will abandon information that is unnecessary for us, such as eye color, and abstract it. But if we create a catalog of photo models for an agency, the situation changes dramatically. To describe a fashion model, height, eye color and hair color are very important to us, but the TIN number is not needed. Therefore, in the class Modelwe create variables String height, String hair, String eyes.

Principle 3: Encapsulation

We have already encountered it. Encapsulation in Java means limiting access to data and the ability to change it. As you can see, it is based on the word “capsule”. In this “capsule” we hide some important data for us that we don’t want anyone to change. A simple example from life. You have a first and last name. Everyone you know knows them. But they do not have access to change your first and last name. This process, one might say, is “encapsulated” in the passport office: you can only change your first and last name there, and only you can do it. Other “users” have read-only access to your first and last name :) Another example is the money in your apartment. Leaving them in plain sight in the middle of the room is not a good idea. Any “user” (a person who comes to your home) will be able to change the number of your money, i.e. pick them up. It's better to encapsulate them in a safe. Only you will have access and only with a special code. Obvious examples of encapsulation that you've already worked with are access modifiers ( private, publicetc.) and getter-setters. If the ageclass field Catis not encapsulated, anyone can write:
Cat.age = -1000;
And the encapsulation mechanism allows us to protect the field agewith a setter method, in which we can put a check that the age cannot be a negative number.

Principle 4. Polymorphism

Polymorphism is the ability to treat multiple types as if they were the same type. In this case, the behavior of objects will differ depending on the type to which they belong. Sounds a bit complicated? Let's figure it out now. Let's take the simplest example - animals. Let's create a class Animalwith a single method - voice(), and two of its descendants - Catand Dog.
public class Animal {

   public void voice() {

       System.out.println("Voice!");
   }
}

public class Dog extends Animal {


   @Override
   public void voice() {
       System.out.println("Bow-wow!");
   }
}

public class Cat extends Animal {

   @Override
   public void voice() {
       System.out.println("Meow!");
   }
}
Now let's try to create a link Animaland assign it an object Dog.
public class Main {

   public static void main(String[] args) {

       Animal dog = new Dog();
       dog.voice();
   }
}
Which method do you think will be called? Animal.voice()or Dog.voice()? The class method will be called Dog: Woof-woof! We created a reference Animal, but the object behaves like Dog. If necessary, he can behave like a cat, horse or other animal. The main thing is to assign a reference of a general type Animalto an object of a specific descendant class. This is logical, because all dogs are animals. This is what we meant when we said “objects will behave differently depending on what type they are.” If we were to create an object Cat
public static void main(String[] args) {

   Animal cat = new Cat();
   cat.voice();
}
the method voice()would output "Meow!" What does “the ability to work with several types as if they were the same type” mean? This is also quite easy. Let's imagine that we are creating a hairdressing salon for animals. Our hair salon must be able to cut all animals, so we will create a method shear()(“cut”) with a parameter Animal- the animal that we will cut.
public class AnimalBarbershop {

   public void shear(Animal animal) {

       System.out.println("The haircut is ready!");
   }
}
And now we can pass shearboth objects Catand objects to the method Dog!
public static void main(String[] args) {

   Cat cat = new Cat();
   Dog dog = new Dog();

   AnimalBarbershop barbershop = new AnimalBarbershop();

   barbershop.shear(cat);
   barbershop.shear(dog);
}
Here is a clear example: the class AnimalBarbershopworks with types Catas Dogif they were the same type. At the same time, they have Catdifferent Dogbehavior: they use their voices differently.

Reasons for the emergence of OOP

Why did this new programming concept - OOP - even arise ? Programmers had tools that worked: procedural languages, for example. What prompted them to invent something fundamentally new? First of all, the complication of the tasks they faced. If 60 years ago a programmer’s task looked like “calculate a mathematical equation such and such,” now it may sound like “implement 7 different endings for the game STALKER depending on what decisions the user made in game moments A, B, C, D, E, F and combinations of these solutions." The tasks, as you can see, have clearly become more complex over the past decades. This means that data types have become more complex. This is another reason for the emergence of OOP. The example with the equation can be easily solved using ordinary primitives; no objects are needed here. But it will be difficult to even describe the problem with the endings of the game without using some classes you have invented. But at the same time, it is quite easy to describe it in classes and objects: we will obviously need the Game class, the Stalker class, the Ending class, the Player’s Decision class, the Game Moment class, and so on. That is, even without starting to solve a problem, we can easily imagine “sketches” of its solution in our heads. The increasing complexity of problems has forced programmers to divide the problem into parts. But in procedural programming this was not so easy. And very often the program was a “tree” of a bunch of branches with all possible options for its operation. Depending on certain conditions, the program was executed along one branch or another. For small programs this option was convenient, but dividing a large task into parts was very difficult. This need became another reason for the emergence of OOP. This concept gave programmers the ability to divide a program into a bunch of “modules” of classes, each of which did its own part of the job. All objects, interacting with each other, form the work of our program. In addition, the code we write can be reused elsewhere in the program, which also saves a lot of time.
Comments
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION