Архитектура Аудит Военная наука Иностранные языки Медицина Металлургия Метрология Образование Политология Производство Психология Стандартизация Технологии |
Ссылочная модель объектов Delphi
В языке Object Pascal реализована ссылочная модель объектов. Это значит, что переменная типа класс хранит в действительности указатель на объект. Однако, при обращении к полям, методам или свойствам объекта разыменование такого указателя не требуется; указывается имя объекта и затем, после разделителя-точки, указывается имя поля, метода или свойства: var p: Person: = new Person('Иванов', 20); Как и другие указатели, переменная типа класс может хранить значение nil: p: = nil; Несколько переменных типа класс могут ссылаться на один объект и совместно модифицировать его: var p1, p2: Person; Локальные определения классов (т.е. определения в процедурах и функциях) запрещены.
Наследование Насле́ дование — механизм объектно-ориентированного программирования (наряду с инкапсуляцией, полиморфизмом и абстракцией), позволяющий описать новыйкласс на основе уже существующего (родительского), при этом свойства и функциональность родительского класса заимствуются новым классом. Другими словами, класс-наследник реализует спецификацию уже существующего класса (базовый класс). Это позволяет обращаться с объектами класса-наследника точно так же, как с объектами базового класса. Типы наследования [править]Простое наследование Класс, от которого произошло наследование, называется базовым или родительским (англ. base class). Классы, которые произошли от базового, называютсяпотомками, наследниками или производными классами (англ. derived class). В некоторых языках используются абстрактные классы. Абстрактный класс — это класс, содержащий хотя бы один абстрактный метод, он описан в программе, имеетполя, методы и не может использоваться для непосредственного создания объекта. То есть от абстрактного класса можно только наследовать. Объекты создаются только на основе производных классов, наследованных от абстрактного. Например, абстрактным классом может быть базовый класс «сотрудник вуза», от которого наследуются классы «аспирант», «профессор» и т. д. Так как производные классы имеют общие поля и функции (например, поле «год рождения»), то эти члены класса могут быть описаны в базовом классе. В программе создаются объекты на основе классов «аспирант», «профессор», но нет смысла создавать объект на основе класса «сотрудник вуза». [править]Множественное наследование Основная статья: Множественное наследование При множественном наследовании у класса может быть более одного предка. В этом случае класс наследует методы всех предков. Достоинства такого подхода в большей гибкости. Множественное наследование реализовано в C++. Из других языков, предоставляющих эту возможность, можно отметить Python и Эйфель. Множественное наследование поддерживается в языке UML. Множественное наследование — потенциальный источник ошибок, которые могут возникнуть из-за наличия одинаковых имен методов в предках. В языках, которые позиционируются как наследники C++ (Java, C# и др.), от множественного наследования было решено отказаться в пользу интерфейсов. Практически всегда можно обойтись без использования данного механизма. Однако, если такая необходимость все-таки возникла, то, для разрешения конфликтов использования наследованных методов с одинаковыми именами, возможно, например, применить операцию расширения видимости — «:: » — для вызова конкретного метода конкретного родителя. Попытка решения проблемы наличия одинаковых имен методов в предках была предпринята в языке Эйфель, в котором при описании нового класса необходимо явно указывать импортируемые члены каждого из наследуемых классов и их именование в дочернем классе. Большинство современных объектно-ориентированных языков программирования (C#, Java, Delphi и др.) поддерживают возможность одновременно наследоваться от класса-предка и реализовать методы нескольких интерфейсов одним и тем же классом. Этот механизм позволяет во многом заменить множественное наследование — методы интерфейсов необходимо переопределять явно, что исключает ошибки при наследовании функциональности одинаковых методов различных классов-предков. [править]Единый базовый класс В ряде языков программирования все классы явно или неявно наследуются от некого базового класса. Smalltalk был одним из первых языков, в которых использовалась эта концепция. К таким языкам относятся Objective-C (NSObject), Perl (UNIVERSAL), Eiffel (ANY), Java (java.lang.Object), C# (System.Object), Delphi (TObject). Delphi (Object Pascal) Для использования механизма наследования в Delphi необходимо в объявлении класса справа от слова class указать класс предок: Предок: TAncestor = classprivateprotectedpublic // Виртуальная процедура procedure VirtualProcedure; virtual; abstract; procedure StaticProcedure; end;Наследник: TDescendant = class (TAncestor) privateprotectedpublic // Перекрытие виртуальной процедуры procedure VirtualProcedure; override; procedure StaticProcedure; end;Абсолютно все классы в Delphi являются потомками класса TObject. Если класс-предок не указан, то подразумевается, что новый класс является прямым потомком класса TObject. Множественное наследование в Delphi частично поддерживается за счёт использования классов-помощников (Сlass Helpers). Совместимость типов При выполнении операций над столбцами разного типа InterBase пытается автоматически привести типы таким образом, чтобы значения, участвующие в операции, принадлежали совместимым типам. Кроме того, для явно! о приведения типов можно использовать функцию CAST, которая приводит типы внутри оператора SELECT, обычно в секции WHERE: CAST (< значение> | NULL AS ТипДанных) Совместимыми считаются только типы DATE, CHAR и NUMERIC. Вот как можно привести значение столбца Date_Data (тип DATE) к типу CHAR и сравнить его со значением столбца Char_Data (тип CHAR): SELECT... WHERE CHAR_DATA < = CAST(DATE_DATA AS CHAR); Совместимость типов требуется при конструировании выражений, а также при вызовах подпрограмм (для параметров-значений). Совместимость означает, что для переменных этих типов возможна операция присваивания - хотя во время этой операции присваиваемое значение может измениться: произойдетнеявное приведение типов данных (см. п. " Приведение типов данных" ниже). Два типа Т1 и Т2 будут совместимыми, если верен хотя бы один вариант из перечисленных ниже: § Т1 и Т2 эквивалентны (в том числе совпадают); § Т1 и Т2 - оба целочисленные или оба вещественные; § Т1 и Т2 являются подмножествами одного типа; § Т1 является некоторым подмножеством Т2; § Т1 - строка, а Т2 - символ (см. лекцию 5); § Т1 - это тип pointer, а Т2 - типизированный указатель (см. лекцию 10); § Т1 и Т2 - оба процедурные, с одинаковым количеством попарно эквивалентных параметров, а для функций - с эквивалентными типами результатов (см. лекцию 8).
Полиморфизм и позднее связывание Полиморфизм Этот принцип неразрывно связан с наследованием и гласит, что каждый класс наследник может обладать не только свойствами, унаследованными от предка, но и своими собственными. В частности, свойства предка могут быть перекрыты наследником - на место свойств предка могут быть подставлены свойства наследника. Существование принципа полиморфизма является естественным следствием существования принципа наследования: наследование без изменения набора свойств не имеет смысла. Кроме того, без полиморфизма невозможно реализовать объединение различных объектов (классов) по некоторому набору свойств (невозможно абстрагироваться от части свойств объектов), а без этого теряется весь смысл подхода. Позднее связывание Несмотря на то, что три перечисленных принципа называют " тремя китами ООП", сами по себе они не имеют смысла без наличия особого механизма, названного поздним (динамическим) связыванием. Приведем пример. Допустим, что у нас создана программа, обрабатывающая объекты определенного класса (для определенности возьмем уже упоминавшийся класс " матрица" ). Естественно, что программа разрабатывалась (и тестировалась) с использованием одного представителя данного (кстати говоря абстрактного) класса, а точнее - его класса-наследника " двумерный массив". Естественно, что все обращения к элементам данных производились через соответствующие методы, абстрагирующие представление. Однако, при этом идейно правильном подходе мы не сможем написать программу, которая могла бы обрабатывать другх представителей класса " матрица", если у нас нет ничего, кроме реализации трех принципов ООП. Действительно, в момент компиляции нашей программы, мы жестко определяем, что при вызове метода доступа к элементу объекта класса " матрица" вызывается метод объекта класса-наследника " двумерный массив". Даже если мы разместим по тем же адресам (или передадим в качестве параметров) объекты других классов-наследников (" блочная матрица", например), все равно будет вызываться метод класса " двумерный массив". Что и приведет к краху программы. Следовательно, необходим механизм, который в процессе выполнения программы определял бы принадлежность объекта конкретному классу и производил бы вызов методов, относящихся к данному классу. Этот механизм и получил название механизма позднего связывания. Однако, позднее связывание должно быть применено не ко всем методам, а только к специфическим для каждого класса-наследника. К примеру, вызов метода обращения должен быть одинаков для всех объектов класса " матрица" - алгоритм одинаков для всех матриц. То есть все методы класса по способу вызова делятся на две группы: · те, для которых механизм позднего связывания не применяется; они, насколько известно автору, не получили названия (за исключением " обычные" ); · те, для которых этот механизм применяется; они получили название " виртуальные методы" (среди них еще выделяют " динамическиевиртуальные методы", но они по принципам вызова не отличаются). Популярное:
|
Последнее изменение этой страницы: 2016-07-14; Просмотров: 781; Нарушение авторского права страницы