Принципы опп. Основные принципы ооп и их использование

по существу пользовались парадигмой директивного программирования - целью было создание кода, воздействующего должным образом на данные. Этот подход хорош при решении небольших задач, но порождает множество трудноразрешимых проблем при попытке создания больших программных систем .

Одной из альтернатив директивному программированию является объектно-ориентированное программирование , которое действительно помогает справиться с нелинейно растущей сложностью программ при увеличении их объема. Не следует, однако, делать вывод , что использование парадигмы объектно-ориентированного программирования гарантирует успешное решение всех проблем.

Для того чтобы стать профессионалом в программировании, необходимы талант, способность к творчеству, интеллект , знания, логика, умение строить и использовать абстракции и, самое главное, опыт .

В этом параграфе мы продолжим знакомство с базисными концепциями объектно-ориентированного программирования, начатое еще в первой главе книги. Сначала будут обсуждены общие для различных языков программирования понятия ООП , а затем - их реализация в языке Java .

Следует знать, что курс объектно-ориентированного программирования читается студентам-старшекурсникам в течение целого семестра, и поэтому материал, изложенный ниже, представляет собой лишь самое начальное введение в мир ООП . Значительно более полное изложение многих вопросов, связанных с объектно-ориентированными дизайном, проектированием и программированием, содержится в книге , а в третьей главе книги можно найти очень ясное описание всех объектно-ориентированных аспектов языка Java .

Основные концепции ООП

Объектно-ориентированное программирование или ООП (object-oriented programming) - методология программирования , основанная на представлении программы в виде совокупности объектов , каждый из которых является реализацией определенного типа , использующая механизм пересылки сообщений и классы , организованные в иерархию наследования .

Центральный элемент ООП - абстракция . Данные с помощью абстракции преобразуются в объекты, а последовательность обработки этих данных превращается в набор сообщений, передаваемых между этими объектами. Каждый из объектов имеет свое собственное уникальное поведение. С объектами можно обращаться как с конкретными сущностями, которые реагируют на сообщения, приказывающие им выполнить какие-то действия.

ООП характеризуется следующими принципами ( по Алану Кею):

  • все является объектом ;
  • вычисления осуществляются путем взаимодействия (обмена данными) между объектами, при котором один объект требует, чтобы другой объект выполнил некоторое действие; объекты взаимодействуют, посылая и получая сообщения ; сообщение - это запрос на выполнение действия, дополненный набором аргументов, которые могут понадобиться при выполнении действия;
  • каждый объект имеет независимую память , которая состоит из других объектов ;
  • каждый объект является представителем класса , который выражает общие свойства объектов данного типа ;
  • в классе задается функциональность (поведение объекта); тем самым все объекты, которые являются экземплярами одного класса, могут выполнять одни и те же действия;
  • классы организованы в единую древовидную структуру с общим корнем, называемую иерархией наследования ; память и поведение, связанное с экземплярами определенного класса, автоматически доступны любому классу, расположенному ниже в иерархическом дереве.

Определение 10.1 . Абстрагирование (abstraction) - метод решения задачи, при котором объекты разного рода объединяются общим понятием (концепцией), а затем сгруппированные сущности рассматриваются как элементы единой категории.

Абстрагирование позволяет отделить логический смысл фрагмента программы от проблемы его реализации, разделив внешнее описание ( интерфейс ) объекта и его внутреннюю организацию (реализацию).

Определение 10.2 . Инкапсуляция (encapsulation) - техника, при которой несущественная с точки зрения интерфейса объекта информация прячется внутри него.

Определение 10.3 . Наследование (inheritance) - свойство объектов, посредством которого экземпляры класса получают доступ к данным и методам классов-предков без их повторного определения.

Наследование позволяет различным типам данных совместно использовать один и тот же код, приводя к уменьшению его размера и повышению функциональности.

Определение 10.4 .

Базовые принципы объектно-ориентированного программирования

Объектно-ориентированное программирование основывается на трех основных концепциях: инкапсуляции , полиморфизме и наследовании .

