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.
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 :)
OOP principles:
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 ”.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.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 classAuto
. 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 classEmployee
. 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 Employee
we will set the variables String name
, int age
, int socialInsuranceNumber
and 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 Model
we 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
, public
etc.) and getter-setters. If the age
class field Cat
is not encapsulated, anyone can write:
Cat.age = -1000;
And the encapsulation mechanism allows us to protect the field age
with 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 classAnimal
with a single method - voice()
, and two of its descendants - Cat
and 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 Animal
and 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 Animal
to 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 shear
both objects Cat
and 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 AnimalBarbershop
works with types Cat
as Dog
if they were the same type. At the same time, they have Cat
different Dog
behavior: they use their voices differently.
GO TO FULL VERSION