Программирование / Делфа длАТПП-01 / Билет2
.docВОПР 2
Наследование
Любой класс жожет быть порожден от другого класса. Для этого при его объявлении указывается имя класса-родителя:
TChildClass = class(TParentClass)
Порожденный класс автоматически наследует поля, методы и свойства своего родителя и_может добавлять их новыми. Таким образом, принцип наследования обеспечивает поэтапное создание сложных классов и разработку собственных библиотек классов. Все классы Object Pascal порождены от единственного родителя - класса TObject. Этот класс не имеет полей и свойств, но включает в себя методы самого общего.назначения, обеспечивающие весь жизненный цикл любых объектов - от их создания до уничтожения. Программист не может создать класс, который не был бы дочерним классом TObject. Следующие два объявления идентичны:
TaClass = class (TObject) TaClass = class
Принцип наследования приводит к созданию ветвящегося дерева классов, постепенно разрастающегося при перемещении от TObject к его потомкам. Каждый потомок дополняет возможности своего родителя новыми и передает их своим потомкам.
Методы и их наследование, полиморфизм
При описании нового класса можно добавлять новые методы и свойства, оставляя методы и свойства родителей, а можно родительские методы и свойства переопределить или перегрузить.
Имеется четыре вида методов: статические, виртуальные, динамические и абстрактные.
По умолчанию все методы статические. Если в классе — наследнике переопределить такой метод (ввести новый метод с тем же именем), то для объектов этого класса новый метод отменит родительский. Если обращаться к объекту этого класса, то вызываться будет новый метод. Но если обратиться к объекту как к объекту родительского класса, то вызываться будет метод родителя.
Виртуальные и динамические методы не связаны с другими методами с тем же именем в классах — наследниках. Если в классах — наследниках эти методы перегружены, то при обращении к такому методу во время выполнения будет вызываться тот из методов с одинаковыми именами, который соответствует классу объекта, указанному при вызове. Например, если имеется базовый класс графических объектов TShape и ряд наследующих ему классов различных геометрических фигур, и если в каждом из этих классов определен свой виртуальный метод Draw, рисующий эту фигуру, то можно написать в программе:
var ShapeArray: array[1..10] of TShape;
for i:=l to 10 do ShapeArray[i].Draw;
В этом коде в массив ShapeArray могут помещаться объекты разных классов, наследующих TShape. В цикле for обращение к объектам производится как к объектам базового для них типа TShape. В этом случае для каждого объекта будет вызываться виртуальный метод Draw именно этого объекта. Такой подход, облегчающий работу с множеством родственных объектов, называется полиморфизмом.
При объявлении в классе виртуальных и динамических методов после точки с запятой, завершающей объявление метода, добавляются ключевые слова virtual или dynamic. Например:
type
TShape = class
procedure Draw; virtual;
end;
Чтобы перегрузить в классе — наследнике виртуальный метод, надо после его объявления поставит ключевое слово override. Например:
type
TRectangle = class(TShape)
procedure Draw; override;
end;
TEllipse = class (TShape)
procedure Draw; override; end;
Если в каком-то базовом классе метод был объявлен как виртуальный, то он остается виртуальным во всех классах — наследниках (в частности, и в наследниках классов наследников). Однако, обычно для облегчения понимания кодов перегруженные методы принято повторно объявлять виртуальными, чтобы была ясна их суть для тех, кто будет строить наследников данного класса. Например:
TEllipse = class (TShape)
procedure Draw; override; virtual;
end;
Описанным способом могут быть перегружены только виртуальные и динамические методы. Различие между динамическими и виртуальными методами невелико и относится к внутреннему механизму реализации их вызовов. Виртуальные методы эффективнее с точки зрения временных затрат, а динамические — с точки зрения затрат памяти. В целом виртуальные методы обеспечивают более эффективный механизм полиморфизма, а динамические более выгодны, если в базовом классе определено много перегружаемых методов и они одновременно используются многими объектами классов — наследников.
Абстрактный метод — это виртуальный или динамический метод, реализация которого не определена в том классе, в котором он объявлен. Предполагается, что этот метод будет перегружен в классах — наследниках. Только в тех классах, в которых он перегружен, его и можно вызывать.
Объявляется абстрактный метод с помощью ключевого слова abstract после слова virtual или dynamic. Например:
procedure DoSomething; virtual; abstract;
При реализации метода, переопределенного любым способом в классе — наследнике, можно вызывать метод класса — родителя. Для этого перед именем метода при его вызове записывается ключевое слово inherited. Например, оператор
inherited Create (...);
вызывает метод Create родителя.
Если записать слово inherited и после него не писать имя вызываемого метода, то будет вызываться наследуемый метод, совпадающий по имени с именем того метода, из которого он вызывается. Например, если в переопределяемом конструкторе встречается оператор
inherited; то будет вызван конструктор родительского класса.