Язык программирования Перфолента.Net - Официальный сайт

 Язык программирования Перфолента.Net - Официальный сайт.

Поиск   
Главная :: О проекте :: Контакты :: Обратная связь :: Благодарности :: ВходГость

   >   >   >   > 



Конструируем класс. Конструкторы.

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


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

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

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

Собака1 = Новый Собака
Собака1.Имя = "Жучка"
Собака1.Вес = 12

Можно заметить, что нам всё время приходится повторять имя объекта Собака1. Существует специальный синтаксис инициализации объектов, который называется «Инициализатор». Этот синтаксис позволяет немного упростить код и не повторять имя объекта (или выражение, которое возвращает объект).

Собака1 = Новый Собака { .Имя = "Жучка", .Вес = 12 }

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

Вот тут нам на помощь придут специальные методы, которые называются конструкторами.

 

Конструкторы объекта.

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

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

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

Посмотрим на простейший конструктор:

Класс Собака Родитель Животное
            Поле ДатаСозданияОбъекта тип Дата
            &ВидноВсем
            Конструктор
                        ДатаСозданияОбъекта = ТекущаяДата()
            КонецКонструктора
КонецКласса

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

Посмотрим, как это делается:

Класс Собака Родитель Животное
            &ВидноВсем Поле Имя тип Строка
            &ВидноВсем
            Конструктор(ИмяСобаки тип Строка)
                        Имя = ИмяСобаки
            КонецКонструктора
КонецКласса

Имея такой конструктор, мы можем задать имя собаки непосредственно при создании объекта оператором Новый:

Собака1 = Новый Собака("Жучка")    

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

Класс Собака Родитель Животное
            &ВидноВсем Поле Имя тип Строка
            &ВидноВсем Поле Вес тип Целое
            &ВидноВсем Поле Цвет тип Строка
            &ВидноВсем
            Конструктор(ИмяСобаки тип Строка)
                        Имя = ИмяСобаки
            КонецКонструктора
            &ВидноВсем
            Конструктор(ИмяСобаки тип Строка, ВесСобаки тип Целое)
                        Имя = ИмяСобаки
                        Вес   = ВесСобаки
            КонецКонструктора
            &ВидноВсем
            Конструктор(ИмяСобаки тип Строка, ВесСобаки тип Целое, ЦветСобаки тип Строка)
                        Имя = ИмяСобаки
                        Вес = ВесСобаки
                        Цвет = ЦветСобаки
            КонецКонструктора
КонецКласса

Теперь мы можем создавать объект любым из 3-х способов:

Собака1 = Новый Собака("Жучка")    

Собака1 = Новый Собака("Жучка", 12)    

Собака1 = Новый Собака("Жучка", 12, "Белый")    

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

Теоретически, что бы уменьшить количество кода мы могли бы заменить три конструктора одним, задав параметрам значения по умолчанию. Например, так:

Класс Собака Родитель Животное
            &ВидноВсем Поле Имя тип Строка
            &ВидноВсем Поле Вес тип Целое
            &ВидноВсем Поле Цвет тип Строка
            &ВидноВсем
            Конструктор( ИмяСобаки тип Строка = "Безымянная", ВесСобаки тип Целое = 0, ЦветСобаки тип Строка = "Цвет не известен")
                        Имя = ИмяСобаки
                        Вес = ВесСобаки
                        Цвет = ЦветСобаки
            КонецКонструктора
КонецКласса

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

Класс Товар
            &ВидноВсем Поле Артикул тип Строка
            &ВидноВсем Поле Наименование тип Строка
            &ВидноВсем
            Конструктор( ОбязательныйАртикул тип Строка, НеОбязательноеНаименование тип Строка = "Товар без наименования")
                        Артикул = ОбязательныйАртикул
                        //вызываем функцию проверки артикула на уникальность
                        Если НЕ ПроверитьУникальностьАртикула(Артикул)
                                    ВызватьИсключение "Артикул не уникален!"
                        КонецЕсли
                        Наименование = НеОбязательноеНаименование
            КонецКонструктора
КонецКласса

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

Класс Собака Родитель Животное
            &ВидноВсем Поле Имя тип Строка
            &ВидноВсем Поле Вес тип Целое
            &ВидноВсем Поле Цвет тип Строка

            Конструктор
                    //не видимый извне конструктор фактически запрещает внешнему коду создавать экземпляры объектов
            КонецКонструктора

            //функция обязательно должна быть общей для класса
            &ВидноВсем, ОбщийДляКласса
            Функция СоздатьРыжуюСобаку (ИмяСобаки тип Строка, ВесСобаки тип Целое) тип Собака
                        НоваяСобака = Новый Собака //отсюда конструктор прекрасно виден
                        НоваяСобака.Имя = ИмяСобаки
                        НоваяСобака.Вес = ВесСобаки
                        НоваяСобака.Цвет = "Рыжий"
                        Возврат НоваяСобака
            КонецФункции
КонецКласса

Теперь посмотрим, как создать экземпляр такого объекта:

РыжаяСобака = Собака.СоздатьРыжуюСобаку("Жучка", 10)

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

Класс Генератор
            //это поле хранит единственный экземпляр объекта класса Генератор
            &ОбщийДляКласса  Поле ТекущийГенератор тип Генератор = Новый Генератор

            Конструктор
                    //не видимый извне конструктор фактически запрещает внешнему коду создавать экземпляры объектов
            КонецКонструктора

            //функция обязательно должна быть общей для класса
            &ВидноВсем, ОбщийДляКласса
            Функция ПолучитьЕдинственныйЭкземпляр()  тип Генератор
                        Возврат ТекущийГенератор
            КонецФункции
КонецКласса

В результате мы можем только получить ссылку на единственный экземпляр объекта класса Генератор:

СсылкаНаГенератор = Генератор.ПолучитьЕдинственныйЭкземпляр()

 

Конструктор общий для класса.

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

&ОбщийДляКласса
Конструктор
                //Тут можно разместить код инициализации общих для класса полей
КонецКонструктора

 

 

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

 




К началу статьи


Предыдущая статья:
Конструируем класс. Поля.

Следующая статья:
Конструируем класс. Свойства.

Вернуться в раздел:
Объектно ориентированное программирование (ООП) на языке Перфолента
  Поддержи проект!

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

  Новости:
      04.01.2025 Опубликован новый релиз дистрибутива языка программирования Перфолента.Net версии 0.4.15.0_CE
      23.09.2024 Опубликована новая статья: "Конструируем класс. Делегаты."
      30.08.2024 Опубликован новый релиз дистрибутива языка программирования Перфолента.Net версии 0.4.14.0
      24.05.2024 Обновлён справочный раздел сайта
      01.07.2023 Новая версия 0.4.13.0 языка программирования Перфолента.Net
       Все новости