Вы находитесь на странице: 1из 16

Тема: Концепции Объектно-ориентированного

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

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

Объект - это программный комплект связанных между собой переменных и


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

Что такое Сообщение (Message)?

Программные объекты связываются и взаимодействуют друг с другом с


помощью сообщений (messages).

Что такое Класс?

Класс - это "клише" или прототип, который определяет переменные и методы,


общие для всех объектов определенного вида.

Что такое Наследование?

Класс наследует состояние и поведение из своего суперкласса. Наследование


предоставляет мощный и естественный механизм для организации и
структурирования программных средств.

Что такое Интерфейс?

Интерфейс - это нечто подобное заготовке "контракта" в виде набора методов и


объявлений констант. Когда класс реализует интерфейс, он предусматривает
для реализации все методы, объявленные в этом интерфейсе.

Как все эти концепции перевести в Код?

В этом разделе рассмотрен небольшой апплет и показан код, который создает


объекты, реализует классы, посылает сообщения, устанавливает суперкласс и
реализует интерфейс.

Вопросы и Упражнения: Объектные Концепции

1
Проверка вашего понимания объектов, классов, сообщений и т.п. путем
выполнения нескольких упражнений и ответов на несколько вопросов.

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


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

Эти объекты реального мира имеют две характеристики: они все имеют
состояние (state) и все имеют поведение, или реакцию (behavior). Например,
собака может иметь какое-то состояние (кличка, масть, порода, голодная), и
может иметь какое-то поведение (лает, ищет, слюнявит ваши новые брюки).
Мотоциклы могут иметь состояние (два колеса, количество скоростей, текущее
положение педалей, текущая скорость) и могут иметь поведение (торможение,
ускорение, переключение скоростей).

Программные объекты моделируют объекты реального мира, и таким образом


тоже имеют состояние и поведение. Программные объекты отслеживают свое
состояние в переменных (variables) и реализуют свое поведение с помощью
методов (methods) .

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


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

Вы можете представить объекты реального мира с помощью программных


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

Ниже на иллюстрации показано общее визуальное представление


программного объекта:

2
Все, что программный объект знает (состояние - state) и может делать
(поведение - behavior), выражается внутри данного объекта с помощью
переменных и методов. Программный объект, который моделирует ваш
мотоцикл из реального мира, должен иметь переменные, которые показывают
текущее состояние мотоцикла: его скорость равна 10 mph, в текущий момент
включена 5-я передача, скорость вращения вала 90 rpm.. Эти переменные
формально называют переменными экземпляра (instance variables ), поскольку
они содержат состояние конкретного объекта - мотоцикла, а в объектно-
ориентированной терминологии конкретный объект называется экземпляром
(instance).

Ниже на иллюстрации показана модель мотоцикла, представленная как


программный объект.

Программная реализация мотоцикла может также иметь методы для ускорения,


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

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

Как вы можете увидеть из диаграммы, переменные объекта формируют центр


или ядро объекта. Методы расположены вокруг и скрывают ядро от других
объектов в программе. Упаковка переменных объекта внутрь защищенной зоны
своих методов называется инкапсуляцией (encapsulation). Эта концептуальная
картина объекта -- ядро переменных, запакованное в защитную мембрану

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

 Модульность (Modularity) -- Исходный код объекта может быть


написан и отлажен независимо от исходного кода других объектов.
Кроме того, объект можно просто передавать по системе. Вы можете
передать свой мотоцикл кому захотите, и он будет продолжать
действовать..
 Скрытие информации (information hiding) -- Объект имеет открытый
(public) интерфейс, который другие объекты могут использовать для
связи с ним. Но объект может использовать и закрытую (private)
информацию и методы, которые могут быть изменены в любой момент
без участия других объектов, которые могут от этого зависеть. Вам не
нужно представлять шестеренки в механизме переключения передач для
того, чтобы переключить скорость с 5-й на 4-ю.

Что такое Сообщение (Message)?


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

Программные объекты взаимодействуют и связываются между собой,


отправляя друг другу сообщения (messages). Если объект A хочет, чтобы объект
B выполнил один из своих методов, то объект A отправляет сообщение
(message) объекту B.

