|
Прошел курс. Получил код 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 .
Все сказанное про виртуальные функции справедливо и для виртуальных свойств


