Объектно-ориентированное программирование (ООП)
В этой статье, как и во всех на моем сайте, я постараюсь упростить объяснения и без того сложных вещей и сделать упор на практику. Безусловно, если вы хотите стать профессиональным разработчиком Java, то вам необходимо иметь намного глубже понимание ООП. Рекомендую к изучению книгу Object-Oriented Software Construction от Bertrand Meyer на более чем 1200 страниц.
Эволюция подходов
Стремление писать более сложные программы меньшими усилиями стало движущей силой эволюции подходов в написании программ.
- Машинные коды
- Ассемблер
- Структурное программирование
- Функциональное программирование
- ООП
Введение в ООП
Объект является экземпляром класса. Класс общее описание, из чего должен состоять экземпляр класса. Экземпляр класса это конкретное описание класса.
В примере ниже существует класс Client,
package com.bouncer77.io; import java.time.LocalDate; public class Client { private String name; private LocalDate birthday; private Gender gender; enum Gender { NOT_SET("null"), MALE("male"), FEMALE("female"); String gender; Gender(String gender) { this.gender = gender; } } Client(String name, String birthday, Gender gender) { this.name = name; this.birthday = LocalDate.parse("2018-05-05"); this.gender = gender; } @Override public String toString() { final StringBuilder sb = new StringBuilder("Client{"); sb.append("name='").append(name).append('\''); sb.append(", birthday=").append(birthday); sb.append(", gender=").append(gender); sb.append('}'); return sb.toString(); } public String getName() { return name; } public void setName(String name) { this.name = name; } public static void main(String[] args) { String name = "Oleg"; String birthday = "1995-05-05"; Gender gender = Gender.MALE; Client client = new Client(name, birthday, gender); System.out.println(client); client.setName("Ivan"); System.out.println(client); } }
Client{name='Oleg', birthday=2018-05-05, gender=MALE} Client{name='Ivan', birthday=2018-05-05, gender=MALE}
Для генерации Конструктора, Сеттеров, Геттеров, Перегрузки метода toString в IntelliJ IDEA используется сочетание клавиш Alt+Insert
Термины ООП
Термин | Описание |
---|---|
Инкапсуляция | Объединение данных и методов в классе |
Сокрытие данных | Сокрытие данных от изменения с помощью модификаторов private, protected или отсутствия модификатора (видимость в пакете) |
Наследование | Унаследованный класс получает все признаки базового класса, так же можно переопределить обработку метода |
Полиморфизм | Конкретный код выполняемый при вызове метода определяется классом объекта находящегося по ссылке в момент исполнения программы. |
Наследование
Класс VipClient унаследован от класса Client. При вызове метода toString у экземпляра класса VipClient помимо информации о клиенте выведется так же VIP статус клиента.
package com.bouncer77.io; public class VipClient extends Client { VipClient(String name, String birthday, Gender gender) { super(name, birthday, gender); } @Override public String toString() { System.out.println("VIP"); return super.toString(); } }
public static void main(String[] args) { Client client = new Client("Oleg", "1995-05-05", Gender.MALE); VipClient vipClient = new VipClient("Ivan", "1997-05-05", Gender.MALE); System.out.println(client); System.out.println(); System.out.println(vipClient); }
Client{name='Oleg', birthday=2018-05-05, gender=MALE} VIP Client{name='Ivan', birthday=2018-05-05, gender=MALE}
Полиморфизм
Сменим у членов класса Client модификатор private
на protected
, теперь они доступны в классе VipClient, так как класс VipClient наследует класс Client.
protected String name; protected LocalDate birthday; protected Gender gender;
Так же обновим переопределенного метода toString в классе VipClient. Это позволит нам увидеть, какой именно метод будет вызываться при обращение к экземпляру класса — метод базового (Client) или текущего класса (VipClient)
@Override public String toString() { final StringBuilder sb = new StringBuilder("VipClient{"); sb.append("name='").append("VIP ").append(name).append('\''); sb.append(", birthday=").append(birthday); sb.append(", gender=").append(gender); sb.append('}'); return sb.toString(); }
Добавим два экземпляра классов Client и VipClient в коллекцию List и выведем результат в стандартный поток вывода
public static void main(String[] args) { Client client = new Client("Oleg", "1995-05-05", Gender.MALE); VipClient vipClient = new VipClient("Ivan", "1997-05-05", Gender.MALE); List<Client> clientList = new ArrayList<>(Arrays.asList(client, vipClient)); System.out.println(clientList); }
[Client{name='Oleg', birthday=2018-05-05, gender=MALE}, VipClient{name='VIP Ivan', birthday=2018-05-05, gender=MALE}]
У обоих экземпляров был вызван метод toString — видим, что в коллекции предполагается наличие элементов Client, но по факту был вызван метод VipClient у второго экземпляра. Именно это свойство и называется полиморфизмом!
Полиморфизм
Конкретный код, выполняемый при вызове метода объекта (экземпляра) определяется классом объекта, находящегося по ссылке в момент исполнения программы