Инкапсуляция (пакетирование) представляет собой механизм, связывающий вместе данные и код, обрабатывающий эти данные, и сохраняющий их от внешнего воздействия и ошибочного использования. Инкапсуляция позволяет создавать объект, являющийся логическим целым, включающим данные и код для работы с этими данными. Объект обеспечивает защиту против случайной или несанкционированной модификации частных (private) составляющих его членов. Закрытые данные или коды (методы) доступны только для других частей этого объекта и не доступны вне его. Открытая часть объекта предназначена для обеспечения контролируемого интерфейса его закрытой части.

Полиморфизм - принцип (подход), обеспечивающий возможность использования одного и того же кода для решения разных задач. Полиморфизм позволяет уменьшить сложность программы посредством использования одного и того жеинтерфейса для задания целого класса действий. Задача выбора специфического действия (метода) в зависимости от конкретной ситуации (количества и типа передаваемых аргументов) возлагается на компилятор.

Ключевым в понимании полиморфизма является то, что он позволяет манипулировать объектами различной степени сложности путем создания общего для них стандартного интерфейса для реализации похожих действий.

Наследование представляет собой процесс, благодаря которому один объект может наследовать (приобретать) свойства от другого объекта. Объект, используя наследование, нуждается только в определении специфичных только для этого объекта свойств, отличающих его от других объектов этого класса. Наследование позволяет поддерживать концепцию иерархии классов .

Различают полиморфные и мономорфные языки. Для мономорфных языков характерно то, что используемые функции, процедуры и операторы имеют уникальный тип. Полиморфные языки поддерживают концепцию полиморфизма в теории типов, когда одно и то же имя может быть использовано для выражения различных действий. Поддержка полиморфизма осуществляется через виртуальные функции, механизм перегрузки функций и операторов.

Передача сообщений выражает основную методологию построения объектно-ориентированных программ. Программы представляются в виде набора объектов и передачи сообщений между ними.

При построении объектно-ориентированной программы одним из основных является вопрос иерархии классов . Пусть имеется некоторая иерархия (структура, взаимосвязь) классов. В этом случае можно:

- определить объект для заданного класса;

- построить новый класс, наследуя его из существующего класса;

- изменить поведение нового класса (изменить существующие и добавить новые функции).

Построение нового класса, наследуя его из существующего, предполагает:

- добавление в новый класс новых компонент-данных;

- добавление в новый класс новых компонент-функций;

- замену в новом классе наследуемых из старого класса компонент-функций;

Наследование может быть одиночным и множественным (рис. 1). При множественном наследовании производный (новый) класс имеет более одного наследуемого (старого) класса, из которых образуется новый класс. При этом новый класс наследует поведение этих классов.

Таким образом, объектно-ориентированное программирование – метод построения программ в виде множества взаимодействующих объектов, структура и поведение которых описаны соответствующими классами. Все эти классы образуют иерархию классов, выражающую отношение наследования.

При разработке объектно-ориентированных программ часто используются библиотеки классов. Библиотека может рассматриваться как заданная базовая иерархическая структура. Для разрабатываемой программы из библиотеки может быть выбрана некоторая подструктура и затем расширена новыми классами с использованием принципов наследования.

Язык программирования называется объектно-ориентированным, если:

- он поддерживает абстрактные типы данных (объекты с определенным интерфейсом и скрытым внутренним состоянием);

- объекты имеют связанные с ними типы (классы);

- поддерживается механизм наследования.

