Герберт Шилдт - C# 4.0 полное руководство - 2011
- Название:C# 4.0 полное руководство - 2011
- Автор:
- Жанр:
- Издательство:неизвестно
- Год:неизвестен
- ISBN:нет данных
- Рейтинг:
- Избранное:Добавить в избранное
-
Отзывы:
-
Ваша оценка:
Герберт Шилдт - C# 4.0 полное руководство - 2011 краткое содержание
C# 4.0 полное руководство - 2011 - читать онлайн бесплатно полную версию (весь текст целиком)
Интервал:
Закладка:
может быть свой вариант виртуального метода. Кроме того, виртуальные методы интересны тем, что именно происходит при их вызове по ссылке на базовый класс. В этом случае средствами языка C# определяется именно тот вариант виртуального метода, который следует вызывать, исходя из типа объекта, к которому происходит обращение по ссылке , причем это делается во время выполнения. Поэтому при ссылке на разные типы объектов выполняются разные варианты виртуального метода. Иными словами, вариант выполняемого виртуального метода выбирается по типу объекта, а не по типу ссылки на этот объект. Так, если базовый класс содержит виртуальный метод и от него получены производные классы, то при обращении к разным типам объектов по ссылке на базовый класс выполняются разные варианты этого виртуального метода.
Метод объявляется как виртуальный в базовом классе с помощью ключевого слова virtual, указываемого перед его именем. Когда же виртуальный метод переопределяется в производном классе, то для этого используется модификатор override. А сам процесс повторного определения виртуального метода в производном классе называется переопределением метода. При переопределении имя, возвращаемый тип и сигнатура переопределяющего метода должны быть точно такими же, как и у того виртуального метода, который переопределяется. Кроме того, виртуальный метод не может быть объявлен как static или abstract (подробнее данный вопрос рассматривается далее в этой главе).
Переопределение метода служит основанием для воплощения одного из самых эффективных в C# принципов: динамической диспетчеризации методов , которая представляет собой механизм разрешения вызова во время выполнения, а не компиляции. Значение динамической диспетчеризации методов состоит в том, что именно благодаря ей в C# реализуется динамический полиморфизм.
Ниже приведен пример, демонстрирующий виртуальные методы и их переопределение.
// Продемонстрировать виртуальный метод.
using System;
class Base {
// Создать виртуальный метод в базовом классе, public virtual void Who() {
Console.WriteLine("Метод Who() в классе Base");
}
}
class Derivedl : 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();
Derivedl dObl = new DerivedlO;
Deri'ved2 dOb2 = new Derived2();
Base baseRef; // ссылка на базовый класс
baseRef = baseOb; baseRef.Who() ;
baseRef = dObl; baseRef.Who();
baseRef = d0b2; baseRef.Who();
}
}
Вот к какому результату приводит выполнение этого кода.
Метод Who() в классе Base.
Метод Who() в классе Derivedl Метод Who() в классе Derived2
В коде из приведенного выше примера создаются базовый класс Base и два производных от него класса — Derivedl и Derived2. В классе Base объявляется виртуальный метод Who () , который переопределяется в обоих производных классах. Затем в методе Main () объявляются объекты типа Base, Derivedl и Derived2. Кроме того, объявляется переменная baseRef ссылочного типа Base. Далее ссылка на каждый тип объекта присваивается переменной baseRef и затем используется для вызова метода Who () . Как следует из результата выполнения приведенного выше кода, вариант выполняемого метода Who () определяется по типу объекта, к которому происходит обращение по ссылке во время вызова этого метода, а не по типу класса переменной baseRef.
Но переопределять виртуальный метод совсем не обязательно. Ведь если в производном классе не предоставляется собственный вариант виртуального метода, то используется его вариант из базового класса, как в приведенном ниже примере.
/* Если виртуальный метод не переопределяется, то используется его вариант из базового класса. */
using System;
class Base {
// Создать виртуальный метод в базовом классе. public virtual void Who() {
Console.WriteLine("Метод Who() в классе Base");
}
}
class Derivedl : Base {
// Переопределить метод Who() в производном классе.
public override void Who() {
Console.WriteLine("Метод Who() в классе Derivedl");
}
}
class Derived2 : Base {
// В этом классе метод Who() не переопределяется.
}
class NoOverrideDemo { static void Main() {
Base baseOb = new Base();
Derivedl dObl = new Derivedl();
Derived2 d0b2 = new Derived2();
Base baseRef; // ссылка на базовый класс
baseRef = baseOb; baseRef.Who();
baseRef = dObl ; baseRef.Who() ;
baseRef = d0b2;
• baseRef.Who(); // вызывается метод Who() из класса Base }
}
Выполнение этого кода приводит к следующему результату.
Метод Who() в классе Base.
Метод Who() в классе Derivedl Метод Who() в классе Base
В данном примере метод Who () не переопределяется в классе Derived2. Поэтому для объекта класса Derived2 вызывается метод Who () из класса Base.
Если при наличии многоуровневой иерархии виртуальный метод не переопределяется в производном классе, то выполняется ближайший его вариант, обнаруживаемый вверх по иерархии, как в приведенном ниже примере.
/* В многоуровневой иерархии классов выполняется тот переопределенный вариант виртуального метода, который обнаруживается первым при продвижении вверх по иерархии. */
using System;
class Base {
// Создать виртуальный метод в базовом классе, public virtual void Who() {
Console.WriteLine("Метод Who() в классе Base");
}
}
class Derivedl : Base {
// Переопределить метод Who() в производном классе. public override void Who() {
Console.WriteLine("Метод Who() в классе Derivedl");
}
}
class Derived2 : Derivedl {
// В этом классе метод Who() не переопределяется.
}
class Derived3 : Derived2 {
//Ив этом классе метод Who() не переопределяется.
}
Читать дальшеИнтервал:
Закладка: