Основы программирования — второй семестр 08-09; Михалкович С.С.; VIII часть — различия между версиями
Juliet (обсуждение | вклад) (→Позднее связывание и виртуальные методы) |
Juliet (обсуждение | вклад) (→Полиморфизм и виртуальные методы) |
||
Строка 1: | Строка 1: | ||
== Полиморфизм и виртуальные методы == | == Полиморфизм и виртуальные методы == | ||
=== Вводные понятия === | === Вводные понятия === | ||
− | '''Инкапсуляция''' — хранение в классе одновременно данных и методов (класс представляет собой «капсулу»). <br /> | + | :'''Инкапсуляция''' — хранение в классе одновременно данных и методов (класс представляет собой «капсулу»). <br />Инкапсуляция тесно связана с защитой данных: лишь некоторые члены в этой «капсуле» являются открытыми. |
− | Инкапсуляция тесно связана с защитой данных: лишь некоторые члены в этой «капсуле» являются открытыми. | ||
− | '''Полиморфизм''' — это, дословно, многообразие форм. <br /> | + | :'''Полиморфизм''' — это, дословно, многообразие форм. <br />Более точно, '''полиморфизм''' — это способность родственных классов выполнять одинаковые действия сходным образом. |
− | Более точно, '''полиморфизм''' — это способность родственных классов выполнять одинаковые действия сходным образом. | ||
''<u>Пример</u>.'' <br /> | ''<u>Пример</u>.'' <br /> | ||
Строка 28: | Строка 26: | ||
<u>Вопрос</u>: какой метод <tt>Print</tt> вызовется? <br /> | <u>Вопрос</u>: какой метод <tt>Print</tt> вызовется? <br /> | ||
<u>Ответ</u>: В разных языках программирования вызовутся <tt>Print</tt> разных классов: | <u>Ответ</u>: В разных языках программирования вызовутся <tt>Print</tt> разных классов: | ||
− | + | * в таких языках, как ''Java'', ''Eiffel'' — <tt>'''Student'''.Print</tt> | |
+ | * а в ''C++'', ''C#'', ''PasacalABC.NET'' — <tt>'''Person'''.Print</tt> | ||
Т.о. в ''PascalABC.NET'' вызовется метод <tt>Person.Print</tt>, но, хотелось бы, чтобы вызывался метод <tt>Student.Print</tt>. | Т.о. в ''PascalABC.NET'' вызовется метод <tt>Person.Print</tt>, но, хотелось бы, чтобы вызывался метод <tt>Student.Print</tt>. | ||
− | Если решение о том, какой метод вызывать, принимается на этапе ''компиляции'' (<u>рано</u>), то связывание имени метода с конкретным кодом называется '''ранним связыванием'''. | + | : Если решение о том, какой метод вызывать, принимается на этапе ''компиляции'' (<u>рано</u>), то связывание имени метода с конкретным кодом называется '''ранним связыванием'''. |
− | Если же решение о том, какой метод вызывать, принимается на этапе ''выполнения программы'' (<u>поздно</u>), то связывание имени метода с конкретным кодом называется '''поздним связыванием'''. <br /> | + | : Если же решение о том, какой метод вызывать, принимается на этапе ''выполнения программы'' (<u>поздно</u>), то связывание имени метода с конкретным кодом называется '''поздним связыванием'''. <br />Позднее связывание осущесвляется с методом того класса, на который ссылается переменная в процессе выполнения программы. |
− | Позднее связывание осущесвляется с методом того класса, на который ссылается переменная в процессе выполнения программы. | ||
Итак, в ''PascalABC.NET'' по умолчанию реализовано '''''раннее связывание'''''. | Итак, в ''PascalABC.NET'' по умолчанию реализовано '''''раннее связывание'''''. | ||
Строка 83: | Строка 81: | ||
'''Полиморфизм''' в объектно-ориентированных программирования реализуется через механизм '''''виртуальных методов'''''. | '''Полиморфизм''' в объектно-ориентированных программирования реализуется через механизм '''''виртуальных методов'''''. | ||
− | Переменная базового класса, содержащая виртуальные методы, называется '''полиморфной переменной'''. <br /> | + | :Переменная базового класса, содержащая виртуальные методы, называется '''полиморфной переменной'''. <br />Она имеет '''''статический''''' тип (заявленный при объявлении) и '''''динамический''''' (тип объекта, на который она ссылается в данный момент выполнения программы). |
− | Она имеет '''''статический''''' тип (заявленный при объявлении) и '''''динамический''''' (тип объекта, на который она ссылается в данный момент выполнения программы). | ||
'''Замечание.''' Обычная подпрограмма также может быть ''полиморфной''. <br /> | '''Замечание.''' Обычная подпрограмма также может быть ''полиморфной''. <br /> | ||
Строка 97: | Строка 94: | ||
</source> | </source> | ||
− | Обычная подпрограмма называется '''полиморфной''', если она содержит хотя бы один полиморфный параметр. | + | :Обычная подпрограмма называется '''полиморфной''', если она содержит хотя бы один полиморфный параметр. |
=== Виртуальные методы как блоки замены кода === | === Виртуальные методы как блоки замены кода === |
Версия 15:26, 21 мая 2009
Содержание
- 1 Полиморфизм и виртуальные методы
- 1.1 Вводные понятия
- 1.2 Позднее связывание и виртуальные методы
- 1.3 Виртуальные методы как блоки замены кода
- 1.4 Класс Object — неявный предок всех классов .NET
- 1.5 Переопределение методов Equals и ToString в классах Person и Student
- 1.6 Цепочка виртуальности и её разрыв
- 1.7 Алгоритм поиска в цепочке виртуальности
Полиморфизм и виртуальные методы
Вводные понятия
- Инкапсуляция — хранение в классе одновременно данных и методов (класс представляет собой «капсулу»).
Инкапсуляция тесно связана с защитой данных: лишь некоторые члены в этой «капсуле» являются открытыми.
- Полиморфизм — это, дословно, многообразие форм.
Более точно, полиморфизм — это способность родственных классов выполнять одинаковые действия сходным образом.
Пример.
Есть класс
Студент Готовиться_к_экзамену()
И два его наследника:
Хороший_студент Готовиться_к_экзамену()
и
Плохой студент Готовиться_к_экзамену()
Действие Готовиться_к_экзамену() они выполняют по-разному.
Рассмотрим следующий код:
var p: Person;
p := new Student('Иванов', 17, 1, 11);
p.Print();
Вопрос: какой метод Print вызовется?
Ответ: В разных языках программирования вызовутся Print разных классов:
- в таких языках, как Java, Eiffel — Student.Print
- а в C++, C#, PasacalABC.NET — Person.Print
Т.о. в PascalABC.NET вызовется метод Person.Print, но, хотелось бы, чтобы вызывался метод Student.Print.
- Если решение о том, какой метод вызывать, принимается на этапе компиляции (рано), то связывание имени метода с конкретным кодом называется ранним связыванием.
- Если же решение о том, какой метод вызывать, принимается на этапе выполнения программы (поздно), то связывание имени метода с конкретным кодом называется поздним связыванием.
Позднее связывание осущесвляется с методом того класса, на который ссылается переменная в процессе выполнения программы.
Итак, в PascalABC.NET по умолчанию реализовано раннее связывание.
Позднее связывание и виртуальные методы
Чтобы обеспечить позднее связывание в языке Pascal, соответствующие методы надо сделать виртуальными в базовом классе.
type
Person = class
...
public
...
procedure Print; virtual;
begin
WriteFormat('Имя: {0} Возраст: {1} ',
fName, fAge);
end;
end;
Student = class(Person)
...
public
procedure Print; override;
begin
inherited Print;
WriteFormat('Курс: {0} Группа: {1} ',
fCourse, fGroup);
end;
end;
При переопределении виртуального метода в классе-потомке используется ключевое слово override.
Примечание. Переопределяющий виртуальный метод должен иметь те же параметры и тот же тип возвращаемого значения.
Вернемся к рассмотренному ранее коду:
var p: Person;
p := new Student('Иванов', 17, 1, 11);
p.Print();
Теперь решение о том, какой метод вызывать, будет отложено до этапа выполнения, и будет вызвано Print того класса, на объект которого ссылается переменная в текущий момент (в данном случае — для Student).
Вызов виртуального метода осуществляется немного медленнее обычного метода.
Полиморфизм в объектно-ориентированных программирования реализуется через механизм виртуальных методов.
- Переменная базового класса, содержащая виртуальные методы, называется полиморфной переменной.
Она имеет статический тип (заявленный при объявлении) и динамический (тип объекта, на который она ссылается в данный момент выполнения программы).
Замечание. Обычная подпрограмма также может быть полиморфной.
Пример.
procedure Print(p: Person);
begin
p.Print(); // обращение полиморфизма
end;
...
Print(new Student(...));
- Обычная подпрограмма называется полиморфной, если она содержит хотя бы один полиморфный параметр.