Подтвердить что ты не робот

Что такое виртуальные методы?

Почему вы объявляете метод "виртуальным".

В чем преимущество использования виртуальных?

4b9b3361

Ответ 1

Virtual Модификатор используется для обозначения того, что метод \property (ect) может быть изменен в производном классе с помощью изменить модификатор.

Пример:

class A
{
    public virtual void Foo()
       //DoStuff For A
}

class B : A
{
    public override void Foo()
    //DoStuff For B

    //now call the base to do the stuff for A and B 
    //if required
    base.Foo()
}

Ответ 2

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

public class Thingy
{
    public virtual void StepA()
    {
        Console.Out.WriteLine("Zing");
    }

    public void Action()
    {
        StepA();
        Console.Out.WriteLine("A Thingy in Action.");
    }
}

public class Widget : Thingy
{
    public override void StepA()
    {
        Console.Out.WriteLine("Wiggy");
    }
}

class Program
{
    static void Main(string[] args)
    {
        Thingy thingy = new Thingy();
        Widget widget = new Widget();

        thingy.Action();
        widget.Action();

        Console.Out.WriteLine("Press any key to quit.");
        Console.ReadKey();
    }
 }

При запуске программы ваш выход будет выглядеть следующим образом:

Zing 
A Thingy in Action. 
Wiggy 
A Thingy in Action.

Обратите внимание, что хотя Виджет вызвал метод Action(), определенный на уровне Thingy, внутренне Thingy вызвал метод Widget StepA().

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

Ответ 3

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

Не виртуальный метод - это тип метода, в котором вызываемый фактический метод зависит от ссылочного типа объекта в точке вызова метода.

Ответ 4

Виртуальные методы в MSDN

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

При вызове виртуального метода проверяется тип времени выполнения объекта для переопределяющего элемента. переопределяющий элемент в самом производном класс, который может быть исходный элемент, если нет производного класса переопределил член. (Для большего информация о времени выполнения и большинстве производная реализация, см. 10.5.3 Виртуальные методы.)

По умолчанию методы не виртуальны. Вы не можете переопределить не виртуальные Метод.

Вы не можете использовать виртуальный модификатор со следующими модификаторами:

статический абстрактный переопределить

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

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

Ответ 5

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

Ответ 6

Даже если вы не планируете выводить из класса, может понадобиться маркировка метода virtual, чтобы издеваться над классом. Некоторые издевательские фреймворки позволяют только высмеять виртуальные методы. Обратите внимание, что методы, реализующие интерфейс, являются виртуальными неявно.

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

Ответ 7

Чтобы переопределить его в наследующих классах.

Отметьте запись MSDN для ключевого слова. Это объясняет это более подробно.

Ответ 8

Короткий вопрос, короткий ответ! Определите ваш метод как "виртуальный", если вы думаете, что унаследуете класс, которому он принадлежит.

Более длинный ответ: "Виртуальный позволяет вам переопределить, чтобы дать другое значение вашего метода в производном классе.

Ответ 9

Излишне говорить, что виртуальные методы пригождаются, когда ваш код пытается соблюдать Открытый закрытый принцип

Подробнее о принципе открытого закрытия здесь, оригинальная документация OCP дяди Боба.

Также следует помнить, что методы не являются виртуальными по умолчанию в С#, в отличие от Java.

Ответ 10

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

    public class sample {
      public virtual void fun(){
        Console.WriteLine("base sample class \n");
      }
    }
    public class A : sample{
      public override void fun(){
        Console.WriteLine("Class A \n");
      }
    }
    public class B : sample{
      public override void fun(){
        Console.WriteLine("Class B \n");
      }
    }
    class run{
      public static void main(String[] args){
        sample obj = new sample();
        sample obj1 = new A();
        sample obj2 = new B();
        obj.fun();
        obj1.fun();
        obj2.fun();
      }
    }

Ответ 12

Время выполнения происходит во время компиляции.
Когда вы объявляете метод как виртуальный, для объявления его в производном классе необходимо добавить override или new модификатор.
мы можем видеть это, когда TrySpeak. Передавая ребенка и отца, оба вызывают Speak of отца, в то время как TryScream будет вызывать каждый метод.
Чтобы понять это, есть некоторые вещи, которые мы должны знать, в случае с Child. Есть два метода Scream из класса Child или класса Father. Мы могли бы позвонить в Scream из класса Child или в класс отца. Поскольку Virtaul Modifier помечает метод так, что он может быть переопределен производным классом, что означает, что даже Scream вызывается из класса Father, он переопределяется, он будет отклоняться, если вы используете новый модификатор.

import system;
class Father
{
    Speak()
    {
        Console.Writeline("Father is speaking") 
    }
    virtual Scream()
    {
        Console.Writeline("Father is screaming")    
    }
}
class Child: father
{
    Speak()
    {
        Console.Writeline("Child is speaking")  
    }
    override Scream()
    {
        Console.Writeline("Child is screaming") 
    }
}
class APP
{
    public static void Main()
    {
        // We new two instances here
        Father father = new Father();
        Child child = new Child();        
        // Here we call their scream or speak through TryScream or TrySpeak
        TrySpeak(father);
        TrySpeak(child);
        //>>>"Father is speaking"
        //>>>"Father is speaking"
        TryScream(father);
        TryScream(child);
        //>>>"Father is screaming"
        //>>>"Child is screaming"
    }
    // when your method take an Parameter who type is Father
    // You can either pass in a Father instance or
    // A instance of a derived Class from Father
    // which could be Child
    public static void TrySpeak(Father person)
    {
        person.Scream();
    }
    public static void TryScream(Father person)
    {
        person.Speak();
    }
}

