Прошел курс. Получил код Dreamspark. Ввожу код на сайте, пишет: Срок действия этого кода проверки уже истек. Проверьте, правильно ли введен код. У вас осталось две попытки. Вы также можете выбрать другой способ проверки или предоставить соответствующие документы, подтверждающие ваш академический статус.
Как активировать код? |
Наследование в C#
Если в крайнем слое адресуемого объекта вызываемая функция непереопределена или отсутствует в нем, ищется ее переопределение в ближайшем слое в сторону слоя базового класса.
Пример
using System; namespace Test { class Point { string name = "Слой Point"; public virtual void Show() { Console.WriteLine(name); } } class Circle : Point { string name = "Слой Circle"; public override void Show() { Console.WriteLine(name); } } class Cylinder : Circle { string name = "Слой Cylinder"; new public void Show() { Console.WriteLine(name); } } // Вызывающая сторона class MyClass { public MyClass() { // Создаем объекты для всех типов // иерархической цепочки наследования // и адресуем их базовой ссылкой Point[] point = { new Point(), new Circle(), new Cylinder() }; // Распечатываем Console.WriteLine("Адресация к ближайшей виртуальной функции"); for (int i = 0; i < point.Length; i++) point[i].Show(); Console.WriteLine(); Console.WriteLine("Адресуемся к слою Cylinder напрямую"); ((Cylinder)point[2]).Show();// Адресуемся напрямую // Извращенный синтаксис использования массива Console.WriteLine(); Console.WriteLine("Нерациональный синтаксис использования массива"); for (int i = 0; i < 3; i++) { Point point1 = new Point[]{ new Point(), new Circle(), new Cylinder() }[i]; point1.Show(); } } } // Запуск class Program { static void Main() { // Настройка консоли Console.Title = "Механизм виртуальных функций"; Console.ForegroundColor = ConsoleColor.White; Console.CursorVisible = false; Console.WindowWidth = 60; Console.WindowHeight = 15; new MyClass();// Чтобы сработал конструктор Console.ReadLine(); } } }Листинг 9.15 . Поиск виртуальной функции по цепочке наследования
Результат выполнения будет такой
Мы видим, что при попытке адресации виртуальной функции в объекте Cylinder, которой в расширяющем слое этого объекта нет, вызвался вариант из слоя Circle. Тонкая ссылка при адресации к толстому объекту игнорирует невиртуальные функции в толстых слоях, поскольку они не включены в таблицу виртуальных функций. Если бы и в слое Circle объекта Cylinder этой функции не было, то вызвался бы вариант слоя Point. Если бы вообще этой функции не было ни в одном слое, то была бы сгенерирована ошибка компиляции как попытка вызова несуществующего члена.
Вот еще один отвлеченный пример адресации к ближайшей виртуальной функции
using System; namespace Test { class A { string name = "Слой A"; public virtual void Show() { Console.WriteLine(name); } } class B : A { string name = "Слой B"; } class C : B { string name = "Слой C"; public override void Show() { Console.WriteLine(name); } } class D : C { string name = "Слой D"; } class E : D { string name = "Слой E"; public override void Show() { Console.WriteLine(name); } } class F : E { string name = "Слой F"; public override void Show() { Console.WriteLine(name); } } // Вызывающая сторона class MyClass { public MyClass() { // Создаем объекты для всех типов // иерархической цепочки наследования // и адресуем их базовой ссылкой A[] a = { new A(), new B(), new C(), new D(), new E(), new F() }; // Распечатываем Console.WriteLine("Адресация к ближайшей виртуальной функции"); Console.WriteLine("В классах B и D виртуальная функция отсутствует"); for (int i = 0; i < a.Length; i++) { Console.Write("Объект " + a[i].GetType().Name + "\t"); a[i].Show(); } } } // Запуск class Program { static void Main() { // Настройка консоли Console.Title = "Поиск виртуальной функции в глубину наследования"; Console.ForegroundColor = ConsoleColor.White; Console.CursorVisible = false; Console.WindowWidth = 60; Console.WindowHeight = 10; new MyClass();// Чтобы сработал конструктор Console.ReadLine(); } } }Листинг 9.16 . Адресация к ближайшей виртуальной функции
и результат выполнения программы
Мы видим, что при адресации к слою, где функция не переопределена (слой B и D ), поиск по порядку ведется в ближайших от адресуемого слоях в направлении базового слоя.
using System; namespace Test { class A { string name = "Слой A"; public virtual string Name { get { return name; } } public virtual void Show() { Console.WriteLine(name); } } class B : A { string name = "Слой B"; public override string Name { get { return name; } } public override void Show() { Console.WriteLine(name); } } class C : B { string name = "Слой C"; public override string Name { get { return name; } } public override void Show() { Console.WriteLine(name); } } // Вызывающая сторона class MyClass { public MyClass() { A[] a = { new A(), new B(), new C() }; // Распечатываем Console.WriteLine("Виртуальные методы:"); for (int i = 0; i < a.Length; i++) { Console.Write("Объект " + a[i].GetType().Name + "\t"); a[i].Show(); } // Распечатываем Console.WriteLine("\nВиртуальные свойства:"); for (int i = 0; i < a.Length; i++) { Console.WriteLine("Объект " + a[i].GetType().Name + "\t" + "{0}", a[i].Name); } } } // Запуск class Program { static void Main() { // Настройка консоли Console.Title = "Виртуальные методы и свойства"; Console.ForegroundColor = ConsoleColor.White; Console.CursorVisible = false; Console.WindowWidth = 60; Console.WindowHeight = 10; new MyClass();// Чтобы сработал конструктор Console.ReadLine(); } } }Листинг 9.17 . Все сказанное про виртуальные функции справедливо и для виртуальных свойств