ТОП 10:

Использование разделов класса public, protected, published.



Каждый компонент класса имеет один из атрибутов, определяющих его область видимости (visibility of class members). Это одно из зарезервированных слов private, protected, public,published или automated. Видимость определяет, где и как компонент класса может быть доступен. Атрибут личный (private) определяет наименьшую видимость, защищенный (protected) – среднюю, а общедоступный (public), опубликованный (published) и автоматизированный (automated) – наибольшую.

Если никакой из атрибутов не указан, то по умолчанию предполагается published, если класс компилируется с директивой {$M+};в противном случае такие компоненты имеют атрибут public. Для большей читабельности рекомендуется группировать компоненты, имеющие одинаковую видимость, располагая их в таком порядке: private, protected,public, published и automated. Описание класса тогда имеет следующий вид:

type

TMyClass = class(TControl)

private

{ private declarations here}

protected

{ protected declarations here }

public

{ public declarations here }

published

{ published declarations here }

end;

Можно увеличить видимость компонента (только свойства property) в классе наследнике путем его повторного объявления (с другим атрибутом), однако понизить видимость нельзя. Например, компонент protected может быть сделан общедоступным (public) в наследнике, однако сделать его private невозможно. Более того, компоненты published не могут стать public в классе наследнике.

Компоненты private, protected и public.

Компоненты privateневидимы вне того модуля или программы, где они описаны. Другими словами, метод private не может быть вызван из другого модуля, а поле или свойствоprivate не могут быть прочитаны или изменены из другого модуля. Таким образом, доступ к этим компонентам из другого класса можно получить, если поместить описание этого класса в том же модуле. При таком описании на компонент надо ссылаться, естественно, с помощью указания имени экземпляра класса.

Компоненты protectedвидимы везде в том модуле, где объявлен класс, и в любом классе наследнике независимо от того, в каком модуле описан класс наследник. Этот атрибут присваивают тем компонентам, которые хотят сделать доступными только в классах потомках.

Компоненты published.

Видимость этих компонентов такая же, как и компонентов public. Разница состоит в том, что для опубликованных компонент генерируется информация времени выполнения (runtime type information RTTI). Эта информация позволяет приложению запрашивать поля и свойства объекта какого-либо неизвестного класса динамически. Delphi использует RTTI для доступа к значениям свойств при сохранении и загрузке файлов форм (.DFM), для вывода свойств инспектором объектов и для установки связи (соответствия) между обработчиками событий (event handlers) и специфическими свойствами, называемыми событиями (event).

Допустимыми типами опубликованных свойств являются:

· порядковые;

· строковые;

· классы;

· интерфейсы;

· указатели на методы;

· множество с числом элементов до 32 (порядковые значения 0-31);

· любой вещественный тип, кроме Real48.

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

Класс может иметь опубликованные компоненты, если он компилируется с директивой{$M+}или является производным от класса, который откомпилирован с этой директивой. Абсолютное большинство классов являются производными от класса TPersistent, который откомпилирован с директивой {$M+},в связи с чем эту директиву редко приходится использовать.

При добавлении компонентов на форму Delphi помещает их в секцию published (этот атрибут видимости применяется по умолчанию).

Поля могут быть опубликованными, только если они имеют тип класс или интерфейс. Следующий пример иллюстрирует этот факт:

type

TMyClass = class

end;

TForm1 = class(TForm)

published

Num : integer; {Вызываетошибкукомпиляции: Published field ‘Num’ not a class
nor interface type. Поле такого типа надо описывать в другой секции
}

MyClass : TMyClass;

Label1: TLabel;

Button1: TButton;

private

{ Private declarations }

public

{ Publicdeclarations }

end;

К вопросу о перекрытии описаний в производных классах.

Если в некотором модуле описать, например, объект типа TControl, то защищенные компоненты этого объекта будут недоступны, что естественно. Если теперь описать в этом же модуле класс, производный от TControl, то эти (защищенные) компоненты станут доступны, например:

TMyControl = class (TControl)

end;

Отметим, что доступными становятся все компоненты: поля, методы и свойства.

Почему так получается? Очевидно, потому, что в том модуле, где класс описан, все его собственные компоненты и унаследованные (в том числе и private) являются доступными. Если же описание класса TMyControl и объекта этого класса находятся в разных модулях, то спецификаторы доступа начинают работать так, как им и положено. В этом случае расширить область видимости компонент-свойств можно только за счет их повторного описания как общедоступных, например:

TMyControl = class (TControl)

public

property Font;

end;

Компоненты автоматизации (automated members).

Видимость этих компонент такая же, как и общедоступных. Отличие состоит в том, что для автоматических компонент генерируется информация типа автоматизации (Automation type information), которая требуется для серверов автоматизации. Компоненты автоматизации появляются обычно только в классах, производных от класса TAutoObject, объявленного в модуле OleAuto. Этот класс, как и само слово automated,предназначены только для обратной совместимости. Класс TAutoObject модуля ComObj не использует слово automated. На компоненты автоматизации накладывается целый ряд ограничений, на которых мы здесь останавливаться не будем.