Ответ 13

Эта ссылка предоставит вам лучшее понимание с очень легким примером fooobar.com/questions/11920/...

Ответ 14

Разница между виртуальными и не виртуальными методами.

У нас есть два класса; один - это класс Vehicle, а другой - класс Cart. Класс "Автомобиль" - это базовый класс, который имеет два метода; один - это виртуальный метод "Speed ()", а другой - не виртуальный метод "Average()". Таким образом, виртуальный метод базового класса "Speed ()" переопределяется в подклассе. У нас есть еще один класс "Программа" (класс исполнения), у которого есть точка входа, где мы создаем экземпляр подкласса "Корзина", и этот экземпляр присваивается типу базового класса "Автомобиль". Когда мы вызываем виртуальные и не виртуальные методы для обоих экземпляров класса, то в соответствии с типом запуска вызывается реализация виртуального метода экземпляра; другими словами, оба экземпляра класса вызывают метод переопределения подкласса, и вызванный не виртуальный метод определяется на основе экземпляра класса.

using System;

namespace VirtualExample
{   
    class Vehicle
    {   
       public double distance=0.0;
       public double hour =0.0;
       public double fuel =0.0; 

       public Vehicle(double distance, double hour, double fuel)
       {
           this.distance = distance;
           this.hour = hour;
           this.fuel = fuel;
       }

       public void Average()
       {
           double average = 0.0;
           average = distance / fuel;
           Console.WriteLine("Vehicle Average is {0:0.00}", average);
       }

       public virtual void Speed()
       {
           double speed = 0.0;
           speed = distance / hour;
           Console.WriteLine("Vehicle Speed is {0:0.00}", speed);
       }
    } 

    class Car : Vehicle
    {
        public Car(double distance, double hour, double fuel)
            : base(distance, hour, fuel)
        {
        }
      public void Average()
        {
            double average = 0.0;
            average = distance / fuel;
            Console.WriteLine("Car Average is {0:0.00}", average);
        }

        public override void Speed()
        {
            double speed = 0.0;           
            speed = distance / hour;
            Console.WriteLine("Car Speed is {0:0.00}", speed);
        }
    } 

    class Program
   {
        static void Main(string[] args)
        {
             double distance,hour,fuel=0.0;
             Console.WriteLine("Enter the Distance");
             distance = Double.Parse(Console.ReadLine());
             Console.WriteLine("Enter the Hours");
             hour = Double.Parse(Console.ReadLine());
             Console.WriteLine("Enter the Fuel");
             fuel = Double.Parse(Console.ReadLine());
             Car objCar = new Car(distance,hour,fuel);
             Vehicle objVeh = objCar;
             objCar.Average();
             objVeh.Average();
             objCar.Speed();
             objVeh.Speed();
            Console.Read();
        }       
    }
}

enter image description here

надеюсь помочь!

Ответ 15

В С# для переопределения метода базового класса в производном классе вы должны объявить метод базового класса как метод виртуального и производного класса как переопределение, как показано ниже:

using System;
namespace Polymorphism
{
 class A
 {
 public virtual void Test() { Console.WriteLine("A::Test()"); }
 }

 class B : A
 {
 public override void Test() { Console.WriteLine("B::Test()"); }
 }

 class C : B
 {
 public override void Test() { Console.WriteLine("C::Test()"); }
 }

 class Program
 {
 static void Main(string[] args)
 {

 A a = new A();
 B b = new B();
 C c = new C();
 a.Test(); // output --> "A::Test()"
 b.Test(); // output --> "B::Test()"
 c.Test(); // output --> "C::Test()"

 a = new B();
 a.Test(); // output --> "B::Test()"

 b = new C();
 b.Test(); // output --> "C::Test()"

 Console.ReadKey();
 }
 }
}

Вы также можете смешать скрытие метода и переопределение метода, используя ключевое слово virtual и new, поскольку метод производного класса может быть виртуальным и новым одновременно. Это необходимо, когда вы хотите переопределить метод производного класса на следующий уровень, так как я переопределяю метод класса B, Test() в классе C, как показано ниже:

using System;
namespace Polymorphism
{
 class A
 {
 public void Test() { Console.WriteLine("A::Test()"); }
 }

 class B : A
 {
 public new virtual void Test() { Console.WriteLine("B::Test()"); }
 }

 class C : B
 {
 public override void Test() { Console.WriteLine("C::Test()"); }
 }

 class Program
 {
 static void Main(string[] args)
 {

 A a = new A();
 B b = new B();
 C c = new C();

 a.Test(); // output --> "A::Test()"
 b.Test(); // output --> "B::Test()"
 c.Test(); // output --> "C::Test()"

 a = new B();
 a.Test(); // output --> "A::Test()"

 b = new C();
 b.Test(); // output --> "C::Test()"

 Console.ReadKey();
 }
 }
}

ЗОЛОТЫЕ СЛОВА: виртуальное ключевое слово используется для изменения метода, свойства, индексатора или события, объявленного в базовом классе, и позволяет переопределить его в производном классе.

Ключевое слово override используется для расширения или изменения виртуального/абстрактного метода, свойства, индексатора или события базового класса в производный класс.

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

НАСЛАЖДАТЬСЯ :-)