(как расшифровывается ООП) – это, прежде всего, парадигма программирования.
Парадигма программирования определяет то, как программист видит выполнение программы.
Так, для парадигмы ООП характерно, что программист рассматривает программу в виде набора взаимодействующих объектов, в то время как, например, в функциональном программировании программа представляется в виде последовательности вычисления функций. Процедурное программирование или, как его еще правильно называют, классическое операциональное, подразумевает написание алгоритма для решения задачи; при этом ожидаемые свойства конечного результата не описываются и не указываются. Структурное программирование в основном придерживается тех же принципов, что и процедурное, лишь немного дополняя их полезными приемами.
Парадигмы непроцедурного программирования, к которым можно отнести объектно-ориентированную парадигму, имеют совершенно другие идеи.
Определение Гради Буча гласит: “Объектно-ориентированное программирование – это методология программирования, которая основана на представлении программы в виде совокупности объектов, каждый из которых является реализацией определенного класса (типа особого вида), а классы образуют иерархию на принципах наследуемости”.
Структурное и объектно-ориентированное программирование строятся на таком научном методе как декомпозиция — метод, который использует структуру задачи и позволяет разбить решение общей большой задачи на решение последовательности меньших задач. Декомпозиция ООП происходит не по алгоритмам, а по объектам, использующимся при решении задачи. Данная декомпозиция уменьшает размер программных систем благодаря повторному использованию общих механизмов. Известно, что системы визуального программирования или системы, построенные на принципах объектно-ориентированного программирования, являются более гибкими и легче эволюционируют со временем.

История развития ООП берет свое начало в конце 60-х годов. Первым объектно-ориентированным языком был язык программирования Simula, созданный в компьютерном центре в Норвегии. Язык предназначался для моделирования ситуаций реального мира. Особенностью Simula было то, что программа, написанная на языке, была организована по объектам программирования. Объекты имели инструкции, называемые методами, и данные, которые назывались переменными; методы и данные определяли поведение объекта. В процессе моделирования объект вел себя согласно своему стандартному поведению и, в случае необходимости, изменял данные для отражения влияния назначенного ему действия.

Сегодня существует достаточное количество объектно-ориентированных языков программирования , наиболее популярными из которых в настоящее время являются C++, Delphi, Java, Visual Basic, Flash. Но, кроме того, многие языки, которые принято причислять к процедурной парадигме, тоже обладают свойствами ООП, имея возможность работать с объектами. Так, объектно-ориентированное программирование в C — это большой раздел программирования на данном языке, то же самое касается ООП в python и многих других структурных языках.

Говоря об ООП, часто всплывает еще одно определение — визуальное программирование . Оно дополнительно предоставляет широкие возможности использования прототипов объектов, которые определяются как классы объектов.
События. Во многих средах визуального программирования реализована характеристика (помимо инкапсуляции, полиморфизма и наследования) объекта – событие. Событиями в объектно-ориентированном программировании называется возможность обработки так называемых сообщений (или событий), получаемых от операционной системы Windows или самой программы. Данный принцип характерен для всех компонентов среды, которые обрабатывают различные события, возникающие в процессе выполнения программы. По сути, событие — это некоторое действие, которое активизирует стандартную реакцию объекта. Событием может рассматриваться, например, щелчок по кнопке мыши, наведение курсора мыши на пункт меню, открытие вкладки и т.п. Очередность выполнения тех или иных действий определяется как раз таки событиями, возникающими в системе, и реакцией на них объектов.
Классы и объекты в ООП — различные понятия. Понятие класса в ООП – это тип данных (такой же как, например, Real или String), а объект – конкретный экземпляр класса (его копия), хранящийся в памяти компьютера как переменная соответствующего типа.
Класс является структурным типом данных. Класс включает описание полей данных, а также процедур и функций, которые работают с этими полями данных. Метод ООП – это и есть такие процедуры и функции применительно к классам.
Классы имеют поля (как тип данных запись — record), свойства, которые похожи на поля, но имеют дополнительные описатели, определяющие механизмы записи и считывания данных и методы — подпрограммы, которые направленны на изменение полей и свойств класса.

Основные принципы ООП

Принципы объектно-ориентированного программирования помимо обработки событий – это инкапсуляция, наследование, подклассы и полиморфизм. Они особенно полезны и необходимы при разработке тиражируемых и простых в сопровождении приложений.
Объект объединяет в себе методы и свойства, которые не могут существовать отдельно от него. Поэтому если объект удаляется, то удаляются его свойства и связанные с ним методы. При копировании происходит то же самое: объект копируется как единое целое. Инкапсуляция ООП — это и есть описанная характеристика.

