Practical usage of virtual functions in c#

爷,独闯天下 提交于 2019-12-17 08:18:13

问题


What 's the practical usage of virtual functions in c#?


回答1:


So basically if in your ancestor class you want a certain behaviour for a method. If your descendent uses the same method but has a different implementation you can override it, If it has a virtual keyword.

using System;
class TestClass 
{
   public class Dimensions 
   {
      public const double pi = Math.PI;
      protected double x, y;
      public Dimensions() 
      {
      }
      public Dimensions (double x, double y) 
      {
         this.x = x;
         this.y = y;
      }

      public virtual double Area() 
      {
         return x*y;
      }
   }

   public class Circle: Dimensions 
   {
      public Circle(double r): base(r, 0) 
      {
      }

      public override double Area() 
      { 
         return pi * x * x; 
      }
   }

   class Sphere: Dimensions 
   {
      public Sphere(double r): base(r, 0) 
      {
      }

      public override double Area()
      {
         return 4 * pi * x * x; 
      }
   }

   class Cylinder: Dimensions 
   {
      public Cylinder(double r, double h): base(r, h) 
      {
      }

      public override double Area() 
      {
         return 2*pi*x*x + 2*pi*x*y; 
      }
   }

   public static void Main()  
   {
      double r = 3.0, h = 5.0;
      Dimensions c = new Circle(r);
      Dimensions s = new Sphere(r);
      Dimensions l = new Cylinder(r, h);
      // Display results:
      Console.WriteLine("Area of Circle   = {0:F2}", c.Area());
      Console.WriteLine("Area of Sphere   = {0:F2}", s.Area());
      Console.WriteLine("Area of Cylinder = {0:F2}", l.Area());
   }
}

Edit: Questions in comment
If I don't use virtual keyword in base class, will it work?

If you use the override keyword in your descendent classes it will not work. You will generate compiler error CS0506 'function1' : cannot override inherited member 'function2' because it is not marked "virtual", "abstract", or "override"

If you don't use the override You'll get the CS0108 warning 'desc.Method()' hides inherited member 'base.Method()' Use the new keyword if hiding was intended.

To get around this put the new keyword in front of the method you are hiding.

e.g.

  new public double Area() 
  {
     return 2*pi*x*x + 2*pi*x*y; 
  }

..and is it compulsory to override a virtual method in derived class?
No, if you don't override the method, the descendent class will use method it is inheriting from.




回答2:


The key to understanding the practical usage of virtual functions is to keep in mind that an object of a certain class can be assigned another object of a class derived from the first object's class.

E.g.:

class Animal {
   public void eat() {...}
}

class FlyingAnimal : Animal {
   public void eat() {...}
}

Animal a = new FlyingAnimal();

The Animal class has a function eat() that generally describes how an animal should eat (e.g. put the object in mouth and swallow).

However, the FlyingAnimal class should define a new eat() method, because flying animals have a particular way of eating.

So the question that comes to mind here is: after I declared the variable a of type Animal and asigned it a new object of type FlyingAnimal, what will a.eat() do? Which of the two methods is called?

The answer here is: because a is of type Animal, it will call Animal's method. The compiler is dumb and doesn't know that you are going to assign an object of another class to the a variable.

Here is where the virtual keyword comes in action: if you declare the method as virtual void eat() {...}, you are basically telling the compiler "be careful that I am doing some clever stuff here that you cannot handle because you're not as smart". So the compiler will not attempt to link the call a.eat() to either of the two methods, but instead it tells the system to do it at runtime!

So only when the code executes, the system will look at a's content type not at its declared type and executes FlyingAnimal's method.

You may wonder: why the hell would I want to do that? Why not say right from the start FlyingAnimal a = new FlyingAnimal() ?

The reason for that is that, for example, you may have many derived classes from Animal: FlyingAnimal, SwimmingAnimal, BigAnimal, WhiteDog etc. And at one point you want to define a world containing many Animals, so you say:

Animal[] happy_friends = new Animal[100];

We have a world with 100 happy animals. You initialize them at some point:

...
happy_friends[2] = new AngryFish();
...
happy_friends[10] = new LoudSnake();
...

And at the end of the day, you want everybody to eat before they go to sleep. So you want to say:

for (int i=0; i<100; i++) {
   happy_friends[i].eat();
}

So as you can see, each animal has its own method of eating. Only by using virtual functions can you achieve this functionality. Otherwise, everyone would be forced to "eat" in the exact same way: as described in the most general eat function inside the Animal class.

EDIT: This behavior is actually default in common high-level languages like Java.




回答3:


Like any other language..when you want polymorphism. There are tons of usage for this. For example you want to abstract the way input is read from a console or a file or some other device. You can have a generic reader interface followed by multiple concrete implementations using virtual functions.




回答4:


e.g. proxying methods. i.e. overwriting methods at runtime. For example, NHibernate uses this to support lazy loading.




回答5:


This allows to achieve late binding, meaning to determine at runtime rather than at compile-time which object's member will be invoked. See Wikipedia.




回答6:


Basically virtual members allow you to express polymorphism, a derived class can have a method with the same signature as the method in its base class, and the base class will call the derived class's method.

A basic example:

public class Shape
{
    // A few example members
    public int X { get; private set; }
    public int Y { get; private set; }
    public int Height { get; set; }
    public int Width { get; set; }

    // Virtual method
    public virtual void Draw()
    {
        Console.WriteLine("Performing base class drawing tasks");
    }
}

class Circle : Shape
{
    public override void Draw()
    {
        // Code to draw a circle...
        Console.WriteLine("Drawing a circle");
        base.Draw();
    }
}
class Rectangle : Shape
{
    public override void Draw()
    {
        // Code to draw a rectangle...
        Console.WriteLine("Drawing a rectangle");
        base.Draw();
    }
}
class Triangle : Shape
{
    public override void Draw()
    {
        // Code to draw a triangle...
        Console.WriteLine("Drawing a triangle");
        base.Draw();
    }
}



回答7:


From here:

In object-oriented programming, a virtual function or virtual method is a function or method whose behavior can be overridden within an inheriting class by a function with the same signature.




回答8:


For example you have a base class Params and a set of derived classes. You want to be able to perform the same operation on an array that stores all possible classes derived from params.

No problem - declare the method virtual, add some basic implementation to Params class and override it in derived classes. Now you can just traverse the array and call the method through the reference - the correct method will be called.

class Params {
public:
   virtual void Manipulate() { //basic impl here }
}

class DerivedParams1 : public Params {
public:
   override void Manipulate() {
      base.Manipulate();
      // other statements here
   }
};

// more derived classes can do the same

void ManipulateAll( Params[] params )
{
    for( int i = 0; i < params.Length; i++ ) {
       params[i].Manipulate();
    }
 }



回答9:


Use of virtual functions in c#

Virtual functions are mostly used to override the base class method in the derived class with the same signature.

When a derived class inherits the base class, the object of derived class is a reference to either the derived class or the base class.

Virtual functions are resolved late by the compiler(i.e run-time binding)

virtual in the base class, the most-derived class's implementation of the function is called according to the actual type of the object referred to, regardless of the declared type of the pointer or reference. If it is not virtual, the method is resolved early and the function called is selected according to the declared type of the pointer or reference.



来源:https://stackoverflow.com/questions/1062102/practical-usage-of-virtual-functions-in-c-sharp

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!