|
Прошел курс. Получил код Dreamspark. Ввожу код на сайте, пишет: Срок действия этого кода проверки уже истек. Проверьте, правильно ли введен код. У вас осталось две попытки. Вы также можете выбрать другой способ проверки или предоставить соответствующие документы, подтверждающие ваш академический статус.
Как активировать код? |
Наследование в C#
Сокрытие имен при наследовании
Находясь внутри производного класса мы можем видеть как-бы два слоя членов: члены производного класса на переднем плане и члены базового класса на заднем плане. Производный и базовый классы могут иметь члены с одинаковыми именам и. Это не является ошибкой, и даже компилятор не выдаст предупреждение, что будет использован член производного класса. Лишь текстовый редактор оболочки напомнит подчеркиванием, что имя члена в производном классе, находящееся в переднем слое, скрывает имя члена базового класса и желательно использовать ключевое слово new, но можно обойтись и без него. Употребление ключевого слова new в данном контексте свидетельствует лишь о том, что программист извещен и знает, что делает. Вот пример
using System;
namespace Test
{
class A
{
protected int x; // Член класса A будет виден в наследниках
public A(int a)
{
x = a;
}
public A()// Обязаны определить
{ }
protected int Get() // Член класса A будет виден в наследниках
{
return x;
}
}
class Empty : A
{
public Empty(int a)
: base(a)
{ }
public Empty() { } // Обязаны определить,
// если определен в базовом классе
}
class B : Empty
{
new int x; // Член класса B, одноименный с унаследованным
public B(int a, int b)
: base(a)
{
x = b; // Значение присваивается члену текущего класса
}
public B(int x)
{
base.x = 10;// Значение присваивается члену базового класса
this.x = x; // Значение присваивается члену текущего класса
}
new int Get() // Член класса B, одноименный с унаследованным
{
return x;
}
public void Show()
{
int sumOfSquares =
base.Get() * base.Get() // Используется унаследованный член
+ Get() * Get(); // Используется член текущего класса
Console.WriteLine("Сумма квадратов:
{0}", sumOfSquares);
}
}
// Вызывающий код
class Program
{
static void Main()
{
// Настройка консоли
Console.Title = "Сокрытие унаследованных имен";
Console.ForegroundColor = ConsoleColor.White;
Console.CursorVisible = false;
Console.WindowWidth = 60;
Console.WindowHeight = 10;
B ob = new B(1, 2);
ob.Show();
Console.WriteLine("Контрольная сумма
квадратов: {0}", 1 + 4);
Console.WriteLine();
ob = new B(5);// Использование ссылки для другого объекта
ob.Show();
Console.WriteLine("Контрольная сумма квадратов:
{0}", 125);
Console.ReadLine();
}
}
}
Листинг
9.7 .
Доступ к одноименным членам в цепочке наследования
Ключевое слово base в данном контексте используется для доступа к члену базового класса, ближайшему в многоуровневой цепочке наследования, содержащему одноименный член. Промежуточный класс Empty здесь как раз и приведен для иллюстрации того, что одноименный член не обязательно может находиться в соседнем базовом классе.
Последовательность срабатывания конструкторов
В многоуровневой цепочке наследования производный класс стоит в самом низу иерархической лестницы. Если создается объект этого составного класса, то срабатывание конструкторов выполняется в сторону производного класса, начиная с конструктора базового класса, в порядке их выведения. Деструкторы срабатывают в обратном порядке и только при активизации сборщика мусора ( GC - Garbare Collector ). Вот пример
using System;
namespace Test
{
class A
{
public A()
{
Console.WriteLine("Сработал конструктор A");
}
~A()
{
Console.WriteLine("Сработал деструктор A");
}
}
class B : A
{
public B()
{
Console.WriteLine("Сработал конструктор B");
}
~B()
{
Console.WriteLine("Сработал деструктор B");
}
}
class C : B
{
public C()
{
Console.WriteLine("Сработал конструктор C");
}
~C()
{
Console.WriteLine("Сработал деструктор C");
}
}
class D : C
{
public D()
{
Console.WriteLine("Сработал конструктор D");
}
~D()
{
Console.WriteLine("Сработал деструктор D");
}
}
// Вызывающий код
class Program
{
static void Main()
{
// Настройка консоли
Console.Title = "Вызовы конструкторов и деструкторов";
Console.ForegroundColor = ConsoleColor.White;
Console.CursorVisible = false;
Console.WindowWidth = 60;
Console.WindowHeight = 10;
D ob = new D(); // Создаем объект
ob = null; // Теряем объект, чтобы сработали деструкторы
Console.WriteLine();// Новая строка в выводе
GC.Collect();// Принудительно вызываем сборщик мусора
GC.WaitForPendingFinalizers(); // Приостанавливаем текущий поток
// до завершения уборки
Console.ReadLine();
}
}
}
Листинг
9.8 .
Порядок срабатывания конструкторов и деструкторов в иерархической лестнице
Результат вывода будет таким
Порядок корректного срабатывания конструкторов и деструкторов удобно представить как модель строительства и разрушения многоэтажного дома
Конструкторы устанавливают составной объект в нужное состояние, назначая полям заданные значения. Естественно, что вначале должна быть создана базовая часть объекта, как фундамент всей последующей надстройки частей, описанных в производных классах. Деструкторы срабатывают в порядке, обратном порядку создания конструкторов, обеспечивая последовательное разрушение объекта по направлению к фундаменту.