Принцип наследования ООП и подклассы

Абсолютно все объекты создаются на основе классов, при это они наследуют свойства и методы этих классов. В свою очередь классы могут создаваться на основе других классов (родителей), тогда такие классы называют подклассами (потомки). Подклассы наследуют все свойства и методы родительского класса. Кроме того для подкласса или класса-потомка можно определить новые, свои собственные, свойства и методы, а также изменять методы класса-родителя. Изменение свойств и методов родительского класса отслеживается в подклассах, созданных на основе этого класса, а также в объектах, созданных на основе подклассов. В этом и заключается наследование ООП.

Полиморфизм ООП

В объектно-ориентированном программировании полиморфизм характеризуется как взаимозаменяемость объектов с одинаковым интерфейсом. Это можно объяснить так: класс-потомок наследует экземпляры методов класса-родителя, но выполнение этих методов может происходить другим образом, соответствующим специфике класса-потомка, то есть модифицированным.
То есть, если в процедурном программировании имя процедуры или функции однозначно определяет выполняемый код, относящейся к данной процедуре или функции, то в объектно-ориентированном программировании можно использовать одни и те же имена методов для выполнения разных действий. То есть результат выполнения одного и того же метода зависит от типа объекта, к которому применяется данный метод.

На сайте представлена частичная теория объектно-ориентированного программирования для начинающих и ООП примеры решения задач. ООП уроки сайта представляют собой подробные алгоритмы выполнения поставленной задачи. На основе выполнения данных лабораторных работ учащийся сможет в дальнейшем самостоятельно решать другие аналогичные задачи.
Желаем Вам легкого и интересного изучения объектно-ориентированного программирования!

Java является объектно-ориентированным языком. Это означает, что писать программы на Java нужно с применением объектно-ориентированного стиля. И стиль этот основан на использовании в программе объектов и классов. Попробуем с помощью примеров разобраться, что такое классы и объекты, а также с тем, как применять на практике основные принципы ООП: абстракцию, наследование, полиморфизм и инкапсуляцию.

Что такое объект?

Мир, в котором мы живем, состоит из объектов. Если мы посмотрим вокруг, то увидим, что нас окружают дома, деревья, автомобили, мебель, посуда, компьютеры. Все эти предметы являются объектами, и каждый из них обладает набором определенных характеристик, поведением и назначением. Мы привыкли к объектам, и мы их используем всегда для вполне конкретных целей. Например, если нам необходимо доехать до работы, мы пользуемся автомобилем, если захотим поесть – посудой, а если отдохнуть – нам понадобится удобный диван. Человек привык мыслить объектно для решения задач в повседневной жизни. Это послужило одной из причин использования объектов в программировании, а такой подход к созданию программ назвали объектно-ориентированным. Приведём пример. Представьте, что вы разработали новую модель телефона и хотите наладить её серийное производство. Как разработчик телефона, вы знаете для чего он нужен, как он будет функционировать, и из каких деталей он будет состоять (корпус, микрофон, динамик, провода, кнопки и т.д.). При этом только вы знаете, как соединить эти детали. Однако вы не планируете выпускать телефоны лично, для этого у вас есть целый штат работников. Чтобы вам не пришлось каждый раз объяснять, как соединить детали телефона, и чтобы все телефоны при производстве получались одинаковыми, прежде чем начать их выпуск, вам понадобиться сделать чертеж в виде описания устройства телефона. В ООП такое описание, чертеж, схема или шаблон называется классом, из которого при выполнении программы создается объект. Класс - это описание еще не созданного объекта, как бы общий шаблон, состоящий из полей, методов и конструктора, а объект – экземпляр класса, созданный на основе этого описания.

Абстракция

