Студопедия

Главная страница Случайная страница

КАТЕГОРИИ:

АвтомобилиАстрономияБиологияГеографияДом и садДругие языкиДругоеИнформатикаИсторияКультураЛитератураЛогикаМатематикаМедицинаМеталлургияМеханикаОбразованиеОхрана трудаПедагогикаПолитикаПравоПсихологияРелигияРиторикаСоциологияСпортСтроительствоТехнологияТуризмФизикаФилософияФинансыХимияЧерчениеЭкологияЭкономикаЭлектроника






Перекрытие методов






Рассмотрим класс для описания животных, способных издавать звуки:

type TPet = class

procedure Speak;

end;

 

procedure TPet.Speak;

begin

Beep; // ничего особенного – просто звуковой сигнал

end;

Потомки TPet – классы TDog и TCat – тоже способны «издавать звуки», но делают это по-своему. Ситуация является достаточно типичной при проектировании иерархии классов: наследник имеет такие же методы как и предок, но реализует их своим способом. ООП даёт возможность описать в классе-потомке метод с тем же именем, что и в классе-предке, но с собственной реализацией. Это называется перекрытие (замещение) методов:

type TDog = class(TPet)

procedure Speak; // перекрытие метода TPet.Speak

end;

 

TCat = class(TPet)

procedure Speak; // перекрытие метода TPet.Speak

end;

 

procedure TDog.Speak;

begin

writeln('Bow-wow')

end;

 

procedure TCat.Speak;

begin

writeln('Mew')

end;

При перекрытии методов их сигнатуры (то есть количество и тип параметров) могут различаться.

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

type TCatWithVolume = class(TCat)

// не перекрыли TCat.Speak, а добавили метод с параметром

procedure Speak(Volume: Integer); overload;

end;

Разберём вопрос о перекрытии полей класса. Классическое ООП не допускает подобного. Однако в Object Pascal дочерний класс может объявить поле с тем же именем, что и поле в родительском классе, но с другим типом. В этом случае методы в дочернем классе будут работать с новым полем, методы в родительском классе – со старым. На практике такая возможность практически не используется, так как способна основательно запутать и проектировщика, и пользователей класса.

Достаточно часто метод класса-потомка не заменяет действия в методе класса-предка, а дополняет их. Чтобы не дублировать код, в методе класса-потомка можно вызвать метод класса-предка. Для вызова перекрытых методов ближайшего класса-предка применяется конструкция inherited имя-метода-класса–предка. Если имя и параметры вызываемого у предка метода совпадают с именем и параметрами вызывающего метода, достаточно записать только ключевое слово inherited:

procedure TCat.Speak;

begin

inherited; // вызов TPet.Speak – звуковой сигнал

writeln('Mew')

end;

Если в непосредственном предке метод, вызываемый через inherited, отсутствует, компилятор проводит поиск такого метода по иерархии классов вплоть до корневого класса. Если метод не найден, никаких действий не предпринимается.

В иерархии классов работа конструктора класса-потомка, как правило, начинается с вызова конструктора класса-предка для корректной инициализации полей предка. Добавим конструктор в класс TEmployee (используется вариант класса TPerson с простым конструктором):

type TEmployee = class(TPerson)

public

...

constructor Create;

end;

 

constructor TEmployee.Create;

begin

inherited; // можно написать inherited Create

// fAge: = 1, fName: = 'Person'

fName: = 'Employee'

end;

Для деструкторов в иерархии классов действует правило, согласно которому вызов унаследованного деструктора происходит в конце работы класса-потомка.


Поделиться с друзьями:

mylektsii.su - Мои Лекции - 2015-2024 год. (0.008 сек.)Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав Пожаловаться на материал