Переопределение виртуальных функций
Виртуальные функции
Чистый полиморфизм
Тема 2.
Пример 2.
class CA
{
string strA;
public CA()
{
strA = ‘Привет’;
}
public string func ()
{
return strA;
}
}
class CB: CA
{
string strB;
public CB();
{
strB = ‘Hello’;
}
public new string func ()
{
return strB;
}
}
class Class 1
{
static void Main (string[] args)
{
CA pA = new CA();
CB pb = new CB();
Console.WriteLine(pA.func());// Выведетпривет
Console.WriteLine(pB.func()); // ВыведетHello
}
}
При очередной модификации библиотечных классов добавим ф-ю, заголовок которой случайно совпал с заголовком ф-ии в вашем производном от нее классе. В этом случае при перекомпиляции программы, вы получите предупреждение компилятора, что требуется ключевок слово new. Т.к. вы скрываете определенную ф-ю базового класса. Логичнее всего в такой ситуации переименовать ф-ю производного класса.
Свойство кода вести себя по разному в зависимости от ситуации, возникающей в момент вып-я, наз-ся полиморфизмом.
Различают два вида полиморфизма:
· специальный полиморфизм
· чистый полиморфизм
Специальный реал-ся с помощью перегруженных ф-й.
Чистый полиморфизм связан с механизмом насл-я и реал-ся через виртуальные ф-ии.
в С# в отличие от С вызов некоторых ф-й на этапе трансляции только обозначается без точного указания какая именно ф-я вызывается. Какая из возможных ф-й будет вызвана определяется на этапе вып-я программы, такой процесс наз-ся поздним связыванием. Выбор во время вып-я соответствующей ф-ии среди ф-й основных и порожденных классов в зав-ти от О. наз-ся чистым полиморфизмом. Чистый полиморфизм нельзя путать с перегруженными ф-ми, где аргументы ф-ии различны по типу. Перегруженная ф-я выбирается во время компиляции, т.е. для нее осущ раннее связывание. Возможность динамически выбирать ф-ю, в зав-ти от О. осущ с помощью виртуальных ф-й.
Виртуальные ф-ии объявляются с помощью ключевого слова virtual. Это слово при определении ф-ии определяет для нее механизм позднего связывания. Виртуальными могут быть только не статические ф-ии, так как ар-ка virtualнаследуются. Виртуальная ф-я явл-ся обычным вып-м кодом и выз-ся так же как и др. ф-ии. В порожденном классе она может быть переопределена, т.е. для нее может быть написано новое тело.
Ф-я, объявленная в производном классе, переопр-т ВФ (виртуальную функцию )т и т.т. когда имеет то же имя и работает с тем же кол-вом и типом аргументов, что и ВФ базового класса. Если они отличаются хоть одним аргументом то ф-я в производном классе считается совершенно другой и переопределение не происходит.
Может возникнуть трудно уловимая ошибка, когда программист , считая, что о переопр-т ВФ базового класса, на самом деле, ошибившис в одном каком либо знаке заголовка ф-ии – определяет новую . В С # , для предотвращения подобной ошибк, необходимо явно указывать с помощью ключевого слова override, что переопр-ся ф-я БК.
встретив ключевое слово override, транслятор проверяет имеется ли ф-я с таким заголовком , среди ВФ БК.
Если ф-я объявленаvirtual, то это св-во передается всем переопределениям в порожденных классах. Переопределять ВФ в порожденном классе необязательно. В этом случае ФБК становится ф-ей производного класса.
Можно с помощью ключевого слова sealedзапретить переопределение ф-ии БК в производном классе. В этом случае попытка переопр-я приведет к ошибку трансляции.