Добавлены примеры к документации ООП
This commit is contained in:
parent
59a9eb4a3c
commit
a4d9c3ca38
217
oop.md
217
oop.md
|
@ -48,6 +48,37 @@ __Инкапсуляция__ – это свойство системы, поз
|
|||
|
||||
>Теперь вернёмся в сегодняшний день к современным чудесам автопрома с коробкой-автоматом. На самом деле, по сути, ничего не изменилось. Бензонасос всё так же поставляет бензин в двигатель, дифференциалы обеспечивают поворот колёс на различающиеся углы, коленвал превращает поступательное движение поршня во вращательное движение колёс. Прогресс в другом. Сейчас все эти действия скрыты от пользователя и позволяют ему крутить руль и нажимать на педаль газа, не задумываясь, что в это время происходит с инжектором, дроссельной заслонкой и распредвалом. Именно сокрытие внутренних процессов, происходящих в автомобиле, позволяет эффективно его использовать даже тем, кто не является профессионалом-автомехаником с двадцатилетним стажем. Это сокрытие в ООП носит название инкапсуляции.
|
||||
|
||||
Пример:
|
||||
```java
|
||||
public class SomePhone {
|
||||
|
||||
private int year;
|
||||
private String company;
|
||||
public SomePhone(int year, String company) {
|
||||
this.year = year;
|
||||
this.company = company;
|
||||
}
|
||||
private void openConnection(){
|
||||
//findComutator
|
||||
//openNewConnection...
|
||||
}
|
||||
public void call() {
|
||||
openConnection();
|
||||
System.out.println("Вызываю номер");
|
||||
}
|
||||
|
||||
public void ring() {
|
||||
System.out.println("Дзынь-дзынь");
|
||||
}
|
||||
|
||||
}
|
||||
```
|
||||
Модификатор private делает доступными поля и методы класса только внутри данного класса. Это означает, что получить доступ к private полям из вне невозможно, как и нет возможности вызвать private методы.
|
||||
|
||||
Сокрытие доступа к методу openConnection, оставляет нам также возможность к свободному изменению внутренней реализации этого метода, так как этот метод гарантированно не используется другими объектами и не нарушит их работу.
|
||||
|
||||
Для работы с нашим объектом мы оставляем открытыми методы call и ring с помощью модификатора public. Предоставление открытых методов для работы с объектом также является частью механизма инкапсуляции, так как если полностью закрыть доступ к объекту – он станет бесполезным.
|
||||
|
||||
[к оглавлению](#ООП)
|
||||
|
||||
## Что такое _«наследование»_?
|
||||
|
@ -61,6 +92,56 @@ __Наследование__ – это свойство системы, поз
|
|||
|
||||
>Очевидно, что все три модификации будут иметь большинство свойств прежней модели (старый добрый двигатель 1970 года, непробиваемая ходовая часть, зарекомендовавшая себя отличным образом на отечественных дорогах, коробку передач и т.д.). При этом каждая из моделей будет реализовать некоторую новую функциональность или конструктивную особенность. В данном случае, мы имеем дело с наследованием.
|
||||
|
||||
Пример:
|
||||
Рассмотрим пример создания класса смартфон с помощью наследования. Все беспроводные телефоны работают от аккумуляторных батарей, которые имеют определенный ресурс работы в часах. Поэтому добавим это свойство в класс беспроводных телефонов:
|
||||
```java
|
||||
public abstract class WirelessPhone extends AbstractPhone {
|
||||
|
||||
private int hour;
|
||||
|
||||
public WirelessPhone(int year, int hour) {
|
||||
super(year);
|
||||
this.hour = hour;
|
||||
}
|
||||
}
|
||||
```
|
||||
Сотовые телефоны наследуют свойства беспроводного телефона, мы также добавили в этот класс реализацию методов call и ring:
|
||||
```java
|
||||
public class CellPhone extends WirelessPhone {
|
||||
public CellPhone(int year, int hour) {
|
||||
super(year, hour);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void call(int outputNumber) {
|
||||
System.out.println("Вызываю номер " + outputNumber);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void ring(int inputNumber) {
|
||||
System.out.println("Вам звонит абонент " + inputNumber);
|
||||
}
|
||||
}
|
||||
```
|
||||
И, наконец, класс смартфон, который в отличие от классических сотовых телефонов имеет полноценную операционную систему. В смартфон можно добавлять новые программы, поддерживаемые данной операционной системой, расширяя, таким образом, его функциональность. С помощью кода класс можно описать так:
|
||||
```java
|
||||
public class Smartphone extends CellPhone {
|
||||
|
||||
private String operationSystem;
|
||||
|
||||
public Smartphone(int year, int hour, String operationSystem) {
|
||||
super(year, hour);
|
||||
this.operationSystem = operationSystem;
|
||||
}
|
||||
|
||||
public void install(String program){
|
||||
System.out.println("Устанавливаю " + program + "для" + operationSystem);
|
||||
}
|
||||
|
||||
}
|
||||
```
|
||||
Как видите, для описания класса Smartphone мы создали совсем немного нового кода, но получили новый класс с новой функциональностью. Использование этого принципа ООП java позволяет значительно уменьшить объем кода, а значит, и облегчить работу программисту.
|
||||
|
||||
[к оглавлению](#ООП)
|
||||
|
||||
## Что такое _«полиморфизм»_?
|
||||
|
@ -79,6 +160,112 @@ _Полиморфная переменная_, это переменная, ко
|
|||
+ _ad hoc_, функция ведет себя по разному для разных типов аргументов (например, функция `draw()` — рисует по разному фигуры разных типов);
|
||||
+ _параметрический_, функция ведет себя одинаково для аргументов разных типов (например, функция `add()` — одинаково кладет в контейнер элементы разных типов).
|
||||
|
||||
Принцип в ООП, когда программа может использовать объекты с одинаковым интерфейсом без информации о внутреннем устройстве объекта, называется полиморфизмом.
|
||||
|
||||
Пример:
|
||||
|
||||
Давайте представим, что нам в программе нужно описать пользователя, который может пользоваться любыми моделями телефона, чтобы позвонить другому пользователю. Вот как можно это сделать:
|
||||
|
||||
```java
|
||||
public class User {
|
||||
private String name;
|
||||
|
||||
public User(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public void callAnotherUser(int number, AbstractPhone phone) {
|
||||
// вот он полиморфизм - использование в коде абстактного типа AbstractPhone phone!
|
||||
phone.call(number);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Теперь опишем различные модели телефонов. Одна из первых моделей телефонов:
|
||||
```java
|
||||
public class ThomasEdisonPhone extends AbstractPhone {
|
||||
|
||||
public ThomasEdisonPhone(int year) {
|
||||
super(year);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void call(int outputNumber) {
|
||||
System.out.println("Вращайте ручку");
|
||||
System.out.println("Сообщите номер абонента, сэр");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void ring(int inputNumber) {
|
||||
System.out.println("Телефон звонит");
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Обычный стационарный телефон:
|
||||
|
||||
```java
|
||||
public class Phone extends AbstractPhone {
|
||||
|
||||
public Phone(int year) {
|
||||
super(year);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void call(int outputNumber) {
|
||||
System.out.println("Вызываю номер" + outputNumber);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void ring(int inputNumber) {
|
||||
System.out.println("Телефон звонит");
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
И, наконец, крутой видеотелефон:
|
||||
|
||||
```java
|
||||
public class VideoPhone extends AbstractPhone {
|
||||
|
||||
public VideoPhone(int year) {
|
||||
super(year);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void call(int outputNumber) {
|
||||
System.out.println("Подключаю видеоканал для абонента " + outputNumber);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void ring(int inputNumber) {
|
||||
System.out.println("У вас входящий видеовызов..." + inputNumber);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Создадим объекты в методе main() и протестируем метод callAnotherUser:
|
||||
|
||||
```java
|
||||
AbstractPhone firstPhone = new ThomasEdisonPhone(1879);
|
||||
AbstractPhone phone = new Phone(1984);
|
||||
AbstractPhone videoPhone=new VideoPhone(2018);
|
||||
User user = new User("Андрей");
|
||||
user.callAnotherUser(224466,firstPhone);
|
||||
// Вращайте ручку
|
||||
//Сообщите номер абонента, сэр
|
||||
user.callAnotherUser(224466,phone);
|
||||
//Вызываю номер 224466
|
||||
user.callAnotherUser(224466,videoPhone);
|
||||
//Подключаю видеоканал для абонента 224466
|
||||
```
|
||||
|
||||
Используя вызов одного и того же метода объекта user, мы получили различные результаты. Выбор конкретной реализации метода call внутри метода callAnotherUser производился динамически на основании конкретного типа вызывающего его объекта в процессе выполнения программы. В этом и заключается основное преимущество полиморфизма – выбор реализации в процессе выполнения программы.
|
||||
|
||||
В примерах классов телефонов, приведенных выше, мы использовали переопределение методов – прием, при котором изменяется реализация метода, определенная в базовом классе, без изменения сигнатуры метода. По сути это является заменой метода, и именно новый метод, определенный в подклассе, вызывается при выполнении программы.
|
||||
|
||||
Обычно, при переопределении метода, используется аннотация @Override, которая подсказывает компилятору о необходимости проверить сигнатуры переопределяемого и переопределяющего методов.
|
||||
|
||||
[к оглавлению](#ООП)
|
||||
|
||||
## Что такое _«абстракция»_?
|
||||
|
@ -86,6 +273,36 @@ _Абстрагирование_ – это способ выделить наб
|
|||
|
||||
>Представьте, что водитель едет в автомобиле по оживлённому участку движения. Понятно, что в этот момент он не будет задумываться о химическом составе краски автомобиля, особенностях взаимодействия шестерёнок в коробке передач или влияния формы кузова на скорость (разве что, автомобиль стоит в глухой пробке и водителю абсолютно нечем заняться). Однако, руль, педали, указатель поворота он будет использовать регулярно.
|
||||
|
||||
Пример:
|
||||
```java
|
||||
// Abstract class
|
||||
abstract class Animal {
|
||||
// Abstract method (does not have a body)
|
||||
public abstract void animalSound();
|
||||
|
||||
// Regular method
|
||||
public void sleep() {
|
||||
System.out.println("Zzz");
|
||||
}
|
||||
}
|
||||
|
||||
// Subclass (inherit from Animal)
|
||||
class Pig extends Animal {
|
||||
public void animalSound() {
|
||||
// The body of animalSound() is provided here
|
||||
System.out.println("The pig says: wee wee");
|
||||
}
|
||||
}
|
||||
|
||||
class MyMainClass {
|
||||
public static void main(String[] args) {
|
||||
Pig myPig = new Pig(); // Create a Pig object
|
||||
myPig.animalSound();
|
||||
myPig.sleep();
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
[к оглавлению](#ООП)
|
||||
|
||||
## Что представляет собой _«обмен сообщениями»_?
|
||||
|
|
Loading…
Reference in New Issue