Объектно-ориентированное программирование (ООП)
В этой статье, как и во всех на моем сайте, я постараюсь упростить объяснения и без того сложных вещей и сделать упор на практику. Безусловно, если вы хотите стать профессиональным разработчиком 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 у второго экземпляра. Именно это свойство и называется полиморфизмом!
Полиморфизм
Конкретный код, выполняемый при вызове метода объекта (экземпляра) определяется классом объекта, находящегося по ссылке в момент исполнения программы