Опережающие описания и взаимно-зависимые классы (Forward declarations and mutually dependent classes).

Если описание класса заканчивается словом class и символом ";" (точка с запятой), т.е. оно имеет форму

type className= class;

без указания родительского класса или списка компонентов, то это и есть опережающее описание класса.

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

Опережающее описание позволяет описать взаимно-зависимые классы, Приведем пример:

type

TFigure = class; // Опережающее описание

TDrawing = class

Figure: TFigure;

//F i e l d s

end;

TFigure = class // Определяющее описание

Drawing: TDrawing;

end;

Не путайте опережающее описание класса с определяющим описанием класса, который является производным классом от TObject, но для которого не указан родительский класс или указан класс TObject:

type

TFirstClass = class; // Опережающее описание

TSecondClass = class // Определяющее описание

end; //

TThirdClass = class(TObject); // Определяющее описание

Использование наследования при создании класса.

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

Другими словами, класс-наследник реализует спецификацию уже существующего класса (базовый класс). Это позволяет обращаться с объектами класса-наследника точно так же, как с объектами базового класса.

Простое наследование

Класс, от которого произошло наследование, называется базовым или родительским (англ. base class). Классы, которые произошли от базового, называются потомками,наследниками или производными классами (англ. derived class).

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

Множественное наследование

Основная статья: Множественное наследование

При множественном наследовании у класса может быть более одного предка. В этом случае класс наследует методы всех предков. Достоинства такого подхода в большей гибкости. Множественное наследование реализовано в C++. Из других языков, предоставляющих эту возможность, можно отметить Python и Эйфель. Множественное наследование поддерживается в языке UML.

Множественное наследование — потенциальный источник ошибок, которые могут возникнуть из-за наличия одинаковых имен методов в предках. В языках, которые позиционируются как наследники C++ (Java, C# и др.), от множественного наследования было решено отказаться в пользу интерфейсов. Практически всегда можно обойтись без использования данного механизма. Однако, если такая необходимость все-таки возникла, то, для разрешения конфликтов использования наследованных методов с одинаковыми именами, возможно, например, применить операцию расширения видимости — «::» — для вызова конкретного метода конкретного родителя.

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

Большинство современных объектно-ориентированных языков программирования (C#, Java, Delphi и др.) поддерживают возможность одновременно наследоваться от класса-предка и реализовать методы нескольких интерфейсов одним и тем же классом. Этот механизм позволяет во многом заменить множественное наследование — методы интерфейсов необходимо переопределять явно, что исключает ошибки при наследовании функциональности одинаковых методов различных классов-предков.

 

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).

 

 

Определение инкапсуляции.

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

§ Пользователь может взаимодействовать с объектом только через этот интерфейс. Реализуется с помощью ключевого слова: public.

§ Пользователь не может использовать закрытые данные и методы. Реализуется с помощью ключевых слов: private, protected, internal.

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

Сокрытие реализации целесообразно применять в следующих случаях:

§ предельная локализация изменений при необходимости таких изменений,

§ прогнозируемость изменений (какие изменения в коде надо сделать для заданного изменения функциональности) и прогнозируемость последствий изменений.

 

Delphi

В Delphi для создания скрытых полей или методов их достаточно объявить в секции private.

TMyClass = class private FMyField: Integer; procedure SetMyField(const Value: Integer); function GetMyField: Integer; protected public property MyField: Integer read GetMyField write SetMyField; end;

Для создания интерфейса доступа к скрытым полям в Delphi введены свойства.

 

Определение полиморфизма.

Полиморфи́зм (в языках программирования) — возможность объектов с одинаковой спецификацией иметь различную реализацию.

Язык программирования поддерживает полиморфизм, если классы с одинаковой спецификацией могут иметь различную реализацию — например, реализация класса может быть изменена в процессе наследования[1].

Кратко смысл полиморфизма можно выразить фразой: «Один интерфейс, множество реализаций».

Полиморфизм — один из четырёх важнейших механизмов объектно-ориентированного программирования (наряду с абстракцией, инкапсуляцией и наследованием).

Полиморфизм позволяет писать более абстрактные программы и повысить коэффициент повторного использования кода. Общие свойства объектов объединяются в систему, которую могут называть по-разному — интерфейс, класс. Общность имеет внешнее и внутреннее выражение:

§ внешняя общность проявляется как одинаковый набор методов с одинаковыми именами и сигнатурами (именем методов и типами аргументов и их количеством);

§ внутренняя общность — одинаковая функциональность методов. Её можно описать интуитивно или выразить в виде строгих законов, правил, которым должны подчиняться методы. Возможность приписывать разную функциональность одному методу (функции, операции) называется перегрузкой метода (перегрузкой функций, перегрузкой операций).

Примеры

Класс геометрических фигур (эллипс, многоугольник) может иметь методы для геометрических трансформаций (смещение, поворот, масштабирование).

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







Последнее изменение этой страницы: 2016-04-08; Нарушение авторского права страницы

infopedia.su Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав. Обратная связь - 3.233.221.149 (0.017 с.)