Понимание основных концепций объектно-ориентированного программирования (ООП) очень важно для развития начинающего Java разработчика, поэтому в этой статье я вкратце пройдусь по каждому пункту и постараюсь максимально простым языком объяснить каждый из принципов.
Основные принципы ООП
- Абстракция
- Инкапсуляция
- Полиморфизм
- Наследование
- Ассоциация
- Агрегирование
- Композиция
А теперь подробнее о каждом:
Абстракция
Абстракция — сокрытие внутренних деталей и описание вещей простыми словами. Например, метод складывает два целых числа, его внутренняя логика сокрыта от внешнего мира: он просто принимает на вход два числа и на выходе выдает результат сложения. Есть много способов достижения абстракции в объектно-ориентированном программировании, например: инкапсуляция и наследование.
Любая программа на Java уже является отличным примером абстракции: Java сама заботится о преобразовании команд на машинный язык и скрывает детали реализации от внешнего мира.
Инкапсуляция
Инкапсуляция — метод достижения абстракции в объектно-ориентированном программировании. Инкапсуляция используется для ограничения доступа до членов класса и методов.
Одним из способов достижения инкапсуляции в ООП являются модификаторы доступа. Подробнее о модификаторах доступа в Java и как они влияют на инкапсуляцию читайте по ссылке.
Полиморфизм
Говоря простыми словами, полиморфизм дает возможность объекту вести себя по-разному в различных ситуациях. Есть два типа полиморфизма: полиморфизм в процессе компиляции и выполнения.
Полиморфизм в процессе компиляции достигается за счет перегрузки метода. Смотрим пример ниже:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
public class Printer { public void print() { System.out.println("Печатаем в консоль"); } public void print(int count) { System.out.println("Печатаем в консоль еще и какое-то значение: " + count); } public void print(int count, String string) { System.out.println("Печатаем в консоль какое-то значение:" + count + " и важную строку: " + string); } } |
Здесь у нас несколько условных методов печати, которые имеют различное поведение. Имена методов одинаковые, однако аргументы методов (сигнатура методов) различные — это и называется перегрузкой метода. Компилятор должен определить метод вызова именно во время компиляции, поэтому это и называется полиморфизмом времени компиляции.
Полиморфизм времени выполнения достигается, когда у нас есть отношения «IS-A» между объектами. Подкласс должен переопределить метод суперкласса для достижения полиморфизма времени выполнения. Если мы смотрим в контексте суперкласса, то фактическая реализация класса определяется во время выполнения. Компилятор не в состоянии решить какой метод класса будет вызван. Это решение будет принято во время выполнения программы, отсюда и название: полиморфизм времени выполнения.
Смотрим пример:
1 2 3 |
public interface Printable { public void print(); } |
1 2 3 4 5 6 7 |
public class Printer implements Printable{ @Override public void print() { System.out.println("Просто печать в консоль"); } } |
1 2 3 4 5 6 |
public class Logger implements Printable { @Override public void print() { System.out.println("Просто логгируем в консоль"); } } |
У нас есть 1 интерфейс и 2 класса, которые его реализуют, теперь посмотрим на полиморфизм времени выполнения:
1 2 3 4 5 6 7 8 9 |
public static void main(String[] args) { Printable pr = new Printer(); pr.print(); // в методе findPrintable() написана какая-то логика, // которая возвращает Printable Printable printable = findPrintable(); printable.print(); } |
В приведенном примере Java компилятор не знает точный класс, который реализует интерфейс. Это все будет определяться во время выполнения, следовательно, это пример полиморфизма времени выполнения.
Наследование
Наследование — одна из концепций объектно-ориентированного программирования, согласно которой один объект основывается на другом объекте. Наследование является механизмом повторного использования кода. Объект, которого унаследовали, называется суперклассом. Объект, который наследует суперкласс называется подклассом.
В Java использутся ключевое слово extends
для реализации наследования. Подробнее о наследовании в Java. Также рекомендую сравнительную статью Композиция vs Наследование.
Ассоциация
Ассоциация — концепция ООП, которая определяет отношения между объектами. Также ассоциация определяет кратность между объектами, например: объект Преподаватель и объекты Студенты. Отношение между преподавателем и учениками будет один ко многим. Точно так же студент может иметь один ко многим отношения с объектами преподавателей. Однако объект студент и объект преподаватель независимы друг от друга.
Агрегирование
Агрегирование представляет собой особый тип ассоциации. При агрегации объекты все также имеют свой жизненный цикл, однако ограничены отношением принадлежности «HAS-A», то есть отношение «часть-целое» между двумя объектами.
Композиция
Композиция представляет собой особую, более строгую форму агрегации. Это значит, что находящийся в отношениях «HAS-A» объект не может существовать сам по себе. Например, отношение «Дом-Комната» — здесь Комната не может существовать без Дома. Подробнее о композиции читайте в этой статье.
На этом краткий обзор концепций ООП завершен. Не упустил ли я чего-то важного в попытках сделать статью простой для понимания новичку? Если что — пишите в комментариях.