Давайте теперь подумаем, как нам перейти от объекта из реального мира к объекту в программе на примере телефона. История этого средства связи превышает 100 лет и современный телефон, в отличие от своего предшественника из 19 века, представляет собой куда более сложное устройство. Когда мы пользуемся телефоном, то не задумываемся о его устройстве и процессах, происходящих внутри него. Мы просто используем функции, предоставленные разработчиками телефона - кнопки или сенсорный экран для выбора номера и совершения вызовов. Одним из первых интерфейсов телефона была рукоятка, которую нужно было вращать, чтобы сделать вызов. Разумеется, это было не очень удобно. Тем не менее, свою функцию рукоять исправно выполняла. Если посмотреть на самый современный и на самый первый телефон, можно сразу выделить самые важные детали, которые важны и для устройства конца 19-го века, и для суперсовременного смартфона. Это совершение вызова (набор номера) и приём вызова. По сути это то, что делает телефон телефоном, а не чем-то другим. Сейчас мы применили принцип в ООП - выделение наиболее важных характеристик и информации об объекте. Этот принцип называется абстракцией. Абстракцию в ООП можно также определить, как способ представления элементов задачи из реального мира в виде объектов в программе. Абстракция всегда связана с обобщением некоторой информации о свойствах предметов или объектов, поэтому главное - это отделить значимую информацию от незначимой в контексте решаемой задачи. При этом уровней абстракции может быть несколько. Попробуем применить принцип абстракции к нашим телефонам. Для начала выделим наиболее распространённые типы телефонов от самых первых и до наших дней. Например, их можно представить в виде диаграммы, приведенной на рисунке 1. Теперь с помощью абстракции мы можем выделить в этой иерархии объектов общую информацию: общий абстрактный тип объектов - телефон, общую характеристику телефона - год его создания, и общий интерфейс - все телефоны способны принимать и посылать вызовы. Вот как это выглядит на Java: public abstract class AbstractPhone { private int year; public AbstractPhone (int year) { this . year = year; } public abstract void call (int outputNumber) ; public abstract void ring (int inputNumber) ; } На основании этого абстрактного класса мы сможем создавать в программе новые типы телефонов с использованием других базовых принципов ООП Java, которые рассмотрим ниже.

Инкапсуляция

С помощью абстракции мы выделяем общее для всех объектов. Однако каждая модель телефона - индивидуальна и чем-то отличается от других. Как же нам в программе провести границы и обозначить эту индивидуальность? Как сделать так, чтоб никто из пользователей случайно или преднамеренно не смог сломать наш телефон, или попытаться переделать одну модель в другую? Для мира реальных объектов ответ очевиден: нужно поместить все детали в корпус телефона. Ведь если этого не сделать и оставить все внутренности телефона и провода, соединяющие их снаружи, обязательно найдется любознательный экспериментатор, который захочет “улучшить” работу нашего телефона. Для исключения подобного вмешательства в конструкцию и работу объекта в ООП используют принцип инкапсуляции – еще один базовый принцип ООП, при котором атрибуты и поведение объекта объединяются в одном классе, внутренняя реализация объекта скрывается от пользователя, а для работы с объектом предоставляется открытый интерфейс. Задача программиста - определить, какие атрибуты и методы будут доступны для открытого доступа, а какие являются внутренней реализацией объекта и должны быть недоступны для изменений.

Инкапсуляция и управление доступом

Допустим, при производстве на тыльной стороне телефона гравируется информация о нем: год его выпуска или логотип компании производителя. Эта информация вполне конкретно характеризует данную модель - его состояние. Можно сказать, разработчик телефона позаботился о неизменности этой информации - вряд ли кому-то придет в голову удалять гравировку. В мире Java состояние будущих объектов описывается в классе с помощью полей, а их поведение – с помощью методов. Возможность же изменения состояния и поведения осуществляется с помощью модификаторов доступа к полям и методам – private, protected, public , а также default (доступ по умолчанию). Например, мы решили, что год создания, название производителя телефона и один из методов относятся к внутренней реализации класса и не подлежат изменению другими объектами в программе. С помощью кода класс можно описать так: 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 . Предоставление открытых методов для работы с объектом также является частью механизма инкапсуляции, тат как если полностью закрыть доступ к объекту – он станет бесполезным.

Наследование

