Изучение виртуальных и абстрактных методов в C #

Язык программирования C # обеспечивает поддержку как виртуальных, так и абстрактных методов, каждый из которых имеет определенные преимущества. Вы используете виртуальные методы для реализации позднего связывания, тогда как абстрактные методы позволяют вам заставить подклассы типа явно переопределять метод. В этом посте я расскажу о виртуальных и абстрактных методах и о том, когда их следует использовать.

Виртуальный метод - это метод, который объявлен как виртуальный в базовом классе. Метод объявляется виртуальным путем указания ключевого слова virtual в сигнатуре метода. Виртуальный метод может иметь или не иметь возвращаемый тип. Виртуальные методы позволяют подклассам типа переопределять метод. Они используются для реализации полиморфизма времени выполнения или позднего связывания. Следует отметить, что виртуальные или абстрактные члены класса не могут быть объявлены частными. Кроме того, вы можете иметь реализацию в виртуальном методе, то есть виртуальные методы могут иметь реализации в себе. Эти реализации могут быть переопределены подклассами того типа, в котором был определен виртуальный метод.

В MSDN указано: «Ключевое слово virtual используется для изменения объявления метода, свойства, индексатора или события и позволяет переопределить его в производном классе».

Давайте теперь углубимся в код, чтобы лучше понять, как используются виртуальные методы. См. Фрагмент кода ниже.

public class Base

{

public virtual void Test()

{

Console.WriteLine("This is the base version of the virtual method");

}

}

public class Derived : Base

{

public override void Test()

{

Console.WriteLine("This is the derived version of the virtual method");

}

}

Метод Test () объявлен как виртуальный в базовом классе и переопределен в производном классе. Обратите внимание, как ключевое слово virtual используется для объявления метода виртуальным в базовом классе. Ключевое слово virtual не требуется при переопределении виртуального метода в классе Derived.

Теперь обратитесь к приведенному ниже фрагменту кода, который показывает, как вызываются виртуальные методы.

class Program

{

static void Main()

{

Base baseObj1 = new Base();

baseObj1.Test();

Base baseObj2 = new Derived();

baseObj2.Test();

}

}

Обратите внимание, что создаются два экземпляра базового класса - baseObj1 и baseObj2. В первом случае ссылочный объект с именем baseObj1 ссылается на экземпляр базового класса. Во втором случае ссылочный объект с именем baseObj2 ссылается на экземпляр класса Derived. Когда вы выполняете код, при первом вызове виртуального метода в консоли отображается сообщение «Это базовая версия виртуального метода». Во втором случае будет отображаться сообщение «Это производная версия виртуального метода». Почему такая разница?

В первом случае рассматривается тип эталонного объекта baseObj1 - поскольку он имеет тип Base, будет вызываться базовая версия виртуального метода. Во втором случае будет рассмотрен контекст ссылочного объекта baseObj2 и, следовательно, результат.

Абстрактные методы - это методы, которые объявлены абстрактными в базовом классе и не могут иметь в себе реализации, т. Е. Не могут иметь в себе каких-либо функций. Вы можете использовать абстрактные методы, когда хотите, чтобы метод был принудительно переопределен в производных классах того типа, в котором был определен абстрактный метод. Это принудительно выполняется компилятором во время компиляции. Итак, если вы объявили метод как абстрактный с использованием модификатора abstract в базовом классе, подклассы этого класса должны будут реализовать абстрактный метод, в случае сбоя которого компилятор отобразит ошибку, заявив, что производный класс не реализовал абстрактный член. По сути,абстрактный метод объявляется с использованием ключевого слова abstract в абстрактном базовом классе, а не абстрактные подклассы этого типа должны иметь собственную реализацию абстрактного метода. Абстрактные методы также неявно виртуальны по своей природе, но вы не можете использовать ключевое слово virtual при объявлении абстрактного метода. Следует отметить, что абстрактные методы могут быть объявлены только внутри абстрактных классов.

Типичное использование абстрактного метода - принудительное переопределение методов ToString () или Equals (). В следующем фрагменте кода показано, как абстрактные методы объявляются в абстрактном классе EntityBase.

public abstract class EntityBase

{

public abstract override string ToString();

public abstract override bool Equals(object obj);

}

public class Customer : EntityBase

{

//Implementation code for the abstract methods

}

Класс EntityBase является базовым типом для всех сущностей - класс сущности Customer расширяет этот класс и обеспечивает реализацию абстрактных методов. По сути, все классы сущностей будут предоставлять свою собственную реализацию методов ToString () и Equals (). Реализация по умолчанию для этих методов в базовом классе не требуется, поэтому они помечены как абстрактные. Таким образом, переопределение метода осуществляется путем объявления метода абстрактным в базовом классе EntityBase.