Объектно-ориентированное программирование на языке Перфолента.NET — различия между версиями

Материал из ТХАБ.РФ
Перейти к: навигация, поиск
м (Копия официального описания ООП на Перфолента.NET (можно править и дополнять))
м
Строка 6: Строка 6:
 
* [[Перфолента.NET. ООП. Конструируем класс. Свойства]]
 
* [[Перфолента.NET. ООП. Конструируем класс. Свойства]]
 
** [[Перфолента.NET. ООП. Конструируем класс. Свойства. Часть 1. Упрощенное описание]] - на основе оригинального
 
** [[Перфолента.NET. ООП. Конструируем класс. Свойства. Часть 1. Упрощенное описание]] - на основе оригинального
 +
* [[Перфолента.NET. ООП. Атрибуты элементов программы]]
  
 
== Упрощенное описание ООП (Не править в процессе написания)==
 
== Упрощенное описание ООП (Не править в процессе написания)==
Строка 18: Строка 19:
 
* Поле - переменная Объекта
 
* Поле - переменная Объекта
 
  Поле это НЕ переменная, переменные "живут" только внутри методов и только пока метод выполняется, а поля это области памяти объектов... Свойства это вообще обёртки над полями...  
 
  Поле это НЕ переменная, переменные "живут" только внутри методов и только пока метод выполняется, а поля это области памяти объектов... Свойства это вообще обёртки над полями...  
* Атрибут Поля - свойство переменной
+
* [[Атрибут]] Поля - свойство переменной
 
** &ВидноВсем - к переменной могут обращаться другие объекты
 
** &ВидноВсем - к переменной могут обращаться другие объекты
 
** ОбщийДляКласса - Переменная в 1м экземпляре для всех объектов данного типа (Класса)
 
** ОбщийДляКласса - Переменная в 1м экземпляре для всех объектов данного типа (Класса)

Версия 12:59, 12 ноября 2020

Копия официального описания ООП на Перфолента.NET (можно править и дополнять)

Упрощенное описание ООП (Не править в процессе написания)

Для понимания темы Вам необходимо понимать что такое Функция и Процедура. Как их использовать.

Используемые, но не введённые понятия (временный раздел для редактирования)

  • Интерфейс
  • Конструктор (из примера кода)
  • Наследование
  • Структура
  • Поле - переменная Объекта
Поле это НЕ переменная, переменные "живут" только внутри методов и только пока метод выполняется, а поля это области памяти объектов... Свойства это вообще обёртки над полями... 
  • Атрибут Поля - свойство переменной
    • &ВидноВсем - к переменной могут обращаться другие объекты
    • ОбщийДляКласса - Переменная в 1м экземпляре для всех объектов данного типа (Класса)

Перечисления

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

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

Перечисление ПородыСобак тип Целое
           Овчарка = 1
           Бульдог = 2
           Такса = 3
           Доберман = 4
           //...
КонецПеречисления

Определения Класса и связанных понятий

Важно: 
  • Классы объявляются после конца программы (после оператора КонецПрограммы).
  • Функции и процедуры объявляются в самом конце программы между операторами КонецПроцедуры (Старт) и КонецПрограммы.

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

Класс состоит из:

  • Переменные - чтобы отличать их от обычных переменных в классах они называются Поля или Свойства (объекта).
  • Функции и Процедуры использующие эти переменные - чтобы отличать их от обычных функций и процедур в классах они называются Методы и События (функции которые реагируют на внешние по отношению к объекту события, например пользователь Щёлкает по кнопке "Закрыть окно")

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

Чем отличается Переменная от Поля ?

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

А если при использования Поля другой объект попытается записать в Поле "переменную правильного типа, но неправильного значения" или у объекта необходимо изменять несколько Полей синхронно или по определённому алгоритму ?

Для этого к выбранному Полю можно добавить 2 специальных метода со стандартными именами Прочитать и Установить. При попытке прочитать значение этого поля или записать в него какое либо значение автоматически будут вырываться соответствующие методы Прочитать и Установить - внутри которых будут прописаны соответствующие алгоритмы по проверке значения присваиваемых переменных и/или синхронному изменению значений нескольких Полей этого объекта. Чтобы отличить такое "Поле" от обычных его называют - Свойство.

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


Дополнительно

  • Атрибуты Поля (свойства Переменной Класса) - Переменные кроме своего значения и свойства ТИП, имеют ещё (Свойство) &ВидноВсем. Чтобы отличать свойства объекта и свойства переменных, свойства переменных называются Атрибуты.
    • &ВидноВсем - без этого Атрибута Поля (переменной) поле было бы видно только тем методам (функциям и процедурам), которые расположены внутри класса. - Т.е. Атрибут ВидоВсем делает из Поля (Переменной) Интерфейс ?

Объявление и создание Класса

Рассмотрим определение простейшего класса:

Класс Животное
           //тут можно определить свойства и методы работы с классом
КонецКласса

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

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

Добавляем в Класс Переменные - Поля

В языке Перфолента любая информация класса хранится в Полях.

Поле — это переменная, в которой хранится один элемент данных конкретного объекта (экземпляра класса) указанного класса или элемент данных общий для класса.

Класс Собака
// общее для всех экземпляров класса Поле (переменная) 
Объект "Собака1"
// Поле (Переменная) индивидуальная  для каждого объекта
Имя = "Жучка"
Объект "Собака2"
// Поле (Переменная) индивидуальная  для каждого объекта
Имя = "Лайка"

Общее Для всех объектов (Экземпляров Класса) Поле

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

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

не проверенное

