Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
7 семестр / Учебники / Все лекции С# / Все лекции С# / Лекции C# for print fineprint.docx
Скачиваний:
340
Добавлен:
24.02.2016
Размер:
523 Кб
Скачать
☆

Сокрытие методов базового класса

При наследовании некоторого члена базового класса наследуется также и его реализация. Если наследуемый член являетсявиртуальным, то имеется возможность переопределить его реализацию, используя ключевое словоoverride. Независимо от того, является ли наследуемый член виртуальным, при необходимости можноскрыть его реализацию. Например, это полезно, когда наследуемый общий член работает не так, как требуется. Сокрытие достигается использованием следующего кода:

publicclassmybase

{

publicvoidf() { //базовая реализация}

}

publicclassderived:mybase

{

publicvoidf() { //реализация, скрывающая базовую реализацию}

}

Хотя такой код будет работать нормально, он сгенерирует предупреждение о том, что в нем скрывается член базового класса. Это дает возможность исправить положение дел, если мы случайно скрыли член, который на самом деле желаем использовать. Если же этот член действительно требуется скрыть, то об этом можно сказать явно, воспользовавшись ключевым словомnew:

publicclassderived:mybase

{

new publicvoidf() {//теперь ДЕЙСТВИТЕЛЬНО скрыли базовую реализацию}

}

Этот код будет работать точно так же, только без выдачи предупреждения.

Разницу между скрытыми и переопределенными членами базового класса рассмотрим на примере:

public class mybase

{

public virtual void f() { Console.WriteLine("Базовая реализация");}

}

public class derived: mybase

{

public override void f() { Console.WriteLine('Производная реализация");}

}

В данном случае переопределенный метод f()заменяет собойреализацию базового класса, так что в следующем коде будет использоваться новая версия, несмотря на то, что обращение к методу происходит через тип базового класса (с использованием полиморфизма):

derived d= new derived();

mybase b;

b=d; //обратите внимание на присвоение экземпляров классов

b.f();

Результатом объявления экземпляров базового и производного классов и вызова переопределенного метода f() будет следующее:Производная реализация

В качестве альтернативы можно скрыть метод базового класса с помощью следующего кода:

public class mybase

{

public virtual void f() { Console.WriteLine('Базовая реализация");}

}

public class derived : mybase

{ new public void f() {Console.WriteLine("Производная реализация") ;}

}

Метод базового класса при этом совершенно не обязательно должен быть виртуальным, однако от этого ничего не изменится, и приведенный здесь код отличается от предыдущего варианта только одной строкой. Результат выполнения этого кода, как при виртуальном методе, так и в противном случае будет следующим: Базовая реализация

Несмотря на то, что базовая реализация является скрытой, к ней, как и раньше, имеется доступ через базовый класс.

Вызов переопределенных или скрытых методов базового класса

Независимо от того, переопределяется некоторый член или скрывается, по-прежнему остается возможность доступа к члену базового класса внутри данного класса. Существует множество различных ситуаций, когда это оказывается полезным, например:

• Если требуется скрыть наследуемый общий член от пользователей производного класса, но необходимо иметь доступ к его функциональным возможностям внутри класса.

• Если требуется что-либо добавить к реализации наследуемого виртуального члена, а не просто заменить ее на новую переопределенную реализацию.

Для этого необходимо воспользоваться ключевым словом base,которое указывает на реализацию базового класса, содержащуюся внутри производного класса.

Например:

publicclassmybase

{

publicvirtualvoidf() { // Базовая реализация}

}

public class derived: mybase

{

public override void f()

{ // Реализация в производном классе, расширяющая реализацию в базовом классе base.f();

//Дополнительная реализация в производном классе

}

В представленном коде выполняется версия метода f(), содержащаяся в классеmybase (базовом), из которой вызывается версияf(), содержащаяся внутри классаderived. Поскольку ключевое словоbase работает с экземплярами объектов, то будет ошибкой использовать его внутристатического члена.