Что такое ооп в java
Что такое ооп в java
Основная цель использования данной концепции — это уменьшение сложности компонентов программы за счет скрытия от программиста, использующего эти компоненты, ненужных ему подробностей. Это позволяет реализовать более сложную логику поверх предоставленной абстракции, не вдаваясь в подробности ее реализации.
Приготовление кофе с помощью кофемашины является хорошим примером абстракции. Все, что нам надо знать, что бы ей пользоваться: как налить воды, засыпать кофейные зерна, включить и выбрать вид кофе, который хотим получить. А, как машина будет варить кофе — нам знать не нужно.
В данном примере кофемашина представляет собой абстракцию, которая от нас скрывает все подробности варки кофе. Нам лишь остается просто взаимодействовать с простым интерфейсом, который не требует от нас каких-либо знаний о внутренней реализации машины.
Этот же подход можно использовать и в объектно-ориентированных языках программирования, таких как Java.
Полиморфизм предоставляет возможность единообразно обрабатывать объекты с различной реализацией при условии наличия у них общего интерфейса или класса. По-простому: способность вызывать нужные методы у объектов, имеющие разные типы (но находящиеся в одной иерархии). При этом происходит автоматический выбор нужного метода в зависимости от типа объекта.
Рассмотрим примеры полиморфизма в Java: переопределение и перегрузка методов.
В случае с переопределением метода, дочерний класс, используя концепцию полиморфизма, может изменить (переопределить) поведение метода родительского класса. Это позволяет программисту по разному использовать один и тот же метод, определяя поведение из контекста вызова (вызывается метод из класса предка или класса наследника).
В случае же с перегрузкой, метод может проявлять различное поведение в зависимости от того, какие аргументы он принимает. В данном случае контекст вызова определяется набором параметров метода.
Собеседование по Java — ООП (вопросы и ответы). Часть 1.
Вопросы и ответы по теме ООП (объектно ориентированное программирование) для собеседования по Java.
К списку вопросов по всем темам
Список всех вопросов по ООП
1. Назовите принципы ООП и расскажите о каждом.
2. Дайте определение понятию “класс”.
3. Что такое поле/атрибут класса?
4. Как правильно организовать доступ к полям класса?
5. Дайте определение понятию “конструктор”.
6. Чем отличаются конструкторы по умолчанию, копирования и конструктор с параметрами?
7. Какие модификации уровня доступа вы знаете, расскажите про каждый из них.
8. Расскажите об особенностях класса с единственным закрытым (private) конструктором.
9. О чем говорят ключевые слова “this”, “super”, где и как их можно использовать?
10. Дайте определение понятию “метод”.
11. Что такое сигнатура метода?
12. Какие методы называются перегруженными?
13. Могут ли нестатические методы перегрузить статические?
14. Расскажите про переопределение методов.
15. Может ли метод принимать разное количество параметров (аргументы переменной длины)?
16. Можно ли сузить уровень доступа/тип возвращаемого значения при переопределении метода?
17. Как получить доступ к переопределенным методам родительского класса?
18. Какие преобразования называются нисходящими и восходящими?
19. Чем отличается переопределение от перегрузки?
20. Где можно инициализировать статические/нестатические поля?
21. Зачем нужен оператор instanceof?
22. Зачем нужны и какие бывают блоки инициализации?
23. Каков порядок вызова конструкторов и блоков инициализации двух классов: потомка и его предка?
24. Где и для чего используется модификатор abstract?
25. Можно ли объявить метод абстрактным и статическим одновременно?
26. Что означает ключевое слово static?
27. К каким конструкциям Java применим модификатор static?
28. Что будет, если в static блоке кода возникнет исключительная ситуация?
29. Можно ли перегрузить static метод?
30. Что такое статический класс, какие особенности его использования?
31. Какие особенности инициализации final static переменных?
32. Как влияет модификатор static на класс/метод/поле?
33. О чем говорит ключевое слово final?
34. Дайте определение понятию “интерфейс”.
35. Какие модификаторы по умолчанию имеют поля и методы интерфейсов?
36. Почему нельзя объявить метод интерфейса с модификатором final или static?
37. Какие типы классов бывают в java (вложенные… и.т.д.)
38. Какие особенности создания вложенных классов: простых и статических.
39. Что вы знаете о вложенных классах, зачем они используются? Классификация, варианты использования, о нарушении инкапсуляции.
40. В чем разница вложенных и внутренних классов?
41. Какие классы называются анонимными?
42. Каким образом из вложенного класса получить доступ к полю внешнего класса?
43. Каким образом можно обратиться к локальной переменной метода из анонимного класса, объявленного в теле этого метода? Есть ли какие-нибудь ограничения для такой переменной?
44. Как связан любой пользовательский класс с классом Object?
45. Расскажите про каждый из методов класса Object.
46. Что такое метод equals(). Чем он отличается от операции ==.
47. Если вы хотите переопределить equals(), какие условия должны удовлетворяться для переопределенного метода?
48. Если equals() переопределен, есть ли какие-либо другие методы, которые следует переопределить?
49. В чем особенность работы методов hashCode и equals? Каким образом реализованы методы hashCode и equals в классе Object? Какие правила и соглашения существуют для реализации этих методов? Когда они применяются?
50. Какой метод возвращает строковое представление объекта?
51. Что будет, если переопределить equals не переопределяя hashCode? Какие могут возникнуть проблемы?
52. Есть ли какие-либо рекомендации о том, какие поля следует использовать при подсчете hashCode?
53. Как вы думаете, будут ли какие-то проблемы, если у объекта, который используется в качестве ключа в hashMap изменится поле, которое участвует в определении hashCode?
54. Чем отличается абстрактный класс от интерфейса, в каких случаях что вы будете использовать?
55. Можно ли получить доступ к private переменным класса и если да, то каким образом?
56. Что такое volatile и transient? Для чего и в каких случаях можно было бы использовать default?
57. Расширение модификаторов при наследовании, переопределение и сокрытие методов. Если у класса-родителя есть метод, объявленный как private, может ли наследник расширить его видимость? А если protected? А сузить видимость?
58. Имеет ли смысл объявлять метод private final?
59. Какие особенности инициализации final переменных?
60. Что будет, если единственный конструктор класса объявлен как final?
61. Что такое finalize? Зачем он нужен? Что Вы можете рассказать о сборщике мусора и алгоритмах его работы.
62. Почему метод clone объявлен как protected? Что необходимо для реализации клонирования?
Ответы. Часть 1
1. Назовите принципы ООП и расскажите о каждом.
Объе́ктно-ориенти́рованное программи́рование (ООП) — это методология программирования, основанная на представлении программы в виде совокупности объектов, каждый из которых является экземпляром определенного класса, а классы образуют иерархию наследования.
Основные принципы ООП: абстракция, инкапсуляция, наследование, полиморфизм.
Абстракция — означает выделение значимой информации и исключение из рассмотрения незначимой. С точки зрения программирования это правильное разделение программы на объекты. Абстракция позволяет отобрать главные характеристики и опустить второстепенные.
Пример: описание должностей в компании. Здесь название должности значимая информация, а описание обязанностей у каждой должности это второстепенная информация. К примеру главной характеристикой для «директор» будет то, что это должность чем-то управляет, а чем именно (директор по персоналу, финансовый директор, исполнительный директор) это уже второстепенная информация.
Инкапсуляция — свойство системы, позволяющее объединить данные и методы, работающие с ними, в классе. Для Java корректно будет говорить, что инкапсуляция это «сокрытие реализации». Пример из жизни — пульт от телевизора. Мы нажимаем кнопочку «увеличить громкость» и она увеличивается, но в этот момент происходят десятки процессов, которые скрыты от нас. Для Java: можно создать класс с 10 методами, например вычисляющие площадь сложной фигуры, но сделать из них 9 private. 10й метод будет называться «вычислитьПлощадь()» и объявлен public, а в нем уже будут вызываться необходимые скрытые от пользователя методы. Именно его и будет вызывать пользователь.
Наследование — свойство системы, позволяющее описать новый класс на основе уже существующего с частично или полностью заимствующейся функциональностью. Класс, от которого производится наследование, называется базовым, родительским или суперклассом. Новый класс — потомком, наследником, дочерним или производным классом.
Полиморфизм — свойство системы использовать объекты с одинаковым интерфейсом без информации о типе и внутренней структуре объекта. Пример (чуть переделанный) из Thinking in Java:
Объектно-Ориентированное Программирование
1. Знакомство с принципами ООП
ООП появилось как ответ на возрастающую сложность программ. Когда количество переменных и функций в первых программах начало исчисляться десятками тысяч, стало понятно, что надо что-то с этим делать. Одним из решений было объединить данные и функции, которые работали с ними, в отдельные объекты.
Теперь программистам приходилось отдельно описывать взаимодействие объектов и действия, которые происходили внутри объекта. Это значительно упрощало понимание и написание программ. Однако открытым оставался вопрос, какие именно функции должны быть внутри объекта, а какие — между объектами.
2. Абстракция
Но вроде бы лучшие умы сошлись на том, что:
В языке программирования Java абстракция осуществляется через использование абстрактных классов и интерфейсов.
Абстракция в реальной жизни
Хороший пример абстракции в реальной жизни — описание должностей в компании или организации. Название должности — это одно, а обязанности каждой конкретной должности — это уже совсем другое.
Представьте, что вы проектируете структуру своей будущей компании. Вы можете разделить обязанности секретаря: «разбросать» их по нескольким другим должностям. Можете разбить должность исполнительного директора на несколько независимых должностей: финансовый директор, технический директор, директор по маркетингу, директор по персоналу. Или, например, объединить должности офис-менеджера и рекрутера в одну.
Вы придумываете названия должностей в своей фирме, а потом «разбрасываете» обязанности по этим должностям. Абстракция – отвлечение от целостности объекта и выделение его главных свойств и составляющих, нужных нам.
С точки зрения же программирования, абстракция — это, скажем так, правильное разделение программы на объекты. Обычно любую большую программу можно десятками способов представить в виде взаимодействующих объектов. Абстракция позволяет отобрать главные характеристики и опустить второстепенные.
3. Инкапсуляция
Цель инкапсуляции — улучшить качество взаимодействия вещей за счет их упрощения.
А лучший способ упростить что-то — скрыть все сложное от посторонних глаз. Например, если вас посадят в кабину Боинга, вы не сразу разберетесь, как им управлять:
С другой стороны, для пассажиров самолета все выглядит проще: купил билет, сел в самолет, взлетели и приземлились. Вы можете с легкостью перелететь с континента на континент, обладая только навыками «купить билет» и «сесть на самолет». Все сложности в виде подготовки самолета к полету, взлета, посадки и различных внештатных ситуаций скрыты от вас. Не говоря уже о спутниковой навигации, автопилоте и диспетчерских центрах в аэропортах. И это упрощает нам жизнь.
С точки зрения программирования, инкапсуляция — это «сокрытие реализации». Мне нравится такое определение. Наш класс может содержать сотни методов и реализовывать очень сложное поведение в различных ситуациях. Но мы можем скрыть от посторонних глаз все его методы (пометить модификатором private), а для взаимодействия с другими классами оставить всего пару-тройку методов (пометить их модификатором public). Тогда все остальные классы нашей программы будут видеть в этом классе всего три метода и вызывать именно их. А все сложности будут скрыты внутри класса, как кабина пилотов от счастливых пассажиров.
4. Наследование
Если нам понадобится что-то создать в реальной жизни, у нас есть два решения:
Наиболее оптимальная стратегия выглядит так: берем существующее хорошее решение, немного его дорабатываем, подгоняем под свои нужды и используем.
Если мы проследим историю возникновения человека, то окажется, что с момента зарождения жизни на планете прошли миллиарды лет. А если представить, что человек возник из обезьяны (на основе обезьяны), то прошла всего пара миллионов лет. Создание с нуля — дольше. Гораздо дольше.
В программировании тоже есть возможность создавать один класс на основе другого. Новый класс становится потомком (наследником) уже существующего. Это очень выгодно, когда есть класс, который содержит 80%-90% нужных нам данных и методов. Мы просто объявляем подходящий класс родителем нашего нового класса, и в новом классе автоматически появляются все данные и методы класса-родителя. Правда, удобно?
5. Полиморфизм
Полиморфизм — это понятие из области программирования. Оно описывает ситуацию, когда за одним интерфейсом скрываются разные реализации. Если постараться поискать его аналоги в реальной жизни, одним из них будет процесс управления машиной.
Если человек может управлять грузовиком, его можно посадить и за руль скорой, и за руль спорткара. Человек может управлять машиной вне зависимости от того, что это за машина, потому что все они имеют одинаковый интерфейс управления: руль, педали и рычаг коробки передач. Внутреннее устройство машин разное, но все они имеют одинаковый интерфейс управления.
Если вернуться к программированию, то полиморфизм позволяет единообразно обращаться к объектам различных классов (обычно имеющих общего предка) — вещь, которую трудно переоценить. Ценность его тем выше, чем больше программа.
ООП — это принципы. Внутренние законы. Каждый из них нас в чем-то ограничивает, давая взамен большие преимущества, когда программа вырастает до больших размеров. Четыре принципа ООП — это как четыре ножки стула. Убери хотя бы одну, и вся система станет неустойчивой.
ООП в Java: четыре принципа с примерами
Объектно-ориентированное программирование (ООП) — это методология программирования с использованием объектов и классов.
Объект характеризует состояние и поведение. Например, у кота есть такие свойства, как имя, порода, цвет. Представим, что они отражают его состояние. Кот может мурчать, спать, охотиться, есть и так далее — это проявления его поведения.
С помощью таких характеристик можно описать любого кота. Шаблон, в котором описаны общие черты и действия похожих друг на друга объектов, называется классом. А объект — это конкретный экземпляр класса. Например, рыжий короткошерстный кот Альбатрос и серый пушистый кот Петька — это объекты класса «кот».
В классах Java состояние представлено в виде полей, а поведение — в виде методов.
Содержание статьи:
Принципы ООП
Объектно-ориентированное программирование опирается на четыре принципа:
Рассмотрим эти принципы подробнее.
Наследование
Наследование позволяет использовать код повторно. Это достигается за счет того, что в одном классе содержатся свойства и методы, общие для более конкретных классов. Класс, от которого наследуются свойства и методы, называется суперклассом (родительским классом). Классы, которые наследуют их, называются подклассами (дочерними классами). Таким образом создается иерархия классов.
На вершине иерархии находится базовый класс. Он не является подклассом, то есть не наследует свойств и методов от других классов. На его основе создаются остальные классы иерархии.
Создадим базовый класс Animal, который описывает животное.
Допустим, у животного есть имя и оно издает какой-то звук. Определим имя и звук как строковые поля.
Ключевое слово private — это модификатор доступа, который означает, что поле будет доступно только в данном классе и его подклассах. Таким образом мы запрещаем изменение значений двух полей этого класса извне.
Чтобы создать экземпляр класса (объект) и задать начальные значения полей, объявим общедоступный конструктор, используя модификатор доступа public. Он позволит обращаться к конструктору извне.
Ключевое слово this — это ссылка на создаваемый объект. Для обращения к полю внутри объекта используется синтаксис:
В этом конструкторе мы присваиваем полям объекта значения, переданные в формальных параметрах.
На данном этапе уже реализовано состояние объекта. Теперь реализуем его поведение.
Мы объявили общедоступный метод speak(), в котором на консоли выводится значение поля voice.
Создадим класс Cat, который будет представлять кота и унаследует от класса Animal его свойства и поведение. Для создания подкласса используется ключевое слово extends.
Благодаря наследованию нам не пришлось еще раз писать код, чтобы дать коту имя и указать звук, который он издает. Имя конкретного кота мы заранее не знаем, но знаем, что коты мяукают. Поэтому конструктор этого класса принимает только один формальный параметр name.
Для обращения к суперклассу из подкласса используется ключевое слово super. В данном случае мы вызываем конструктор суперкласса и передаем ему формальный параметр name и литерал meow. Конструктор суперкласса присваивает унаследованным переменным объекта переданные значения.
Теперь мы можем создать экземпляр класса Cat и воспользоваться методом speak(), унаследованным от суперкласса, чтобы «услышать», как мяукает кот.
В языке Java все (точнее, почти все) является объектом. Поэтому мы создаем класс Main с методом main, в котором содержатся инструкции программы. В нем мы объявляем переменную класса Cat для создания объекта. Чтобы инициализировать его, обращаемся к конструктору, используя ключевое слово new, и задаем имя питомца:
Полный код будет выглядеть так:
Абстракция
Для решения сложной задачи нужно разделить ее на части, с которыми удобно работать. Некоторые части могут быть похожими друг на друга, то есть иметь общие признаки. Например, у сотрудника компании и у клиента есть имя, фамилия, адрес. Эти общие свойства можно вынести в отдельный более абстрактный класс.
При моделировании реальных объектов совсем необязательно учитывать все их характеристики. Как правило, для решения определенной задачи бывает достаточно лишь нескольких. Поэтому в определении клиента и сотрудника неважен рост или цвет волос (если только этого не требует задача).
Создадим класс Person и определим в нем общие характеристики.
Унаследуем от него классы Customer и Employee. Добавим для клиента номер банковского счета, а для сотрудника — размер зарплаты.
Так, мы избавились от повторного написания кода, выделив общие признаки в суперкласс. Рабочий пример выглядит так:
Инкапсуляция
Инкапсуляция дает возможность предоставить пользователю методы, которые нужны для работы с объектами, и скрыть от него детали их реализации. Площадь треугольника и площадь прямоугольника вычисляются по разным формулам. Несмотря на это, можно объявить для обеих фигур метод square, который получит разные реализации.
Площадь прямоугольника равна произведению длин его сторон. Площадь треугольника по сторонам можно вычислить по формуле Герона. Создадим абстрактный класс Area, который будет представлять геометрическую фигуру.
Абстрактный класс, как и его абстрактный метод, объявляются с помощью ключевого слова abstract. Абстрактный метод не имеет реализации, он лишь объявлен в коде класса.
Создадим производные классы Rectangle и Triangle.
В этих классах объявлены стороны и переопределен унаследованный метод area().
Стороны объявлены с использованием модификатора final, который означает, что значение данного поля — это константа, и поэтому не может быть изменено во время выполнения программы. Если объявить класс как final, то он не сможет иметь подклассов.
Подклассы могут переопределять методы суперкласса с использованием аннотации @Override. Как видим, в переопределенных методах, в отличие от абстрактного, содержится код вычисления площади.
Для вычисления площади треугольника мы используем статический метод sqrt() класса Math. Чтобы воспользоваться таким методом в программе, его нужно импортировать:
Полный код будет выглядеть так:
Хоть площадь этих фигур определяется по разным формулам, мы просто вызываем метод area(), не заботясь о том, как производятся вычисления.
Полиморфизм
Используя полиморфизм, можно обращаться к методам экземпляров суперкласса и его подклассов, как к методам одинаковых объектов. Допустим, существует два музыканта: клавишник и гитарист. Оба они могут играть, но играют на разных инструментах.
Рассмотрим полный пример кода:
Обратите внимание, что в определении суперкласса мы используем модификатор protected для поля name. Этот модификатор позволяет обращаться к нему не только из данного класса, но и из его подклассов. Прямой доступ извне по-прежнему закрыт.
В методе Main мы создаем список объектов класса Musician, в котором могут находиться и экземпляры унаследованных от него классов:
Затем в цикле мы перечисляем музыкантов и вызываем для каждого из них метод play(). Поскольку этот метод реализован во всех классах, не приходится заботиться о том, на чем именно играет каждый музыкант, и писать код вызова метода для каждого из них отдельно.
Причины появления ООП
По мере того, как совершенствовались компьютеры, требовалось создавать все больше функций. Разобраться в коде и разделить задачу на части становилось труднее и труднее.
Объектно-ориентированное программирование было создано как ответ на эти трудности. Оно позволило объединить связанные участки кода и отделить их от тех участков, с которыми они были связаны слабо.
В результате вместо огромного количества процедур и переменных требовалось помнить лишь те, которые нужны для применения объекта (интерфейс). Остальная часть его реализации была скрыта.
Если требовалось внести изменения или улучшить код, это стало происходить незаметно для пользователя, потому что интерфейс не менялся. Кроме того, наследование давало возможность повторно использовать код.
ООП упрощает понимание кода и позволяет экономить много времени при его написании.
ООП — основные принципы
— Привет, Амиго! Сегодня я открою для тебя новый и интересный мир. Этот мир называется ООП – объектно-ориентированное программирование. Ты уже познакомился с классами и объектами. Сегодня ты узнаешь про них больше, намного больше.
Начнем с четырех принципов ООП. Это: абстракция, инкапсуляция, наследование и полиморфизм. (Раньше их было три, но потом решили добавить абстракцию)
1) Абстракция.
Хорошим примером абстракции в реальной жизни является описание должностей в компании или организации. Название должности – это одно, а обязанности каждой конкретной должности – это уже совсем другое.
Представь, что ты проектируешь структуру своей будущей компании. Ты можешь разделить обязанности секретаря: «раскидать» их по нескольким другим должностям. Можешь разбить должность исполнительного директора на несколько независимых должностей: финансовый директор, технический директор, директор по маркетингу, директор по персоналу. Или, например, объединить должности офис-менеджера и рекрутера в одну.
Ты придумываешь названия должностей в своей фирме, а потом «раскидываешь» обязанности по этим должностям. Это и есть абстракция – разбиение чего-то большого, монолитного на множество маленьких составных частей.
С точки зрения программирования, абстракция — это, скажем так, правильное разделение программы на объекты.
Обычно любую большую программу можно десятками способов представить в виде взаимодействующих объектов. Абстракция позволяет отобрать главные характеристики и опустить второстепенные.
Абстракция – это как стратегия в военном деле. Плохая стратегия – и никакой гениальной тактикой ситуацию уже не исправить.
2) Инкапсуляция.
Цель инкапсуляции – улучшить качество взаимодействия вещей за счет упрощения их.
А лучший способ упростить что-то – это скрыть все сложное от посторонних глаз. Например, если тебя посадят в кабину Боинга, ты не сразу разберешься, как им управлять:
С другой стороны, для пассажиров самолета все выглядит проще: купил билет, сел в самолет, взлетели и приземлились. Ты можешь с легкостью перелететь с континента на континент, обладая только навыками «купить билет» и «сесть на самолет». Все сложности в виде подготовки самолета к полету, взлета, посадки и различных внештатных ситуаций скрыты от нас. Не говоря уже о спутниковой навигации, автопилоте и диспетчерских центрах в аэропортах. И это упрощает нам жизнь.
С точки зрения программирования, инкапсуляция – это «сокрытие реализации». Мне нравится такое определение. Наш класс может содержать сотни методов и реализовывать очень сложное поведение в различных ситуациях. Но мы можем скрыть от посторонних глаз все его методы (пометить модификатором private), а для взаимодействия с другими классами оставить всего пару-тройку методов (пометить их модификатором public). Тогда все остальные классы нашей программы будут видеть в этом классе всего три метода, и будут вызывать именно их. А все сложности будут скрыты внутри класса, как кабина пилотов от счастливых пассажиров.
3) Наследование.
У наследования есть две стороны. Сторона программирования и сторона реальной жизни. С точки зрения программирования, наследование – это специальное отношение между двумя классами. Но гораздо интереснее, что же такое наследование с точки зрения реальной жизни.
Если бы нам понадобилось что-то создать в реальной жизни, то у нас есть два решения:
1) создать нужную нам вещь с нуля, потратив кучу времени и сил.
2) создать нужную нам вещь на основе уже существующей.
Наиболее оптимальная стратегия выглядит так: берем существующее хорошее решение, немного его дорабатываем, подгоняем под свои нужды и используем.
Если мы проследим историю возникновения человека, то окажется, что с момента зарождения жизни на планете прошли миллиарды лет. А если представить, что человек возник из обезьяны (на основе обезьяны), то прошла всего пара миллионов лет. Создание с нуля – дольше. Гораздо дольше.
В программировании тоже есть возможность создавать один класс на основе другого. Новый класс становится потомком (наследником) уже существующего. Это очень выгодно, когда есть класс, который содержит 80%-90% нужных нам данных и методов. Мы просто объявляем подходящий класс родителем нашего нового класса, тогда в новом классе автоматически появляются все данные и методы класса-родителя. Правда, удобно?
4) Полиморфизм.
Полиморфизм – это понятие из области программирования. Оно описывает ситуацию, когда за одним интерфейсом скрываются разные реализации. Если постараться поискать его аналоги в реальной жизни, то одним из таких аналогов будет процесс управления машиной.
Если человек может управлять грузовиком, то его можно посадить и за руль скорой, и за руль спорткара. Человек может управлять машиной вне зависимости от того, что это за машина, потому что все они имеют одинаковый интерфейс управления: руль, педали и рычаг коробки передач. Внутреннее устройство машин разное, но все они имеют одинаковый интерфейс управления.
Если вернуться к программированию, то полиморфизм позволяет единообразно обращаться к объектам различных классов (обычно имеющих общего предка) – вещь, которую трудно переоценить. Ценность его тем выше, чем больше программа.
ООП – это принципы. Внутренние законы. Каждый из них нас в чем-то ограничивает, давая взамен большие преимущества, когда программа вырастает до больших размеров. Четыре принципа ООП – это как четыре ножки стула. Убери хотя бы одну, и вся система станет неустойчивой.









