Переопределение виртуальных методов в обобщенном классе

В обобщенном классе виртуальный метод может быть переопределен таким же образом, как и любой другой метод. В качестве примера рассмотрим следующую программу, в которой переопределяется виртуальный метод GetOb().

// Пример переопределения виртуального метода в обобщенном классе,

using System;

// Обобщенный базовый класс,

class Gen<T> {

  protected T ob;

  public Gen(T о) {

    ob = о;

  }

  // Возвратить значение переменной ob.

  // Этот метод является виртуальным.

  public virtual T GetOb() {

    Console.Write("Метод GetOb() из класса Gen" + " возвращает результат: ");

    return ob;

  }

}

// Класс, производный от класса Gen. В этом классе

// переопределяется метод GetOb().

class Gen2<T> : Gen<T> {

  public Gen2(T o) : base(o) { }

  // Переопределить метод GetOb().

  public override T GetOb() {

    Console.Write("Метод GetOb() из класса Gen2" + " возвращает результат: ");

    return ob;

  }

}

// Продемонстрировать переопределение метода в обобщенном классе,

class OverrideDemo {

  static void Main() {

    // Создать объект класса Gen с параметром типа int.

    Gen<int> iOb = new Gen<int>(88);

    // Здесь вызывается вариант метода GetOb() из класса Gen.

    Console.WriteLine(iOb.GetOb());

    //А теперь создать объект класса Gen2 и присвоить

    // ссылку на него переменной iOb типа Gen<int>.

    iOb = new Gen2<int>(99);

    // Здесь вызывается вариант метода GetOb() из класса Gen2.

    Console.WriteLine(iOb.GetOb());

  }

}

Ниже приведен результат выполнения этой программы.

Метод GetOb() из класса Gen возвращает результат: 88

Метод GetOb() из класса Gen2 возвращает результат: 99

Как следует из результата выполнения приведенной выше программы, переопределяемый вариант метода GetOb() вызывается для объекта типа Gen2, а его вариант из базового класса вызывается для объекта типа Gen.

Обратите внимание на следующую строку кода.

iOb = new Gen2<int>(99);

Такое присваивание вполне допустимо, поскольку iOb является переменной типа Gen<int>. Следовательно, она может ссылаться на любой объект типа Gen<int> или же объект класса, производного от Gen<int>, включая и Gen2<int>. Разумеется, переменную iOb нельзя использовать, например, для ссылки на объект типа Gen2<int>, поскольку это может привести к несоответствию типов.