3. Понятие класса и объекта
1. Понятие объекта
Объект – структура, которая объединяет данные и методы, которые эти данные обрабатывают. Это позволят разграничить область применения методов. Объект – это строительный блок объектно-ориентированных программ. Объектно-ориентированная программа является, по сути, набором объектов. Объект состоит из трех частей:
имя объекта;
состояние (данные объекта, переменные состояния). Состояние объекта характеризуется перечнем всех свойств данного объекта и текущими значениями каждого из этих свойств;
методы (операции).
Данные объектов. Данные, содержащиеся в объекте, представляют его состояние. В терминологии ООП, эти данные называются атрибутами. Например, атрибутами работника могут быть имя, фамилия, пол, дата рождения, номер телефона и так далее. В разных объектах атрибуты имеют разное значение.
Поведение объектов. Поведение объекта – то, что он может сделать (в структурном программировании это реализовывалось функциями, процедурами, подпрограммами).
Сообщения – механизм коммуникации между объектами. Например, когда объект А вызывает метод объекта B, объект A отправляет сообщение объекту B. Ответ объекта B определяется его возвращаемым значением. Только «открытые» методы могут вызываться другим объектом.
2. Понятие класса
Каждый объект определяется общим шаблоном, который называется классом. В рамках класса задается общий шаблон, структура, на основе которой затем создаются объекты. Данные, относящиеся к классу, называются полями класса, а программный код для их обработки – методами класса. Поля и методы иногда называют общим термином – члены класса.
В классе описываются, какого типа данные относятся к классу, а также то, какие методы применяются к этим данным. Затем, в программе на основе того или иного класса создается экземпляр класса (объект), в котором указываются конкретные значения полей и выполняются необходимые действия над ними.
Согласно конвенции кода и правилам языка Java:
каждый класс должен содержаться в своем отдельном файле с расширением .java;
название файла должно совпадать с названием класса;
класс должен быть именем существительным;
имя класса должно его описывать;
имя класса начинается с большой буквы;
если имя состоит из нескольких слов, то каждое слово начинается с большой буквы.
Рассмотрим разницу между объектом и классом на примере. Определим класс Cat
и Dog
. Описание класса производится через указание полей (данных) и методов класса. Для класса Cat
в качестве полей укажем name
(кличку кота) и color
(окрас). Для класса Dog
задаем поля name
(кличка), color
(окрас) и breed
(порода).
Помимо полей, определим методы для этих классов. Методы – это то, что может делать объект класса (или что можно делать с объектом). Коты будут мяукать, и ловить мышей, а собаки лаять и вилять хвостом.
Таким образом, мы определили шаблоны, на основании которых впоследствии будут создаваться экземпляры классов или объекты. Разница между классом и объектом такая же, как между абстрактным понятием и реальным объектом. При создании объекта класса задаются конкретные значения для полей. Когда мы говорим о собаке или кошке вообще, как понятии, мы имеем в виду домашних животных, у которых есть имя, окрас и прочие характеристики. Это абстрактные понятия, которые соответствуют классу. А вот если речь идет о конкретном Шарике или Мурзике, то это уже объекты, экземпляры класса.
3. Синтаксис классов
Рассмотрим синтаксис описания классов в Java. Описание класса начинается с ключевого слова class. После этого следует имя класса и в фигурных скобках тело класса. Тело класса состоит из описания членов класса – полей и методов.
Для объявления класса служит ключевое слово class. Упрощенная форма определения класса имеет вид:
Данные или переменные, определенные в классе, называются переменными экземпляра, поскольку каждый экземпляр класса (объект) содержит собственные копии этих переменных. Таким образом, данные одного объекта отделены и отличаются от данных другого объекта.
Код содержится в теле методов. В большинстве классов действия над переменными и доступ к ним осуществляют методы этого класса. Таким образом, методы определяют порядок использования данных класса.
4. Пример простого класса
Создадим класс Box
, который описывает контейнер, допустим, на каком-то складе.
Класс Box
определяет три переменные экземпляра: width
(ширина), height
(высота) и depth
(глубина). В настоящий момент класс Box
не содержит никаких методов.
Как мы уже говорили, класс определяет новый тип данных. В данном случае новый тип данных называется Box
. Это имя будет использоваться для объявления объектов типа Box
. Не следует забывать, что объявление class
создает только шаблон, но не конкретный объект. Таким образом, приведенный выше код не приводит к появлению каких-нибудь объектов типа Box
.
Чтобы действительно создать объект класса Box
, нужно воспользоваться оператором new
После выполнения этого оператора объект myBox
станет экземпляром класса Box
. Таким образом, он обретет "физическое" существование.
Также следует напомнить, что каждый объект содержит собственную копию переменной экземпляра, которая определена в классе. Каждый объект типа Box
будет содержать собственные копии переменных width
, height
и depth
(рис. 4.2).
Изменения в переменных экземпляра одного объекта не влияют на переменные экземпляра другого объекта. Таким образом, каждый объект класса Box
будет содержать собственные копии переменных width
, height
и depth
. Для доступа к этим переменным служит оператор-точка (.)
. Эта операция связывает имя объекта с именем переменной экземпляра. Например, чтобы присвоить переменной width
экземпляра myBox
значение 100, нужно выполнить следующий оператор:
Этот оператор предписывает компилятору, что копии переменной width
, хранящейся в объектe myBox
, требуется присвоить значение 100. В общем, операция-точка служит для доступа как к переменным экземпляра, так и к методам в пределах объекта.
Ниже приведет пример программы, в которой используется класс Box
Как пояснялось ранее, каждый объект содержит собственные копии переменных экземпляра. Это означает, что при наличии двух объектов класса Box
каждый из них будет содержать собственные копии переменных width
, height
и depth
. Следует, однако, иметь ввиду, что изменения в переменных экземпляра одного объекта не влияют на переменные экземпляра другого. Например, в следующей программе объявлены два объекта класса Box
:
Программа выводит следующий результат:
Как видите, данные из объекта myBox1
полностью изолированы от данных, содержащихся в объекте myBox2
.
5. Методы класса
Как упоминалось ранее, классы состоят из двух компонентов: переменных экземпляра и методов. Общая форма метода выглядит следующим образом:
где возвращаемый тип
означает конкретный тип данных, возвращаемый методом. Он может быть любым допустимым типом данных, в том числе и типом созданного класса. Если метод не возвращает значение, то его возвращаемым типом должен быть void
. В качестве имени методов может быть любой допустимый идентификатор, кроме тех, которые уже используются другими элементами кода в текущей области действия. А список параметров
обозначает последовательность пар "тип-идентификатор", разделенных запятыми. По существу, параметры - это переменные, которые принимают значения аргументов, передаваемых методу во время его вызова. Если у метода отсутствуют параметры, то список параметров оказывается пустым. Методы, возвращаемый тип которых отличается от void
, возвращают значение вызывающей части программы с помощью оператора return
.
Вернемся к нашему примеру с классом Box
. Было бы логично, если бы расчет объема коробки выполнялся в классе Box
, поскольку объем коробки зависит от ее размеров. Для этого добавим в класс Box
метод getVolume()
Внимательно рассмотрим две следующие строки кода
В первой строке вызывается метод volume()
для объекта myBox1
. Следовательно, метод volume()
вызывается по отношению к объекту myBox1
, для чего было указано имя объекта, а вслед за ним - операция-точка. Таким образом, в результате вызова метода myBox1.volume()
выводится объем коробки, определяемого объектом myBox1
, а в результате вызова метода myBox2.volume()
- объем коробки, определяемого объектом myBox2
.
При вызове метода myBox1.volume()
исполняющая система Jаvа передает управление коду, определенному в теле метода volume()
. По окончании выполнения всех операторов в теле метода управление возвращается вызывающей части программы и далее ее выполнение продолжается со строки кода, следующей за вызовом метода. В самом общем смысле метод - это способ реализации подпрограмм в Java.
В методе volume()
следует обратить внимание на еще одну очень важную особенность: ссылка на переменные экземпляра width
, height
и depth
делается непосредственно без указания перед ними имени объекта или операции-точки. Когда в методе используется переменная экземпляра, определенная в его же классе, это делается непосредственно, без указания явной ссылки на объект и применения операции-точки . Это становится понятным, если немного подумать. Метод всегда вызывается по отношению к какому-то объекту его класса. Как только этот вызов сделан, объект известен. Таким образом, в теле метода вторичное указание объекта совершенно излишне. Это означает, что переменные экземпляра width
, height
и depth
неявно ссылаются на копии этих переменных, хранящиеся в объекте, который вызывает метод volume()
.
Подведем краткие итоги. Когда доступ к переменной экземпляра выполняется из кода, не входящего в класс, где определена переменная экземпляра, следует непременно указать объект с помощью операции-точки. Но когда такой доступ осуществляется из кода, входящего в класс, где определена переменная экземпляра, ссылка на переменную может делаться непосредственно. Эти же правила относятся и к методам.
Следует обратить внимание, что метод getVolume()
возвращает значение 3000, и это значение рассчитанного объема сохраняется в переменной vol
. При обращении с возвращаемыми значениями следует принимать во внимание два важных обстоятельства:
тип данных, возвращаемых методом, должен быть совместим с возвращаемым типом, указанным в методе. Так, если какой-нибудь метод должен возвращать логический тип boolean, то возвратить из него целочисленное значение нельзя;
переменная, принимающая возвращаемое методом значение (например,
vol
), также должна быть совместима с возвращаемым типом, указанным для метода.
Last updated
Was this helpful?