Давайте посмотрим еще раз на диаграмму телефонов. Можно заметить, что она представляет собой иерархию, в которой модель, расположенная ниже обладает всеми признаками моделей, расположенных выше по ветке, плюс своими собственными. Например, смартфон, использует сотовую сеть для связи (обладает свойствами сотового телефона), является беспроводным и переносным (обладает свойствами беспроводного телефона) и может принимать и делать вызовы (свойствами телефона). В этом случае мы можем говорить о наследовании свойств объекта. В программировании наследование заключается в использовании уже существующих классов для описания новых. Рассмотрим пример создания класса смартфон с помощью наследования. Все беспроводные телефоны работают от аккумуляторных батарей, которые имеют определенный ресурс работы в часах. Поэтому добавим это свойство в класс беспроводных телефонов: public abstract class WirelessPhone extends AbstractPhone { private int hour; public WirelessPhone (int year, int hour) { super (year) ; this . hour = hour; } } Сотовые телефоны наследуют свойства беспроводного телефона, мы также добавили в этот класс реализацию методов call и ring: 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) ; } } И, наконец, класс смартфон, который в отличие от классических сотовых телефонов имеет полноценную операционную систему. В смартфон можно добавлять новые программы, поддерживаемые данной операционной системой, расширяя, таким образом, его функциональность. С помощью кода класс можно описать так: 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 позволяет значительно уменьшить объем кода, а значит, и облегчить работу программисту.

Полиморфизм

Если мы посмотрим на все модели телефонов, то, несмотря на различия во внешнем облике и устройстве моделей, мы можем выделить у них некое общее поведение – все они могут принимать и совершать звонки и имеют достаточно понятный и простой набор кнопок управления. Применяя известный нам уже один из основных принципов ООП абстракцию в терминах программирования можно сказать, что объект телефон имеет один общий интерфейс. Поэтому пользователи телефонов могут вполне комфортно пользоваться различными моделями, используя одни и те же кнопки управления (механические или сенсорные), не вдаваясь в технические тонкости устройства. Так, вы постоянно пользуетесь сотовым телефоном, и без труда сможете совершить звонок с его стационарного собрата. Принцип в ООП, когда программа может использовать объекты с одинаковым интерфейсом без информации о внутреннем устройстве объекта, называется полиморфизмом . Давайте представим, что нам в программе нужно описать пользователя, который может пользоваться любыми моделями телефона, чтобы позвонить другому пользователю. Вот как можно это сделать: 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) ; } } } Теперь опишем различные модели телефонов. Одна из первых моделей телефонов: 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 ("Телефон звонит" ) ; } } Обычный стационарный телефон: 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 ("Телефон звонит" ) ; } } И, наконец, крутой видеотелефон: 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: 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 , которая подсказывает компилятору о необходимости проверить сигнатуры переопределяемого и переопределяющего методов. В итоге , чтобы стиль вашей программы соответствовал концепции ООП и принципам ООП java следуйте следующим советам:
  • выделяйте главные характеристики объекта;
  • выделяйте общие свойства и поведение и используйте наследование при создании объектов;
  • используйте абстрактные типы для описания объектов;
  • старайтесь всегда скрывать методы и поля, относящиеся к внутренней реализации класса.

Основы объектно-ориентированного программирования

