Виртуальная функция си шарп

virtual (Справочник по C#)

Ключевое слово virtual используется для изменения объявлений методов, свойств, индексаторов и событий и разрешения их переопределения в производном классе. Например, этот метод может быть переопределен любым наследующим его классом:

public virtual double Area()

Реализацию виртуального члена можно изменить путем переопределения члена в производном классе. Дополнительные сведения об использовании ключевого слова virtual см. в разделах Управление версиями с помощью ключевых слов Override и New и Использование ключевых слов Override и New.

Remarks

При вызове виртуального метода тип времени выполнения объекта проверяется на переопределение члена. Вызывается переопределение члена в самом дальнем классе. Это может быть исходный член, если никакой производный класс не выполнял переопределение этого члена.

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

Нельзя использовать модификатор virtual с модификаторами static , abstract , private , или override . В следующем примере показано виртуальное свойство.

class MyBaseClass < // virtual auto-implemented property. Overrides can only // provide specialized behavior if they implement get and set accessors. public virtual string Name < get; set; >// ordinary virtual property with backing field private int _num; public virtual int Number < get < return _num; >set < _num = value; >> > class MyDerivedClass : MyBaseClass < private string _name; // Override auto-implemented property with ordinary property // to provide specialized accessor behavior. public override string Name < get < return _name; >set < if (!string.IsNullOrEmpty(value)) < _name = value; >else < _name = "Unknown"; >> > > 

Действие виртуальных свойств аналогично виртуальным методам, за исключением отличий в синтаксисе объявлений и вызовов.

  • Использование модификатора virtual в статическом свойстве является недопустимым.
  • Виртуальное наследуемое свойство может быть переопределено в производном классе путем включения объявления свойства, которое использует модификатор override .
Читайте также:  Css code text padding

Пример

В этом примере класс Shape содержит две координаты x , y и виртуальный метод Area() . Различные классы фигур, такие как Circle , Cylinder и Sphere , наследуют класс Shape , и для каждой фигуры вычисляется площадь поверхности. Каждый производный класс обладает собственной реализацией переопределения метода Area() .

Обратите внимание, что наследуемые классы Circle , Sphere и Cylinder используют конструкторы, которые инициализируют базовый класс, как показано в следующем объявлении.

public Cylinder(double r, double h): base(r, h) <> 

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

class TestClass < public class Shape < public const double PI = Math.PI; protected double _x, _y; public Shape() < >public Shape(double x, double y) < _x = x; _y = y; >public virtual double Area() < return _x * _y; >> public class Circle : Shape < public Circle(double r) : base(r, 0) < >public override double Area() < return PI * _x * _x; >> public class Sphere : Shape < public Sphere(double r) : base(r, 0) < >public override double Area() < return 4 * PI * _x * _x; >> public class Cylinder : Shape < public Cylinder(double r, double h) : base(r, h) < >public override double Area() < return 2 * PI * _x * _x + 2 * PI * _x * _y; >> static void Main() < double r = 3.0, h = 5.0; Shape c = new Circle(r); Shape s = new Sphere(r); Shape l = new Cylinder(r, h); // Display results. Console.WriteLine("Area of Circle = ", c.Area()); Console.WriteLine("Area of Sphere = ", s.Area()); Console.WriteLine("Area of Cylinder = ", l.Area()); > > /* Output: Area of Circle = 28.27 Area of Sphere = 113.10 Area of Cylinder = 150.80 */ 

Спецификация языка C#

Дополнительные сведения см. в спецификации языка C#. Спецификация языка является предписывающим источником информации о синтаксисе и использовании языка C#.

Источник

Виртуальная функция си шарп

При наследовании нередко возникает необходимость изменить в классе-наследнике функционал метода, который был унаследован от базового класса. В этом случае класс-наследник может переопределять методы и свойства базового класса.

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

А чтобы переопределить метод в классе-наследнике, этот метод определяется с модификатором override . Переопределенный метод в классе-наследнике должен иметь тот же набор параметров, что и виртуальный метод в базовом классе.

Например, рассмотрим следующие классы:

class Person < public string Name < get; set; >public Person(string name) < Name = name; >public virtual void Print() < Console.WriteLine(Name); >> class Employee : Person < public string Company < get; set; >public Employee(string name, string company) : base(name) < Company = company; >>

Здесь класс Person представляет человека. Класс Employee наследуется от Person и представляет сотруднника предприятия. Этот класс кроме унаследованного свойства Name имеет еще одно свойство — Company.

Чтобы сделать метод Print доступным для переопределения, этот метод определен с модификатором virtual . Поэтому мы можем переопределить этот метод, но можем и не переопределять. Допустим, нас устраивает реализация метода из базового класса. В этом случае объекты Employee будут использовать реализацию метода Print из класса Person:

Person bob = new Person("Bob"); bob.Print(); // вызов метода Print из класса Person Employee tom = new Employee("Tom", "Microsoft"); tom.Print(); // вызов метода Print из класса Person

Но также можем переопределить виртуальный метод. Для этого в классе-наследнике определяется метод с модификатором override , который имеет то же самое имя и набор параметров:

class Employee : Person < public string Company < get; set; >public Employee(string name, string company) : base(name) < Company = company; >public override void Print() < Console.WriteLine($"работает в "); > >

Возьмем те же самые объекты:

Person bob = new Person("Bob"); bob.Print(); // вызов метода Print из класса Person Employee tom = new Employee("Tom", "Microsoft"); tom.Print(); // вызов метода Print из класса Employee
Bob Tom работает в Microsoft

Виртуальные методы базового класса определяют интерфейс всей иерархии, то есть в любом производном классе, который не является прямым наследником от базового класса, можно переопределить виртуальные методы. Например, мы можем определить класс Manager, который будет производным от Employee, и в нем также переопределить метод Print.

При переопределении виртуальных методов следует учитывать ряд ограничений:

  • Виртуальный и переопределенный методы должны иметь один и тот же модификатор доступа. То есть если виртуальный метод определен с помощью модификатора public, то и переопредленный метод также должен иметь модификатор public.
  • Нельзя переопределить или объявить виртуальным статический метод.

Ключевое слово base

Кроме конструкторов, мы можем обратиться с помощью ключевого слова base к другим членам базового класса. В нашем случае вызов base.Print(); будет обращением к методу Print() в классе Person:

class Employee : Person < public string Company < get; set; >public Employee(string name, string company) :base(name) < Company = company; >public override void Print() < base.Print(); Console.WriteLine($"работает в "); > >

Переопределение свойств

Также как и методы, можно переопределять свойства:

class Person < int age = 1; public virtual int Age < get =>age; set < if(value >0 && value < 110) age = value; >> public string Name < get; set; >public Person(string name) < Name = name; >public virtual void Print() => Console.WriteLine(Name); > class Employee : Person < public override int Age < get =>base.Age; set < if (value >17 && value < 110) base.Age = value; >> public string Company < get; set; >public Employee(string name, string company) : base(name) < Company = company; base.Age = 18; // возраст для работников по умолчанию >>

В данном случае в классе Person определено виртуальное свойство Age, которое устанавливает значение, если оно больше 0 и меньше 110. В классе Employee это свойство переопределено — возраст работника должен быть не меньше 18.

Person bob = new Person("Bob"); Console.WriteLine(bob.Age); // 1 Employee tom = new Employee("Tom", "Microsoft"); Console.WriteLine(tom.Age); // 18 tom.Age = 22; Console.WriteLine(tom.Age); // 22 tom.Age = 12; Console.WriteLine(tom.Age); // 22

Запрет переопределения методов

Также можно запретить переопределение методов и свойств. В этом случае их надо объявлять с модификатором sealed :

class Employee : Person < public string Company < get; set; >public Employee(string name, string company) : base(name) < Company = company; >public override sealed void Print() < Console.WriteLine($"работает в "); > >

При создании методов с модификатором sealed надо учитывать, что sealed применяется в паре с override, то есть только в переопределяемых методах.

И в этом случае мы не сможем переопределить метод Print в классе, унаследованном от Employee.

Источник

virtual (C# Reference)

The virtual keyword is used to modify a method, property, indexer, or event declaration and allow for it to be overridden in a derived class. For example, this method can be overridden by any class that inherits it:

public virtual double Area()

The implementation of a virtual member can be changed by an overriding member in a derived class. For more information about how to use the virtual keyword, see Versioning with the Override and New Keywords and Knowing When to Use Override and New Keywords.

Remarks

When a virtual method is invoked, the run-time type of the object is checked for an overriding member. The overriding member in the most derived class is called, which might be the original member, if no derived class has overridden the member.

By default, methods are non-virtual. You cannot override a non-virtual method.

You cannot use the virtual modifier with the static , abstract , private , or override modifiers. The following example shows a virtual property:

class MyBaseClass < // virtual auto-implemented property. Overrides can only // provide specialized behavior if they implement get and set accessors. public virtual string Name < get; set; >// ordinary virtual property with backing field private int _num; public virtual int Number < get < return _num; >set < _num = value; >> > class MyDerivedClass : MyBaseClass < private string _name; // Override auto-implemented property with ordinary property // to provide specialized accessor behavior. public override string Name < get < return _name; >set < if (!string.IsNullOrEmpty(value)) < _name = value; >else < _name = "Unknown"; >> > > 

Virtual properties behave like virtual methods, except for the differences in declaration and invocation syntax.

  • It is an error to use the virtual modifier on a static property.
  • A virtual inherited property can be overridden in a derived class by including a property declaration that uses the override modifier.

Example

In this example, the Shape class contains the two coordinates x , y , and the Area() virtual method. Different shape classes such as Circle , Cylinder , and Sphere inherit the Shape class, and the surface area is calculated for each figure. Each derived class has its own override implementation of Area() .

Notice that the inherited classes Circle , Sphere , and Cylinder all use constructors that initialize the base class, as shown in the following declaration.

public Cylinder(double r, double h): base(r, h) <> 

The following program calculates and displays the appropriate area for each figure by invoking the appropriate implementation of the Area() method, according to the object that is associated with the method.

class TestClass < public class Shape < public const double PI = Math.PI; protected double _x, _y; public Shape() < >public Shape(double x, double y) < _x = x; _y = y; >public virtual double Area() < return _x * _y; >> public class Circle : Shape < public Circle(double r) : base(r, 0) < >public override double Area() < return PI * _x * _x; >> public class Sphere : Shape < public Sphere(double r) : base(r, 0) < >public override double Area() < return 4 * PI * _x * _x; >> public class Cylinder : Shape < public Cylinder(double r, double h) : base(r, h) < >public override double Area() < return 2 * PI * _x * _x + 2 * PI * _x * _y; >> static void Main() < double r = 3.0, h = 5.0; Shape c = new Circle(r); Shape s = new Sphere(r); Shape l = new Cylinder(r, h); // Display results. Console.WriteLine("Area of Circle = ", c.Area()); Console.WriteLine("Area of Sphere = ", s.Area()); Console.WriteLine("Area of Cylinder = ", l.Area()); > > /* Output: Area of Circle = 28.27 Area of Sphere = 113.10 Area of Cylinder = 150.80 */ 

C# language specification

For more information, see the C# Language Specification. The language specification is the definitive source for C# syntax and usage.

Источник

Оцените статью