Для программистов: В других языках программирования общие для класса члены называются по разному. Например, в языке C# используется термин Static, т.е. общие для класса члены называют статическими, а в языке Visual Basic используется термин Shared (разделяемый между несколькими), т.е. члены общего пользования. Термин используемый в Visual Basic гораздо лучше отражает суть. В языке Перфолента.Net используется прямое определение – член общий для класса. Что бы член стал общим для класса, он должен иметь атрибут ОбщийДляКласса.

Добавим в наш класс поле Имя:

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

Теперь мы можем дать собакам имена, например, так:

Собака1 = Новый Собака
Собака1.Имя = "Жучка"    
Собака2 = Новый Собака
Собака2.Имя = "Лайка"    

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

Добавим в класс ещё полей:

Класс Собака Родитель Животное
           &ВидноВсем Поле Имя тип Строка
           &ВидноВсем Поле ДатаРождения тип Дата
           &ВидноВсем Поле Вес тип Целое
           &ВидноВсем Поле Цвет тип Строка
           &ВидноВсем Поле Порода тип ПородыСобак //перечисление, которое мы пока не определили
КонецКласса

Общее Для всех объектов (Экземпляров Класса) Поле

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

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

Класс Собака Родитель Животное
           //поля общие для класса
           &ВидноВсем, ОбщийДляКласса Поле КоличествоЭкземпляров тип Целое
           &ВидноВсем, ОбщийДляКласса Поле ОбщийВес тип Целое
           //это поле не имеет атрибута ВидноВсем и будет видно только методам (функциям) описанным внутри класса
           &ОбщийДляКласса Поле ВремяПоследнегоСозданияОбъекта тип Дата
           //-----------------------------------------------
           //поля для каждого экземпляра созданных объектов
           &ВидноВсем Поле Имя тип Строка
           &ВидноВсем Поле ДатаРождения тип Дата
           &ВидноВсем Поле Вес тип Целое
           &ВидноВсем Поле Цвет тип Строка
           &ВидноВсем Поле Порода тип ПородыСобак //перечисление, которое мы пока не определили
           //это поле не имеет атрибута ВидноВсем и будет видно только методам описанным внутри класса
           Поле ВремяСозданияОбъекта тип Дата
КонецКласса

Любой общий для класса член должен быть отмечен атрибутом ОбщийДляКласса, это относится и к полям.

Задание первоначальных значений переменных (Полей) при создании Объекта (Инициализация полей)

При создании объекта (экземпляра класса) его Поле получает значение по умолчанию для указанного типа поля. Например, поле типа Целое получит значение 0 (ноль), а поле типа Строка получит значение Неопределено.

Если при создании объекта поле должно получить другое значение, то можно присвоить необходимое значение так же, как это делается для переменных, например:

Поле ВремяСозданияОбъекта тип Дата = ТекущаяДата

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

Поля в интерфейсах.

Так как интерфейсы не содержат данных, в них не допустимо определение полей.

Поля в структурах.

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

Структура МояСтруктура
           &ВидноВсем, ОбщийДляКласса Поле ОбщееПоле тип Целое = 111     // Правильно. Инициализация допустима.
           &ВидноВсем Поле ПриватноеПоле1 тип Целое     // Правильно. Нет инициализации.
           &ВидноВсем Поле ПриватноеПоле2 тип Целое = 222     // ОШИБКА !!! Инициализация НЕ допустима.
КонецСтруктуры

Поля в модулях.

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

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

Программа МояПрограмма
           Поле ВремяСтартаПрограммы тип Дата = ТекущаяДата
КонецПрограммы
Модуль ОбщиеДанные
           &ВидноВсем Поле ОбщаяСтоимость тип Число = 0
КонецМодуля

Поля в перечислениях

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

Перечисление ПородыСобак тип Целое
           Овчарка = 1
           Бульдог = 2
           Такса = 3
           Доберман = 4
           //...
КонецПеречисления

Множественное определение полей одного типа.

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

&ВидноВсем Поле Вес, Рост, ШиринаПлеч, РазмерОбуви, РазмерШапки тип Число = 0

Не забывайте при этом, что инициализирующее выражение вычисляется столько раз, сколько переменных инициализируется, например:

Поле Счетчик тип Целое = 0
Поле Один, Два, Три, Четыре, Пять тип Целое = ++Счетчик
// и где-то в методе
ВыводСтроки ""+Один+Два+Три+Четыре+Пять

На экран консоли будет выведено: 12345.


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

Наследование (надо ввести понятие ниже)

Создадим классы Кошка и Собака, указав, что родителем для них является Класс Животное:

Класс Кошка Родитель Животное
           //тут можно определить свойства и методы работы с классом
КонецКласса
Класс Собака Родитель Животное
           //тут можно определить свойства и методы работы с классом
КонецКласса

Теперь покажем, как можно эти классы использовать:

МойКот = Новый Кот // создадим объект МойКот сложного типа - Кот
ПриветЖивотное(МойКот) // передадим объект МойКот 
МояСобака = Новый Собака
ПриветЖивотное(МояСобака)
//где-то ниже определим процедуру
Процедура ПриветЖивотное(МоёЖивотное тип Животное) // процедура принимает объект типа Животное
       Выбор Для МоёЖивотное // оператор выбора Выбор Для
       Когда ЭтоТип Кот
               ВыводСтроки "Привет кот!"
       Когда ЭтоТип Собака
               ВыводСтроки "Привет собака!"
       Иначе
               ВыводСтроки "Привет не известное животное!"
       КонецВыбора
КонецПроцедуры

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

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

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

Ссылки