Конструируем класс. Поля.
Класс может иметь много разнообразных членов: поля, свойства, методы, события. Однако поля занимают особое место, только поля хранят данные созданного объекта. В этой статье будут рассмотрены правила и синтаксис определения полей в создаваемых вами классах и в других элементах программы.
«Все данные объектов хранятся только в полях.»
Второй закон Перфоленты.
В прошлой статье «Терминология: классы, объекты и типы в языке Перфолента» были показаны примеры создания простого класса. В этой статье мы начнем наполнять класс - научимся хранить данные в полях.
Концепция класса в языке программирования Перфолента.Net мало чем отличается от принятой в других языках, основанных на технологии .Net. Однако, некоторые различия существуют, это же другой язык. Давайте разберемся с устройством класса и способами его конструирования.
Для начала повторим известный нам пример:
Класс Собака Родитель Животное
//тут можно определить поля, свойства, методы и события
КонецКласса
Можно отметить, что этот класс не содержит никакой информации о собаке. Два экземпляра объектов этого класса будут представлять двух собак, но с точки зрения программы между ними не будет никакой разницы, кроме той, что это две разные собаки, т.е. операция Собака1 Это Собака2 вернёт Ложь. Надо бы добавить в класс информацию, которая могла бы помочь сделать собаку уникальной, хотя бы добавить ей имя.
Поля.
В языке Перфолента любая информация класса хранится в полях.
Поле — это участок памяти компьютера, в котором хранится один элемент данных конкретного экземпляра объекта указанного класса или элемент данных общий для класса.
Умнику на заметку: В других языках программирования общие для класса члены называются по разному. Например, в языке C# используется термин Static, т.е. общие для класса члены называют статическими, а в языке Visual Basic используется термин Shared, т.е. члены общего пользования. Термин используемый в Visual Basic гораздо лучше отражает суть. В языке Перфолента.Net используется прямое определение – член общий для класса. Что бы член стал общим для класса, он должен иметь атрибут ОбщийДляКласса.
Объявление поля.
Добавим в наш класс поле Имя:
Класс Собака Родитель Животное
&ВидноВсем Поле Имя тип Строка
КонецКласса
Теперь мы можем дать собакам имена, например, так:
Собака1 = Новый Собака
Собака1.Имя = "Жучка"
Собака2 = Новый Собака
Собака2.Имя = "Лайка"
Обратите внимание на атрибут поля ВидноВсем, без него поле было бы видно только тем методам, которые расположены внутри класса. Подробнее атрибуты видимости членов мы рассмотрим позднее.
Добавим в класс ещё полей:
Класс Собака Родитель Животное
&ВидноВсем Поле Имя тип Строка
&ВидноВсем Поле ДатаРождения тип Дата
&ВидноВсем Поле Вес тип Целое
&ВидноВсем Поле Цвет тип Строка
&ВидноВсем Поле Порода тип ПородыСобак //перечисление, которое мы пока не определили
КонецКласса
Теперь наш класс может содержать достаточно информации, что бы можно было создавать объекты, соответствующие конкретным собакам. Однако, иногда нам бы хотелось дополнительно хранить информацию о всех созданных объектах класса Собака, например, количество созданных объектов или общий вес поголовья для расчета количества необходимого корма.
Поле общее для класса позволяет хранить данные принадлежащие классу, а не конкретным объектам, поэтому общие для класса поля хранятся в единственном экземпляре, а не по одной копии на каждый объект, как хранятся обычные поля.
Класс Собака Родитель Животное
//-----------------------------------------------
//поля общие для класса
&ВидноВсем, ОбщийДляКласса
Поле КоличествоЭкземпляров тип Целое
&ВидноВсем, ОбщийДляКласса
Поле ОбщийВес тип Целое
//это поле не имеет атрибута ВидноВсем и будет видно только
методам описанным внутри класса
&ОбщийДляКласса Поле ВремяПоследнегоСозданияОбъекта тип Дата
//-----------------------------------------------
//поля для каждого экземпляра созданных объектов
&ВидноВсем Поле Имя тип Строка
&ВидноВсем Поле ДатаРождения тип Дата
&ВидноВсем Поле Вес тип Целое
&ВидноВсем Поле Цвет тип Строка
&ВидноВсем Поле Порода тип ПородыСобак //перечисление, которое мы пока не определили
//это поле не имеет атрибута ВидноВсем и будет видно только
методам описанным внутри класса
Поле ВремяСозданияОбъекта тип Дата
КонецКласса
Любой общий для класса член должен быть отмечен атрибутом ОбщийДляКласса, это относится и к полям.
Инициализация полей.
При создании экземпляра объекта поле получает значение по умолчанию для указанного типа поля. Например, поле типа Целое получит значение 0 (ноль), а поле типа Строка получит значение Неопределено.
Если при создании объекта поле должно получить другое значение, то можно присвоить необходимое значение так же, как это делается для переменных, например:
Поле
ВремяСозданияОбъекта тип Дата = ТекущаяДата
Точно так же могут инициализироваться и общие для класса поля, однако тут есть один нюанс. Поле общее для класса буде инициализировано один раз при первом обращении к любому члену этого класса. При создании экземпляра объекта значение общего для класса поля может быть прочитано и/или изменено, например, счетчик создаваемых объектов может быть увеличен на единицу.
Ограничение доступа на запись.
Иногда необходимо ограничить доступ к полю на запись. Например, если поле содержит значение однозначно определяющее объект, такое как идентификатор, то менять его на другое нельзя.
В языке Перфолента для ограничения доступа к полю на запись используется атрибут ТолькоЧтение, например:
&ВидноВсем, ТолькоЧтение Поле Идентификатор тип Целое = ++СчетчикОбъектов
Важно! Есть только два способа записать значение в поле имеющее атрибут ТолькоЧтение. Первая – это инициализация поля, вторая – установка значения в конструкторе.
Умнику на заметку: На самом деле, инициализация полей в любом случае происходит в конструкторе. Компилятор автоматически создаёт и размещает код инициализации в начале каждого имеющегося конструктора или в конструкторе по умолчанию, который компилятор создаёт, когда конструкторы в коде класса отсутствуют.
Запретить доступ к полю на чтение нельзя. В случае такой необходимости используйте свойства. Для свойств разрешается использовать атрибут ТолькоЗапись или определять единственный метод - Установить.
Множественное объявление полей одного типа.
Как и в случае с переменными, несколько полей одного типа можно определить одной строкой кода:
&ВидноВсем Поля Вес, Рост, ШиринаПлеч, РазмерОбуви,
РазмерШапки тип Число
= 0
Не забывайте при этом, что инициализирующее выражение вычисляется столько раз, сколько полей инициализируется, например:
Поле
Счетчик тип Целое
= 0
Поля Один, Два, Три, Четыре,
Пять тип Целое
= ++Счетчик
// и где-то в методе
ВыводСтроки ""+Один+Два+Три+Четыре+Пять
На экран консоли будет выведено: 12345.
Умнику на заметку: Хотя для объявления нескольких полей существует ключевое слово Поля, использование для этой же цели ключевого слова Поле не считается ошибкой.
Поля в интерфейсах.
Так как интерфейсы не содержат данных, в них не допустимо определение полей.
Поля в структурах.
Поля в структурах полностью аналогичны по правилам создания
и использования полям классов, описанным выше, за исключением одного нюанса:
инициализация полей структур допустима только
для полей общих для класса.
Структура МояСтруктура
&ВидноВсем, ОбщийДляКласса
Поле ОбщееПоле тип Целое = 111 // Правильно.
Инициализация допустима.
&ВидноВсем Поле ПриватноеПоле1 тип Целое // Правильно. Нет
инициализации.
&ВидноВсем Поле ПриватноеПоле2 тип Целое = 222 // ОШИБКА !!! Инициализация НЕ допустима.
КонецСтруктуры
Поля в модулях.
Как мы уже знаем, Модуль — это специализированная версия класса, экземпляры объектов которого создавать нельзя, а все члены являются общими для класса.
Поэтому полям, объявленным в модулях (в том числе в модуле Программа), нет необходимости задавать атрибут ОбщийДляКласса, они и так уже общие.
Программа МояПрограмма
Поле ВремяСтартаПрограммы
тип Дата = ТекущаяДата
КонецПрограммы
Модуль ОбщиеДанные
&ВидноВсем Поле ОбщаяСтоимость тип Число = 0
КонецМодуля
Поля в перечислениях.
Поля в перечислениях являются единственным возможным типом членов. Поэтому они создаются без ключевого слова Поле и по умолчанию имеют атрибут ВидноВсем. Указывать тип полей нельзя, т.к. все они имеют тип перечисления.
Отдельно остановимся на инициализации полей в перечислениях. Вы можете задать полю значение того типа, который указан как тип перечисления. Однако, Вы можете оставить инициализацию компилятору. В этом случае компилятор назначит значения полям, у которых значение не задано, с помощью счетчика, начиная со значения 0. При этом значения заданные вручную пропускаются.
Обратите внимание на то, что несколько полей перечисления могут иметь одинаковые значения. В том числе значение установленное вручную может совпасть со значением назначенным компилятором.
//в этом примере поля перечисления инициализированы вручную
Перечисление ПородыСобак тип
Целое
Овчарка = 1
Бульдог = 2
Такса = 3
//два следующих поля имеют одинаковые значения
Доберман = 4
ПохожаНаДобермана = 4
//...
КонецПеречисления
//в этом примере поля будут инициализированы компилятором
Перечисление ПородыСобак тип
Целое
Овчарка //поле получит значение 0
Бульдог //поле получит значение 1
Такса //поле получит значение 2
Доберман //поле получит значение 3
//...
КонецПеречисления
//в этом примере часть полей инициализированы вручную,
//а часть полей будут инициализированы компилятором
Перечисление ПородыСобак тип
Целое
Овчарка //поле получит значение 0
Бульдог = 99 //полю вручную задано значение 99
Такса //поле получит значение 1
Доберман //поле получит значение 2
//значение следующего поля установленное вручную совпадает
//с назначенным компилятором для предыдущего поля
ПохожаНаДобермана = 2 //полю вручную задано значение 2
//...
КонецПеречисления
Вывод: Поле – это единственное средство для хранения данных объекта находящегося в памяти компьютера. Поле обязательно имеет Тип и может быть либо общим для класса, создающимся в одном экземпляре, либо объектным, создающимся в каждом экземпляре объекта. В разных видах элементов программы поля имеют особенности написания и использования во время компиляции и выполнения программы.
Сергей Рогаткин
К началу статьи
Предыдущая статья:
Терминология: классы, объекты и типы в языке Перфолента
Следующая статья:
Конструируем класс. Конструкторы.
Вернуться в раздел:
Объектно ориентированное программирование (ООП) на языке Перфолента