Все основанные на объектах языки (C#, Java, С++, Smalltalk, Visual Basic и т.п.) должны отвечать трем основным принципам объектно-ориентированного программирования (ООП), которые перечислены ниже:

Инкапсуляция

Как данный язык скрывает детали внутренней реализации объектов и предохраняет целостность данных?

Наследование

Как данный язык стимулирует многократное использование кода?

Полиморфизм

Как данный язык позволяет трактовать связанные объекты сходным образом?

Прежде чем погрузиться в синтаксические детали реализации каждого принципа, важно понять базовую роль каждого из них.

Роль инкапсуляции

Инкапсуляция - это механизм программирования, объединяющий вместе код и данные, которыми он манипулирует, исключая как вмешательство извне, так и неправильное использование данных. В объектно-ориентированном языке данные и код могут быть объединены в совершенно автономный черный ящик. Внутри такого ящика находятся все необходимые данные и код. Когда код и данные связываются вместе подобным образом, создается объект. Иными словами, объект - это элемент, поддерживающий инкапсуляцию.

Т.е. инкапсуляция представляет собой способности языка скрывать излишние детали реализации от пользователя объекта. Например, предположим, что используется класс по имени DatabaseReader , который имеет два главных метода: Open() и Close().

Фиктивный класс DatabaseReader инкапсулирует внутренние детали нахождения, загрузки, манипуляций и закрытия файла данных. Программистам нравится инкапсуляция, поскольку этот принцип ООП упрощает кодирование . Нет необходимости беспокоиться о многочисленных строках кода, которые работают "за кулисами", чтобы реализовать функционирование класса DatabaseReader. Все, что потребуется - это создать экземпляр и отправлять ему соответствующие сообщения (например, "открыть файл по имени AutoLot.mdf, расположенный на диске С:").

С идеей инкапсуляции программной логики тесно связана идея защиты данных. В идеале данные состояния объекта должны быть специфицированы с использованием ключевого слова private (или, возможно, protected ). Таким образом, внешний мир должен вежливо попросить, если захочет изменить или получить лежащее в основе значение. Это хороший принцип, поскольку общедоступные элементы данных можно легко повредить (даже нечаянно, а не преднамеренно).

Основной единицей инкапсуляции в C# является класс , который определяет форму объекта. Он описывает данные, а также код, который будет ими оперировать. В C# описание класса служит для построения объектов, которые являются экземплярами класса. Следовательно, класс, по существу, представляет собой ряд схематических описаний способа построения объекта.

Код и данные, составляющие вместе класс, называют членами . Данные, определяемые классом, называют полями , или переменными экземпляра . А код, оперирующий данными, содержится в функциях-членах , самым типичным представителем которых является метод. В C# метод служит в качестве аналога подпрограммы. (К числу других функций-членов относятся свойства, события и конструкторы.) Таким образом, методы класса содержат код, воздействующий на поля, определяемые этим классом.

Роль наследования

Следующий принцип ООП - наследование - касается способности языка позволять строить новые определения классов на основе определений существующих классов. По сути, наследование позволяет расширять поведение базового (или родительского) класса, наследуя основную функциональность в производном подклассе (также именуемом дочерним классом):

Т.е. наследование представляет собой процесс, в ходе которого один объект приобретает свойства другого объекта. Это очень важный процесс, поскольку он обеспечивает принцип иерархической классификации. Если вдуматься, то большая часть знаний поддается систематизации благодаря иерархической классификации по нисходящей.

Если не пользоваться иерархиями, то для каждого объекта пришлось бы явно определять все его свойства. А если воспользоваться наследованием, то достаточно определить лишь те свойства, которые делают объект особенным в его классе. Он может также наследовать общие свойства своего родителя. Следовательно, благодаря механизму наследования один объект становится отдельным экземпляром более общего класса.

Роль полиморфизма

Последний принцип ООП - полиморфизм . Он обозначает способность языка трактовать связанные объекты в сходной манере. В частности, этот принцип ООП позволяет базовому классу определять набор членов (формально называемый полиморфным интерфейсом ), которые доступны всем наследникам. Полиморфный интерфейс класса конструируется с использованием любого количества виртуальных или абстрактных членов.

По сути, виртуальный член - это член базового класса, определяющий реализацию по умолчанию, которая может быть изменена (или, говоря более формально, переопределена) в производном классе. В отличие от него, абстрактный метод - это член базового класса, который не предусматривает реализации по умолчанию, а предлагает только сигнатуру. Когда класс наследуется от базового класса, определяющего абстрактный метод, этот метод обязательно должен быть переопределен в производном классе. В любом случае, когда производные классы переопределяют члены, определенные в базовом классе, они по существу переопределяют свою реакцию на один и тот же запрос.



Есть вопросы?

Сообщить об опечатке

Текст, который будет отправлен нашим редакторам: