Прошел курс. Получил код 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 . Порядок срабатывания конструкторов и деструкторов в иерархической лестнице
Результат вывода будет таким
Порядок корректного срабатывания конструкторов и деструкторов удобно представить как модель строительства и разрушения многоэтажного дома
Конструкторы устанавливают составной объект в нужное состояние, назначая полям заданные значения. Естественно, что вначале должна быть создана базовая часть объекта, как фундамент всей последующей надстройки частей, описанных в производных классах. Деструкторы срабатывают в порядке, обратном порядку создания конструкторов, обеспечивая последовательное разрушение объекта по направлению к фундаменту.