Устаревшее его использование (не показан в вышестоящем синтаксисе), использовалось, чтобы создать объект (теперь мы используем конструктор класса).
Переменные функции и типы процедуры могут использоваться как указатели к функциям и процедурам с теми же самыми параметрами и конфигурацией возвращаемого значения (сигнатура).
function AddUp(a, b : Integer) : Integer; . type TFunc = function(a, b : Integer) : Integer; var func : TFunc; c : Integer; begin func := AddUp; c := func(12, 34); // Вызывает функцию AddUp end;
Со спецификатором Of Object, тип подпрограммы должен быть установлен на указатель метода в объекте.
type TMyClass = class public procedure StoreName(name : string); end;
TProc = procedure(name : string) of object; var proc : TProc; myClass : TMyClass; begin myClass := TMyClass.Create; proc := myClass.StoreName; proc(‘My name’); // Вызывает myClass.StoreName end;
Примечания
Такие типы подпрограмм в действительности яявляются указателями и на код и на части данных метода.
Похожие команды
Class Начинает объявление типа объектного класса
Function Определяет подпрограмму, которая возвращает значение
Procedure Определяет подпрограмму, которая не возвращает значение
TObject Тип базового класса, который является предком для всех других классов
С этого урока мы начнем осваивать так называемое объектно-ориентированное программирование (ООП). ООП — идеология программирования, основанная на объединении данных и процедур, которые могут работать с этими данными в совокупности, называемые классами. Ранее мы вкратце упоминали о них, и теперь пришло время в них разобраться. Сутью ООП является использование привычной нам в обыденной жизни объектной модели. Каждый объект имеет свои свойства и с ним можно совершить характерные для него действия. Класс — это тип объекта. Класс описывает и реализует те самые свойства и действия. Объект в нашем понимании будет являться переменной, типом который и будет являться какой-то класс. Полями класса мы будем называть его свойства, а методами — действия, которые можно совершить с экземпляром этого класса (объектом). В некоторой степени классы можно сравнить с обыкновенными записями, которые мы рассмотрели в прошлом уроке. Однако классы имеют гораздо больше возможностей, с которыми мы будем знакомиться постепенно на протяжении большого количества уроков.
Прежде чем создавать какие-то объекты, давайте создадим хотя бы один тип объектов, т.е. класс. Класс описывается в разделе type следующим образом: [cc lang=»delphi»]type TBook = class public PagesCount: integer; Title, Author: string;
function CompareWithBook(OtherBook: TBook): integer; procedure ShowTitle;
Вы уже наверное догадались, что наши методы, как и обычные процедуры и функции, Установим курсор на названии любого метода и нажмем сочетание клавиш Ctrl+Shift+C. Это создаст нам пустые шаблоны реализаций всех методов класса. Выглядеть это будет примерно следующим образом: [cc lang=»delphi»]
function TBook.CompareWithBook(OtherBook: TBook): integer; begin
constructor TBook.Create(NewTitle, NewAuthor: string; NewPagesCount: integer); begin
procedure TBook.ShowTitle; begin
end; [/cc] Начнем с реализации самого интересного — конструктора. Как уже упоминалось выше, внутри конструктора мы должны присвоить некоторым полям определенные значения (не обязательно всем) и создать все нужные нам вложенные объекты. Т.к. вложенных объектов внутри нашего класса нет, да и рассматривать создание объекта (экземпляра класса) мы будем чуть позже, то нам нужно только присвоить полям Title, Author и PagesCount нужные значения. Эти значения мы будем передавать при помощи параметров конструктора. Однако в конструкторе (в отличие от нашего примера) мы можем и не присваивать значения всем полям. Нетрудно догадаться, каким образом будет выглядеть реализация конструктора: [cc lang=»delphi»]constructor TBook.Create(NewTitle, NewAuthor: string; NewPagesCount: integer); begin Title := NewTitle; Author := NewAuthor; PagesCount := NewPagesCount; end;[/cc] Я уже говорил, что внутри методов класса мы имеем доступ ко всем другим полям и методам данного класса (за исключением описанных внутри специальных модификаторов доступа, их мы будем рассматривать позже). Так вот и в конструкторах (как и в методах) мы можем работать с полями класса как с локальными переменными. Этим мы и воспользовались — присвоили полям класса изначальные значения. Теперь реализуем метод CompareWithBook: [cc lang=»delphi»]function TBook.CompareWithBook(OtherBook: TBook): integer; begin Result := Abs(OtherBook.PagesCount — PagesCount); end;[/cc] В этом примере мы получаем модуль разности количества страниц другой книги и данной. В нашем случае OtherBook — это объект типа/класса TBook. Т.е. OtherBook — является экземпляром класса TBook. Методу одной книги CompareWithBook, который мы будем использовать, мы будем передавать в качестве параметра другую книгу типа TBook. И соответственно к своему полю PagesCount из метода данного класса можно обратиться как и к локальной переменной. Также, мы можем обращаться к своим полям и методам при помощи зарезервированной переменной Self: [cc lang=»delphi»]Result := Abs(OtherBook.PagesCount — Self.PagesCount);[/cc] Ну и наконец реализуем метод ShowTitle. Этот метод будет выводить в сообщении ShowMessage автора книги и название в кавычках. Еще один наглядный пример обращения к полям класса: [cc lang=»delphi»]procedure TBook.ShowTitle; begin ShowMessage(Author + ‘ «‘ + Title + ‘»‘); end;[/cc]
После того как мы описали класс и реализовали все его методы, мы можем использовать наш класс, а именно создавать экземпляры этого класса — объекты. Сначала опишем объект в разделе var как обыкновенную переменную: [cc lang=»delphi»]var MyBook: TBook;[/cc] Затем приступим к созданию объекта. Для того чтобы использовать экземпляр класса, просто объявить его недостаточно. Его нужно создать. Если объект не создать, то при первом обращении к какому-либо полю или методу класса, неминуемо будет вызвана ошибка «Access Violation». Поэтому научимся создавать объекты: [cc lang=»delphi»]MyBook := TBook.Create(‘Delphi для начинающих’, ‘Cyberexpert’, 1000);[/cc] Воспользуемся нашим конструктором Create. Как вы видите, мы должны присвоить нашему объекту конструктор создаваемого класса. При необходимости конструктору нужно передать параметры. Конструкторов у класса может быть несколько. Вот теперь мы можем использовать наш объект так как нам нужно. Давайте создадим еще одну книгу: [cc lang=»delphi»]MyBook2 := TBook.Create(‘Delphi для начинающих 2’, ‘Cyberexpert’, 1300);[/cc] И попробуем сравнить эти книги при помощи нашего метода CompareWithBook у класса TBook. Для этого вызовем этот метод у одного объекта, и в качестве параметра передадим другой объект типа TBook: [cc lang=»delphi»]a := MyBook.CompareWithBook(MyBook2); ShowMessage(IntToStr(a));[/cc] Можем также вывести на экран автора и название книги: [cc lang=»delphi»]MyBook.ShowTitle;[/cc] Предположим мы каким-то образом использовали наш объект и теперь он стал нам не нужен. Зачем ему занимать лишнюю оперативную память? Давайте его удалим! Сделать это можно при помощи деструктора. У каждого класса по-умолчанию помимо конструктора Create существует деструктор Destroy. Т.е. их не надо описывать и создавать, у каждого класса они уже есть. Только в нашем нестандартном конструкторе мы реализовали присвоение полям начальных данных. Если бы мы не создали свой конструктор, то использовали бы стандартный при создании объекта, и изначальных параметров передать не смогли бы. Также можно создать и деструктор, давайте его сделаем и будем в нем выводить некоторое сообщение: [cc lang=»delphi»] TBook = class public PagesCount: integer; Title, Author: string;
function CompareWithBook(OtherBook: TBook): integer; procedure ShowTitle;
constructor Create(NewTitle, NewAuthor: string; NewPagesCount: integer); destructor Destroy; // так деструктор будет выглядеть в описании класса end;[/cc] Реализация деструктора: [cc lang=»delphi»]destructor TBook.Destroy; begin ShowMessage(‘Уничтожается книга «‘ + Title + ‘»‘); end;[/cc] Т.е. мы будем выводить сообщение перед уничтожением объекта. Для чего же еще нужен деструктор? Для того чтобы уничтожать также и все вложенные в классе объекты. Т.е. когда внутри класса существует объект, чтобы его использовать, мы должны этот «подобъект» создать в конструкторе и уничтожить в деструкторе. Соответственно, чтобы вызвать деструктор мы вызовем его как обыкновенный метод тогда, когда нам нужно удалить объект: [cc lang=»delphi»]MyBook.Destroy;[/cc] В этом уроке мы рассмотрели самые базовые основы ООП. В следующих уроках мы продолжим знакомиться с классами и их возможностями. Исходный код проекта, созданного в этом уроке, можно скачать здесь.
Объекты в Delphi. Создание объектов Обучающий материал
Возникновение объектно-ориентированного программирования стало очень важным шагом в развитии современных технологий. Это связано с тем, что до появления объектно-ориентированного программирования код был “плоским”, а теперь программисты могут оперировать не только функциями или процедурами, но и объектами.
Объекты представляют собой совокупность различных методов, свойств и событий. Под термином совокупность в данном определении подразумевается тот факт, что объекты как-бы состоят из перечисленных выше элементов, которые обеспечивают его полноценную работу.
Для примера можно рассмотреть кнопку, которая имеет:
1. Свойства, включающие в себя надписи на кнопке, цвет, размер шрифта и так далее. 2. События (например, нажатие). 3. Методы (прорисовку фокуса, способ вывода текста и так далее).
Если все перечисленные выше пункты объединить воедино, то в результате получится один полнофункциональный автономный объект Delphi. Причем, данный объект будет корректно отрабатывать в самых разных условиях.
Программисту нужно будет просто установить кнопку в определенной форме, и она готова к использованию. Таким образом, объекты в Delphi существенно облегчают жизнь специалистам.
Объекты в Delphi, как и классы, объявляются в разделе var. Например,
Стоит отметить тот факт, что объекты в Delphi имеют динамическую структуру. Переменная, обозначающая объект, включает в себя не данные, а только лишь ссылку на данные объекта. В связи с этим программисты должны заранее позаботиться о том, чтобы выделить определенный объем памяти для хранения информации.
Создание объектов Delphi
Для выделения необходимой памяти используется специальный метод класса-конструктора. Как правило, ему обычно дают имя Create (создать). С помощью слова constructor, которое применяется вместо привычного procedure при описании класса, подчеркивается особое значение и поведение конструктора.
Помимо того, что с помощью конструктора происходит выделение памяти, он еще позволяет решить задачу присвоения полям объекта первоначальных значений. Иначе говоря, с его помощью выполняется создание объектов.
Следует отметить тот факт, что если какой-то объект больше использоваться не будет, то стоит освободить память, отведенную для хранения полей. Данное действие выполняется с помощью метода-деструктора Free. Этот метод является очень важным, если говорить про создание объектов в Delphi.
Например, для освобождения памяти, которую занимают поля объекта professor, следует задать следующую команду:
Итак, создание объектов происходит до передачи управления телу конструктора. На начальном этапе под объект отводится определенное количество памяти, а все его значения обновляются. После этого, идет отработка кода конструктора, который пишется программистами.
На первый взгляд может показаться, что по синтаксису конструктор напоминает процедуры, но это не так. На самом деле конструктор представляет собой функцию, которая возвращает созданный и инициализированный объект.
Классы и объекты Добрый день всем.Хотел узнать кое что,надеюсь вопрос будет соответствовать название темы:) На.
Классы и объекты Создать класс Date для работы с датами в формате «год.месяц.день». Дата представляется структурой с.
Классы и объекты Не могу разобраться с классами для курсовой. Нужно сделать мобов. Каждый должен иметь timer и.
Объекты и классы Всем привет! Может кто-то нормальным русским языком объяснить, что такое классы и объекты, как.
Может вам это поможет.
Тема 2.2.41. Классы и объекты
1. Основные понятия 2. Составляющие класса 3. Объявление класса
1. Основные понятия
Классами в Object Pascal называются специальные типы, которые содержат поля, методы и свойства. Как и любой другой тип, класс служит лишь образцом для создания конкретных экземпляров реализации, которые называются объектами. Понятие класса разработчиками Object Pascal было заимствованно из языка Си++. Всякий экземпляр класса называется объектом. По структуре и способу доступа класс в некоторой степени напоминает запись. Важным отличием классов от других типов является то, что объекты класса всегда распределяются в куче, поэтому объект-переменная фактически представляет собой лишь указатель на динамическую область памяти. Однако в отличие от других указателей при ссылке на содержимое объекта запрещается использовать символ «^» за именем объекта: Пример описания:
Таким образом, по умолчанию непосредственным родилем любого пользовательского класса считается класс TObject. Принцип наследования приводит к созданию ветвящегося дерева классов, постепенно разрастающегося при перемещении от TObject к его потомкам. Каждый потомок дополняет возможности своего родителя новыми и передает их своим потомкам. Полиморфизм – это свойство классов решать схожие по смыслу проблемы разными способами. В рамках Object Pascal поведенческие свойства класса определяются набором входящих в него методов. Изменяя алгоритм того или иного метода в потомках класса, программист может придавать этим потомкам отсутствующие у родителя специфические свойства. Для изменения метода необходимо перекрыть его в потомке, т. е. объявить в потомке одноименный метод и реализовать в нем нужные действия. В результате в объекте-родителе и объекте-потомке будут действовать два одноименных метода, имеющие разную алгоритмическую основу и, следовательно, придающие объектам разные свойства. Это и называется полиморфизмом объектов. В Object Pascal полиморфизм достигается не только описанным выше механизмом наследования и перекрытия методов родителя, но и их виртуализацией, позволяющей родительским методам обращаться к методам своих потомков.
2. Составляющие класса
Как уже было сказано выше, составляющими класса являются его поля, методы и свойства. Полями называются инкапсулированные в классе данные. Поля могут быть любого типа, в том числе в свою очередь классами:
В контексте программы свойство ведет себя как обычное поле. Разница между полем и свойством заключается в том, что при обращении к свойству автоматически подключается соответствующий метод: при передачи свойству нового значения – метод, описанный после write; если же свойство передает свое значение – метод read. Если нет необходимости в специальных действиях при чтении или записи свойства, вместо имени соответствующего метода можно указывать имя поля.Если необходимо, чтобы поле было доступно только для чтения или только для записи, следует опустить соответственно часть write или read. Вообще говоря, свойство может и не связываться с полем. Фактически оно описывает один или два метода, кото рые осуществляют некоторые действия над данными того же типа, что и свойство.
3. Объявление класса
Любой вновь создаваемый класс может содержать секции (разделы), определяемые зарезервированными словами published (декларированные), private (личные), protected (защищенные), public (доступные) и automated (автоматизированные). Внутри каждой секции вначале определяются поля, а затем – методы и свойства. Секции определяют области видимости элементов описания класса. Секция public не накладывает ограничений на область видимости перечисляемых в ней полей, методов и свойств – их можно вызывать в любом другом модуле программы. Секция published также не ограничивает область видимости, однако в ней перечисля ются свойства, которые должны быть доступны не только на этапе исполнения, но и на этапе конструирования программы (т. е. в окне Инспектора Объектов). Секция published используется только при разработке нестандартных компонентов. Среда Delphi помещает описания компонентов, вставленных в форму, в специальную секцию без названия, которая располагается сразу за заголовком класса и продолжается до первой объявленной секции. Эта секция – published. В нее не следует помещать собственные элементы описания класса или удалять из нее элементы, вставленные средой. Секция private сужает область видимости до минимума: личные элементы описания доступны только внутри методов данного класса и подпрограммах, находящихся в том же модуле, где описан класс. Элемент, объявленный в секции private, становится недоступным даже ближайшим потомкам класса, если они размещаются в других модулях. Секция protected доступна только методам самого класса, а также любым его потомкам независимо от того, находятся ли они в том же модуле или нет. Наконец, секция automated используется только для объявления свойств и методов, которые будут добавлены к так называемому интерфейсу OLE-объектов Автоматизации; область видимости членов этой секции не ограничена. В Object Pascal разрешается сколько угодно раз объявлять любую секцию, причем порядок следования секций не имеет значения. Любая секция может быть пустой. Класс может объявляться только в интерфейсной области модуля или в самом начале области реализации. Нельзя определять классы в разделе описаний подпрограмм.
В части 1 говорилось о механизме наследования. Рассмотрим его действие на примере. Будем создавать иерархию классов, начиная от базового класса TObject.
Посмотрим на методы базового класса TObject и дадим комментарии к некоторым из них.
Во первых, это методы, которые даже сгруппированы в отдельный класс TClass.
Далее дан полный перечень методов класса TObject.
Если посмотреть внимательно, то можно увидеть, что методы класса TClass являются составной частью класса TObject, но помечены директивой «class»:
Просмотрев содержание класса TObject, можно выделить четыре группы записей.
1) конструктор «constructor Create» и деструктор «destructor Destroy».
2) Функции и процедуры, помеченные директивой «virtual» (а также директивой «dinamic»; в классе TObject она отсутствует).
3) Функции и процедуры, которым предшествует ключевое слово class.
4) Функции и процедуры, не помеченные директивами «dinamic», «virtual» и class.
Функции и процедуры, не помеченные директивами «dinamic» и «virtual», называются статическими.
Под статические процедуры и функции распределение памяти происходит при компиляции программы. То есть, использовать такие функции и процедуры можно, не создавая экземпляр объекта данного класса в динамической памяти.
Рассмотрим пример. Создадим новый класс на основе класса TObject.
Type
ii:integer; //ввели новое поле, которого нет в TObject.
Объявим переменную класса TMyClass и посмотрим, какие методы оказываются доступны без создания экземпляра объекта.
Мы видим, что можно напрямую обратиться к функциям и процедурам, имеющим директиву «class» (о директиве «class» смотри выше).
Замечание.
Компилятор не отводит память под поле ii, хотя наличие поля отображается в составе класса. Память под поля объекта будет распределена при создании экземпляра объекта.
Действительно, экземпляров данного класса может быть создано несколько, и у каждого может быть собственное значение поля.
Проиллюстрируем доступ к статическим методам без создания экземпляра объекта.
При обращении к методу «ClassName» объект «x» ещё не создан. В этом случае обращение к методу класса через переменную возвращает тип того объекта, из которого вызван метод. Метод вызван из обработчика Button4Click, поэтому возвращается значение Tbutton.
Второй обработчик — обработчик клика по Edit1.
procedure TForm1.Edit1Click(Sender: TObject);
var x:TObject;
form1.Edit3.Text:=x.ClassName;
Метод вызван из обработчика Edit1Click, поэтому возвращается значение «Tedit».
Обращение к функции ClassName через класс TMyClassCвозвращает имя класса «TMyClassC».
Delphi конструктор класса
Однако надо помнить, что главной статической процедурой является конструктор Create.
Сама процедура Create ничего не делает (тело процедуры пустое), но служит основой для переопределения в потомках. Однако её вызов автоматически влечёт за собой вызов функции «_ClassCreate()». Внутри неё осуществляются ассемблеровские операции по распределению памяти под объект и вызов функции InitInstance.
В результате создаётся экземпляр объекта и возвращается указатель на него.
После создания объекта открывается доступ к его полям и нестатическим методам. Все поля инициируются нулевыми или пустыми значениями.
Если поле является ссылкой на объект, то ему присваивается значение nil.
Таким образом, основное предназначение статических методов TObject — создание экземпляра объекта.
Непосредственно к методам TObject как правило, не обращаются.
Экземпляр класса
var x:TObject;
и вызывая конструктор
мы создаём экземпляр объекта и получаем доступ к его полям (либо напрямую, либо через свойства; о свойствах объекта речь пойдёт далее). Также мы получаем доступ не только к статическим, но также к динамическим и виртуальным методам.
Также мы получаем возможность наполнить содержанием методы, помеченные директивой «abstract»
После создания экземпляра объекта нам становится доступен весь список методов, полей и свойств экземпляра. В данном случае это методы объекта класса Tobject (полей у этого класса просто нет):