Попытка собрать и связать между собой разные сведения о понятии объекта в ООП.

Сначала были структуры:
struct point_xyz { int x; int y; int z; };
Но по мере роста размера и сложности программ возникло новое понятие — объект.
Собственно, можно из всего множества определений объекта выделить два понятия:
а) объект как «данные и методы работы с ними» и б) «объект как сущность (организм)».
Первый вариант понятия объекта наиболее распространен, второй встречается реже.
Появились основные принципы ООП (выделяют от 3 и более принципов):
1) Инкапуляция
2) Наследование
3) Полиморфизм
4) Абстракция
5) Посылка сообщений
6) Повторное использование
Главный тут самый первый принцип — инкапсуляция.
Но будем идти по порядку. Для примеров далее будем использовать Java, как наиболее типичный представитель мира ООП.
I) Структура:

public class Person { public String fistName; public String secondName; public String middleName; }
Так, конечно, мало кто пишет. Минусы очевидны — любое значение меняется извне без каких либо ограничений. Об объекте речи быть не может. Здесь никакой инкапсуляции нет — это структура. Данные без коробочки.
Но есть и плюсы — объем кода. Никаких мешающих взгляду геттеров и сеттеров. Например, структуры можно использовать в виде внутренних классов, получая доступ к полям без геттеров и сеттеров, спасая код от захламления.
Посмотрите как сделан внутренний класс Node. По-моему, очень красиво.
Можно переделать класс Person и использовать его как внутренний в каком-то другом классе:
public class Foo { private class Person { private String fistName; private String secondName; private String middleName; } }
II) «Улучшенная структура» — это структура с геттерами и сеттерами.

public class Person { private String fistName; private String secondName; private String middleName; public String getFistName() { return fistName; } public void setFistName(String fistName) { this.fistName = fistName; } public String getSecondName() { return secondName; } public void setSecondName(String secondName) { this.secondName = secondName; } public String getMiddleName() { return middleName; } public void setMiddleName(String middleName) { this.middleName = middleName; } }
Можем ли мы назвать это объектом? С одной стороны мы обеспечили сокрытие полей класса. Теперь к ним можно получить доступ из других классов только через методы. Это во многих случаях дает дополнительную гибкость. Например, можно отсеивать невалидные значения.
Формально определение «данные и методы работы с ними» соблюдено. С другой стороны, инкапсуляция подразумевает целостность данных. Данные, заключенные в «коробочку», должны быть целостны, какие бы извне методы не вызывались. А у нас при вызове сеттеров в какой-то момент может получится что целостность будет нарушена. Например, будем переименовывать Ивана Ивановича Иванова в Елену Петровну Сидорову. После вызова первого сеттера получим Елену Ивановича Иванова.
Где такие вещи используются? Везде. К сожалению. Это глупая коробочка для данных, во многих случаях не поддерживающая их целостность.
III) Объект с инкапсуляцией

public class Person { private final String fistName; private final String secondName; private final String middleName; public Fio(String fistName, String secondName, String middleName) { this.fistName = fistName; this.secondName = secondName; this.middleName = middleName; } public String getFistName() { return fistName; } public String getSecondName() { return secondName; } public String getMiddleName() { return middleName; } }
Ну теперь по крайней мере объект всегда в целостном состоянии. Елену Ивановича Иванова не получим в качестве промежуточного результата. Кроме того, объект стал не изменяемым — что огромный плюс, в том числе для многопоточной работы. Первому определению объекта соответствуем. Это очень умная коробочка для данных — она поддерживает их целостность. Но это все равно коробочка.
IV) Объект-организм
public class Person { private String fistName; private String secondName; private String middleName; public Person(String fistName, String secondName, String middleName) { this.fistName = fistName; this.secondName = secondName; this.middleName = middleName; } public void sayName(PrintStream printStream) { if (middleName == null) printStream.print(fistName + " " + secondName); else printStream.print(fistName + " " + middleName + " " + secondName); } }
Убираем геттеры, сеттеры. Объект становится сущностью, сам осуществляет целостную обработку данных. Мы его лишь «просим». У коробочки с данными появились ножки.
Теперь Вы знаете разгадку первой картинки и где на ней объект.
ссылка на оригинал статьи https://habrahabr.ru/post/327764/
Добавить комментарий