Полезное:
Как сделать разговор полезным и приятным
Как сделать объемную звезду своими руками
Как сделать то, что делать не хочется?
Как сделать погремушку
Как сделать так чтобы женщины сами знакомились с вами
Как сделать идею коммерческой
Как сделать хорошую растяжку ног?
Как сделать наш разум здоровым?
Как сделать, чтобы люди обманывали меньше
Вопрос 4. Как сделать так, чтобы вас уважали и ценили?
Как сделать лучше себе и другим людям
Как сделать свидание интересным?
Категории:
АрхитектураАстрономияБиологияГеографияГеологияИнформатикаИскусствоИсторияКулинарияКультураМаркетингМатематикаМедицинаМенеджментОхрана трудаПравоПроизводствоПсихологияРелигияСоциологияСпортТехникаФизикаФилософияХимияЭкологияЭкономикаЭлектроника
|
Виртуальные методы и их переопределениеВиртуальным называется такой метод, который объявляется как virtual в базовом классе. Виртуальный метод отличается тем, что он может быть переопределен в одном или нескольких производных классах. Следовательно, у каждого производного класса может быть свой вариант виртуального метода. Кроме того, виртуальные методы интересны тем, что именно происходит при их вызове по ссылке на базовый класс. В этом случае средствами языка C# определяется именно тот вариант виртуального метода, который следует вызывать, исходя из типа объекта, к которому происходит обращение по ссылке, причем это делается во время выполнения. Иными словами, вариант выполняемого виртуального метода выбирается по типу объекта, а не по типу ссылки на этот объект. Метод объявляется как виртуальный в базовом классе с помощью ключевого слова virtual, указываемого перед его именем. Когда же виртуальный метод переопределяется в производном классе, то для этого используется модификатор override. А сам процесс повторного определения виртуального метода в производном классе называется переопределением метода. При переопределении имя, возвращаемый тип и сигнатура переопределяющего метода должны быть точно такими же, как и у того виртуального метода, который переопределяется. Кроме того, виртуальный метод не может быть объявлен как static или abstract. Переопределение метода служит основанием для воплощения одного из самых эффективных в C# принципов: динамической диспетчеризации методов, которая представляет собой механизм разрешения вызова во время выполнения, а не компиляции. Значение динамической диспетчеризации методов состоит в том, что именно благодаря ей в C# реализуется динамический полиморфизм. //Продемонстрировать виртуальный метод. using System; class Base { // Создать виртуальный метод в базовом классе. public virtual void Who() { Console.WriteLine("Метод Who() в классе Base"); } } class Derived1: Base { // Переопределить метод Who() в производном классе. public override void Who() { Console.WriteLine("Метод Who() в классе Derivedl"); } } class Derived2: Base { // Вновь переопределить метод Who() в еще одном производном классе. public override void Who() { Console.WriteLine("Метод Who() в классе Derived2"); } } class OverrideDemo { static void Main() { Base baseOb = new Base(); Derived1 dOb1 = new Derived1(); Derived2 dOb2 = new Derived2(); Base baseRef;//ссылка на базовый класс
baseRef = baseOb; baseRef.Who();
baseRef = dOb1; baseRef.Who();
baseRef = dOb2; baseRef.Who(); } } Метод Who() в классе Base. Метод Who() в классе Derived1 Метод Who() в классе Derived2
В коде из приведенного выше примера создаются базовый класс Baseи два производных от него класса — Derived1 и Derived2. В классе Base объявляется виртуальный метод Who(), который переопределяется в обоих производных классах. Но переопределять виртуальный метод совсем не обязательно. Ведь если в производном классе не предоставляется собственный вариант виртуального метода, то используется его вариант из базового класса, как в приведенном ниже примере. /* Если виртуальный метод не переопределяется, то используется его вариант из базового класса. */ using System; class Base { // Создать виртуальный метод в базовом классе. public virtual void Who() { Console.WriteLine("Метод Who() в классе Base"); } } class Derived1: Base { // Переопределить метод Who() в производном классе. public override void Who() { Console.WriteLine("Метод Who() в классе Derived1"); } } class Derived2: Base { // В этом классе метод Who() не переопределяется. } class NoOverrideDemo { static void Main() { Base baseOb = new Base(); Derived1 dOb1 = new Derived1(); Derived2 dOb2 = new Derived2(); Base baseRef; // ссылка на базовый класс baseRef = baseOb; baseRef.Who(); baseRef = dOb1; baseRef.Who(); baseRef = dOb2; baseRef.Who(); // вызывается метод Who() из класса Base } } Метод Who() в классе Base. Метод Who() в классе Derived1 Метод Who() в классе Base Если при наличии многоуровневой иерархии виртуальный метод не переопределяется в производном классе, то выполняется ближайший его вариант, обнаруживаемый вверх по иерархии, как в приведенном ниже примере. /* В многоуровневой иерархии классов выполняется тот переопределенный вариант виртуального метода, который обнаруживается первым при продвижении вверх по иерархии. */ using System; class Base { // Создать виртуальный метод в базовом классе. public virtual void Who() { Console.WriteLine("Метод Who() в классе Base"); } } class Derived1: Base { // Переопределить метод Who() в производном классе. public override void Who() { Console.WriteLine("Метод Who() в классе Derived1"); } } class Derived2: Derived1 { // В этом классе метод Who() не переопределяется. } class Derived3: Derived2 { // И в этом классе метод Who() не переопределяется. } class NoOverrideDemo2 { static void Main() { Derived3 dOb = new Derived3(); Base baseRef; // ссылка на базовый класс baseRef = dOb; baseRef.Who(); // вызов метода Who() из класса Derived1 } } Метод Who() в классе Derivedl И еще одно замечание: свойства также подлежат модификации ключевым словом virtual и переопределению ключевым словом override. Это же относится и к индексаторам.
|