1
1
Fork 0

Добавлены примеры к документации ООП

This commit is contained in:
Arthur 2020-03-03 18:29:47 +03:00 committed by Enchased Horse
parent 59a9eb4a3c
commit a4d9c3ca38
1 changed files with 217 additions and 0 deletions

217
oop.md
View File

@ -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();
}
}
```
[к оглавлению](#ООП)
## Что представляет собой обмен сообщениями»_?