4
Иногда принимающему объекту нужно больше информации, чтобы точно
знать, что именно нужно делать -- например, если вы хотите переключить
передачу (change gears) на велосипеде, то нужно указать, какую передачу вы
хотите. Эта информация передается вместе с сообщением в виде параметров
(parameters).

Сообщение составляют три компонента:

1. Объект, которому адресовано сообщение (ваш велосипед или мотоцикл)


2. Имя выполняемого метода - переключение скоростей (changeGears)
3. Параметры, которые нужны методу (lower gear)

Эти три компонента дают принимающему объекту достаточно информации для


выполнения выбранного метода. Никакой другой информации или контекста не
требуется.

Сообщения предоставляют вам два основных преимущества:

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

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

При построении велосипедов фабрикант пользуется тем преимуществом, что


множество велосипедов можно строить по одному проекту -- было бы просто
неэффективно готовить новый индивидуальный проект для каждого
велосипеда.

В объектно-ориентированном программировании также можно иметь много


объектов, имеющих сходные характеристики: прямоугольники, записи о
сотрудниках, видео-клипы, и т.п. Как и на фабрике велосипедов, вы можете
использовать преимущество того факта, что объекты одного вида похожи, и что
для этих объектов вы можете создать заготовку (blueprint - "клише").
Программные "заготовки" для объектов называются классами (classes ).

Определение: Класс -- это "клише", или прототип, который


определяет переменные и методы, общие для всех объектов
некоторого вида.

Например, вы можете создать класс "велосипед" или "мотоцикл", объявляющий


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

6
Переменные экземпляра (instance variables) предусмотрены для каждого
экземпляра класса. Так, после создания класса "велосипед" перед тем, как вы
сможете им пользоваться, вам нужно его "тиражировать" - instantiate (создать
его экземпляр - instance). При создании экземпляра класса вы создаете объект
данного типа, а система резервирует память для переменных экземпляра,
объявленных в этом классе. Каждый экземпляр получает свою собственную
копию всех переменных экземпляра (instance variables), которые определены в
классе.

В дополнение к переменным экземпляра, классы могут определить переменные


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

7
Раздел Понятие о членах Экземпляра и Класса - Instance и Class Members
подробно описывает переменные и методы экземпляра, а также переменные и
методы класса.

Объекты против Классов

Вы, вероятно, обратили внимание, что на илллюстрациях объекты и классы


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

На иллюстрациях класс не затенен, потому что он представляет "заготовку"


объекта, а не сам объект. Объект же затенен, чтобы показать, что объект
действительно существует и вы можете его использовать.

Преимущества Классов

Объекты предоставляют преимущество модульности и скрытия информации.


Классы предоставляют преимущество повторного использования (reusability).
Фабрика повторно использует один и тот же проект велосипеда при
изготовлении все новых и новых велосипедов. Программисты повторно
используют один и тот же класс (значит, один и тот же код) для создания
множества объектов.

8
Что такое Наследование (Inheritance)?
В общем говоря, объекты определяются в терминах классов. Мы знаем много
об объекте, если знаем его класс. Даже если вы ничего не видели, если я скажу
вам, что это был велосипед, вы будете знать, что у него было два колеса, руль и
педали.

Объектно-ориентированные системы делают шаг дальше и позволяют


определять классы в терминах других классов. Например, горные велосипеды,
гоночные велосипеды и тандемы -- все они являются различными видами
велосипедов. В объектно-ориентированной терминологии горные велосипеды,
гоночные велосипеды и тандемы являются суб-классами (subclasses ) одного
класса -- велосипедов. Аналогично, велосипед является суперклассом
(superclass ) для горных велосипедов, гоночных велосипедов и тандемов.

