Программирование >>  Программирование с использованием ajax 

1 ... 80 81 82 [ 83 ] 84 85 86 ... 396


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

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

public class MyBaseClass {

public void DoSomething () {

Базовая реализация.

public class MyDerivedClass : MyBaseClass {

public void DoSomething () {

Реализация в производном классе, скрывающая базовую реализацию.

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

public class MyDerivedClass : MyBaseClass {

new piiblic void DoSomething ()

Реализация в производном классе, скрывающая базовую реализацию.

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

public class MyBaseClass {

public virtual void DoSomething ()

Console.WriteLine( Base imp );

Базовая реализация

public class MyDerivedClass : MyBaseClass {

public override void DoSomething ()

Console.WriteLine ( Derived ±axp ) ;

Производная реализация



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

MyDerivedClass myOb] = new MyDerivedClass(); MyBaseClass myBaseObj; myBaseObj = myObj; myBaseObj.DoSomething();

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

Derived imp

Производная реализация

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

public class MyBaseClass {

public virtual void DoSomething ()

Console.WriteLine ( Base imp );

Базовая реализация

public class MyDerivedClass : MyBaseClass

new public void DoSomething ()

Console.WriteLine( Derived imp );

Производная реализация

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

Base imp

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

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

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

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

□ Это может быть полезно при желании добавить реализацию унаследованного виртуального класса вместо того, чтобы просто заменять ее новой переопределенной реализацией.

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



тому, как оно применяется для управления конструкторами, что демонстрировалось в предыдущей главе):

public class MyBaseClass {

public virtual void DoSomething () {

Базовая реализация.

public class MyDerivedClass : MyBaseClass {

public override void DoSomething () {

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

Еще реализация в производном классе.

Этот код выполняет версию DoSomething, которая содержится в MyBaseClass, являющимся базовым классом MyDerivedClass, из версии DoSomething, которая содержится в MyDerivedClass. Поскольку ключевое слово base работает с экземплярами объектов, его использование в статическом члене считается ошибкой.

Ключевое слово this

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

Наиболее полезной функцией ключевого слова this является его способность передавать ссылку на текущий экземпляр объекта метода, как показано в следующем примере:

public void doSomething () {

MyTargetClass myOb] = new MyTargetClass (); myObj.DoSomethingWith (this);

Здесь объект MyTargetClass, экземпляр которого создается, имеет метод по имени DoSomethingWith, который принимает один единственный параметр такого типа, который является совместимым с типом класса, содержащего предыдущий метод. То есть тип этого параметра может представлять собой либо тип данного класса, либо тип класса, производным от которого является данный класс, либо тип интерфейса, реализуемого данным классом, либо (конечно же) тип System.Object.

Вложенные определения типов

Типы вроде классов можно определять не только в пространствах имен, но и внутри других классов. Такой подход открывает возможность использовать для определения целый ряд модификаторов доступности, а не только public и internal, а также позволяет применять ключевое слово new для сокрытия определения типа, унаследованного от базового класса. Например, в следующем коде помимо класса MyClass также еще определяется и вложенный класс по имени myNestedClass:



1 ... 80 81 82 [ 83 ] 84 85 86 ... 396

© 2006 - 2024 pmbk.ru. Генерация страницы: 0.355
При копировании материалов приветствуются ссылки.
Яндекс.Метрика