Переопределение виртуальных функций

Виртуальные функции

Чистый полиморфизм

Тема 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запретить переопределение ф-ии БК в производном классе. В этом случае попытка переопр-я приведет к ошибку трансляции.