Каждый суб-класс наследует (inherits ) состояние или структуру (в форме


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

Однако суб-классы не ограничиваются состоянием и поведением, которые


предусмотрены для них в суперклассе. О чем это говорит? Суб-классы могут
добавлять переменные и методы к тем, которые они унаследовали из
суперкласса. Тандемы имеют два седла и две пары педалей, некоторые горные
велосипеды имеют дополнительные скорости с пониженным передаточным
числом.

Суб-классы могут также переопределить (override ) наследуемые методы и


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

9
переопределить метод "переключение скоростей" так, чтобы седок мог
действительно использовать эти новые скорости.

Вы не лимитированы лишь одним слоем наследования. Дерево наследования,


или иерархия классов (class hierarchy ), может иметь любую нужную глубину.
Методы и переменные наследуются вниз от одного уровня к другому. В обшем,
чем ниже по иерархии появляется класс, тем более специализированным будет
его поведение.

Класс Object находится на вершине иерархии классов, и каждый класс


является его потомком (прямо или косвенно). Переменная типа Object может
содержать ссылку к любому объекту - такому, как экземпляру класса или к
массиву. Класс Object предоставляет реакции, которые обязательны для всех
объектов, выполняющихся в Java Virtual Machine. Например, все классы
наследуют метод toString класса Object, который возвращает строковое
представление объекта.

Преимущества Наследования

 Суб-классы предоставляет специализированное поведение на основе общих


элементов, предоставляемых суперклассом. Через механизм наследования
программисты могут много раз повторно использовать код суперкласса.
 Программисты могут реализовать также суперклассы, называемые абстрактными
классами (abstract classes ), которые определяют "изначальное" поведение.
Абстрактный суперкласс определяет и может частично реализовать поведение, но
большая часть класса не определена и не реализована. Другие программисты
заполняют детали для специализированных суб-классов.

10
Что такое Интерфейс?
В английском языке интерфейс (interface) - это устройство или система,
которую используют для взаимодействия друг с другом две не связанные
между собой некоторые реалии. В соответствии с этим определением,
дистанционный пульт является интерфейсом для взаимодействия между вами и
телевизором, английский язык является интерфейсом для общения двух людей,
а воинский устав в армии является интерфейсом между военными. Внутри
программного языка Java интерфейс (interface ) - это способ
взаимодействовать друг с другом двум не связанным между собой объектам.
Интерфейс, наверное, в чем-то похож на протокол (т.е. на соглашение о
правилах поведения). На самом деле и другие объектно-ориентированные
языки имеют функциональные возможности интерфейсов, но называют свои
интерфейсы протоколами.

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

Для работы со складской программой класс велосипедов должен согласиться с


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

Вы используете интерфейс для определения протокола поведения, который


может быть реализован любым классом в любом месте иерархии классов.
Интерфейсы удобны для следующего:

 Нахождения сходства между двумя не связанными друг с другом


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

11
Метод main

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

Метод main
Первая строка, выделенная жирным шрифтом в показанном ниже листинге,
начинает определение метода main.

/**
* The HelloWorldApp class implements an application
that
* simply displays "Hello World!" to the standard
output.
*/
class HelloWorldApp {
public static void main(String[] args) {
System.out.println("Hello World!"); //Display
the string.
}
}

Каждое приложение Java должно содержать метод main, сигнатура которого


выглядит следующим образом:

public static void main(String[] args)

Сигнатура метода (method signature) для метода main содержит три


модификатора:

 public показывает, что метод main может быть вызван любым другим
объектом. Раздел Управление доступом к членам класса описывает
добавления и исключения - ins и outs модификаторов доступа (access
modifiers), поддерживаемых языком Java.
 static показывает, что метод main является статическим методом, или
методом класса (class method) В разделе. Представление об экземплярах
и членах класса рассказывается о методах класса и переменных.
 void показывает, что метод main не возвращает какого-либо значения.

Как вызывается метод main

Метод main в языке Java аналогичен функции main в языках C и C++. Когда
интерпретатор Java исполняет приложение (вызывая управление для
управляющего класса приложения), он стартует с вызова метода main данного

12
класса. Затем метод main вызывает все остальные методы, необходимые для
запуска вашего приложения.

Если вы попытаетесь вызвать интерпретатор Java для класса, не имеющего


метода main, интерпретатор откажется запускать вашу программу и выдаст
сообщение об ошибке примерно такого вида:

In class NoMain: void main(String argv[]) is not defined

Аргументы для обращения к методу main

Как вы можете увидеть в показанном фрагменте кода, в данном случае метод


main принимает один аргумент в виде массива элементов типа String.

public static void main(String[] args)

Массив - это механизм, через который исполняющая система передает


информацию вашему приложению. Каждый элемент String в массиве
называется аргументом командной строки (command-line argument).
Аргументы командной строки позволяют пользователю воздействовать на
приложение без необходимости его повторной перекомпиляции. Например,
программа сортировки может позволить пользователю с помощью аргументов
командной строки указать, чтобы сортировка выполнялась в порядке убывания:

-descending

Приложение "Hello World" игнорирует свои аргументы командной строки, так


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

Замечания для программистов C и C++ : Количество и типы


аргументов, передаваемых методу main в исполняющей среде
Java (runtime environment), отличаются от количества и типов
аргументов, передаваемых в функцию main языков C и C++.
Дополнительные сведения см. в секции Аргументы командной
строки раздела Установка программных атрибутов .

Применение Классов и Объектов

Другими компонентами приложения Java являются поддерживающие объекты,


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

13
Применение Классов и Объектов
В этом разделе поясняется, как приложение "Hello World" использует классы и
объекты. Если вы не очень хорошо представляете концепции объектно-
ориентированного программирования, то данный раздел будет не всегда
понятен. В этом случае загляните в раздел Концепции объектно-
ориентированного программирования

Приложение "Hello World" является, видимо, самой простой программой Java,


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

Приложение "Hello World" использует другой класс -- класс System, который


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

Ниже в листинге ширным шрифтом выделен пример, иллюстрирующий


применение переменной класса (class variable) для класса System, и метода
экземпляра (instance method).

/**
* The HelloWorldApp class implements an application
that
* simply displays "Hello World!" to the standard
output.
*/
class HelloWorldApp {
public static void main(String[] args) {
System.out.println("Hello World!"); //Display
the string.
}
}

Применение метода или переменной класса

Давайте посмотрим на первый сегмент оператора:

System.out.println("Hello World!");

Сочетание System.out является полным именем переменной out в классе


System. Обратите внимание, что приложение никогда не порождает
(instantiates) экземпляр класса System и что на переменную out ссылаются
прямо из имени класса. Это потому, что out является переменной класса (class
variable) -- т.е. переменной, связанной с классом, а не с экземпляром класса. Вы

14
также можете связать с классом методы, получая таким образом методы класса
-- class methods.

Для ссылки на переменные и методы класса используется точечная нотация -


соединение имени класса и имени метода класса или переменной класса через
точку (".").

Применение метода или переменной экземпляра

Методы и переменные, которые не являются методами и переменными класса,


называются методами экземпляра (instance methods) и переменными
экземпляра (instance variables). Для ссылки на методы и переменные
экземпляра вы должны ссылаться на них из объекта.

Пока переменная out класса System является переменной класса, она ссылается
(refers) на экземпляр класса PrintStream (класс, предоставляемый средой
разработки Java), который реализует стандартный выходной поток.

Когда класс System загружается в приложение, он порождает (instantiates)


экземпляр выходного потока PrintStream и назначает новому объекту
PrintStream переменную класса out. Теперь, имея экземпляр класса, вы
можете вызвать один из методов экземпляра (instance methods):

System.out.println("Hello World!");

Как видите, на методы и переменные экземпляра вы ссылаетесь так же, как и на


методы и переменные класса. Вы объединяете ссылку на объект (out) и имя
метода или переменной экземпляра (println) через символ точки (".").

Компилятор Java позволяет вам составлять каскадные ссылки на методы и


переменные экземпляра или класса, получая при построении такую
конструкцию, какую мы видим в примере программы:

System.out.println("Hello World!");

Эта строка кода показывает "Hello World!" в стандартном выходном потоке


приложения (standard output stream).

Резюме

Метод класса или переменная класса связаны с конеретным классом.


Исполняющая система (runtime system) выделяет память для переменной класса
один раз на класс, независимо от того, сколько экземпляров этого класса
существует. Вы обращаетесь к переменным и методам класса через класс.

Метод экземпляра или переменная экземпляра связываются с конкретным


объектом (экземпляром класса). Каждый раз, когда вы порождаете объект,
новый объект получает копию каждой переменной экземпляра (instance

15
variable), определенной в этом классе. Вы обращаетесь к переменным и
методам экземпляра через объекты.

16

Вам также может понравиться