Csharp/CSharp Tutorial/Class/virtual

Материал из .Net Framework эксперт
Перейти к: навигация, поиск

Class inheritance with virtual method

<source lang="csharp">using System; class MainClass {

 static void Main(string[] args)
 {
   B MyB = new D();
   D MyD = new D();
   MyB.Display();
   MyD.Display();
 }

} public class B {

 public virtual void Display()
 {
   Console.WriteLine("Class B"s Display Method");
 }

} public class C: B {

 public override void Display()
 {
   Console.WriteLine("Class C"s Display Method");
 }

} public class D: C {

 public override void Display()
 {
   Console.WriteLine("Class D"s Display Method");
 }

}</source>

Class D"s Display Method
Class D"s Display Method

Define virtual function in base and its subclass

<source lang="csharp">public class Control {

   public virtual void Foo() {}

} public class MyControl: Control {

   public virtual void Foo() {}

}</source>

Demonstrate a virtual method.

<source lang="csharp">using System;

class BaseClass {

 // Create virtual method in the base class.  
 public virtual void who() { 
   Console.WriteLine("who() in BaseClass"); 
 } 

}

class Derived1 : BaseClass {

 // Override who() in a derived class. 
 public override void who() { 
   Console.WriteLine("who() in Derived1"); 
 } 

}

class Derived2 : BaseClass {

 // Override who() again in another derived class. 
 public override void who() { 
   Console.WriteLine("who() in Derived2"); 
 } 

}

class OverrideDemo {

 public static void Main() { 
   BaseClass baseOb = new BaseClass(); 
   Derived1 dOb1 = new Derived1(); 
   Derived2 dOb2 = new Derived2(); 

   BaseClass baseRef; // a base-class reference 

   baseRef = baseOb;  
   baseRef.who(); 

   baseRef = dOb1;  
   baseRef.who(); 

   baseRef = dOb2;  
   baseRef.who(); 
 } 

}</source>

who() in BaseClass
who() in Derived1
who() in Derived2

Illustrates polymorphism

<source lang="csharp">using System; public class Car {

 public string make;
 public string model;
 public Car(string make, string model)
 {
   this.make = make;
   this.model = model;
 }
 public virtual void Accelerate()
 {
   Console.WriteLine(model + " accelerating");
 }

} public class MyFirstCar : Car {

 public MyFirstCar(string make, string model) : base(make, model)
 {
 }
 public override void Accelerate()
 {
   Console.WriteLine("Pushing gas pedal of " + model);
   base.Accelerate();  
 }

} public class MySecondCar : Car {

 public MySecondCar(string make, string model) : base(make, model)
 {
 }
 public override void Accelerate()
 {
   Console.WriteLine("Twisting throttle of " + model);
   base.Accelerate(); 
 }

}

class MainClass {

 public static void Main()
 {
   MyFirstCar myCar = new MyFirstCar("Toyota", "MR2");
   myCar.Accelerate();
   MySecondCar myMySecondCar = new MySecondCar("Harley-Davidson", "V-Rod");
   myMySecondCar.Accelerate();
 }

}</source>

Pushing gas pedal of MR2
MR2 accelerating
Twisting throttle of V-Rod
V-Rod accelerating

Illustrates versioning: virtual/new

<source lang="csharp">using System; public class BaseClass {

 public string firstName;
 public string lastName;
 public BaseClass(string firstName, string lastName)
 {
   this.firstName = firstName;
   this.lastName = lastName;
 }
 public virtual void Accelerate()
 {
   Console.WriteLine("In BaseClass Accelerate() method");
   Console.WriteLine(lastName + " accelerating");
 }

} public class DerivedClass : BaseClass {

 public DerivedClass(string firstName, string lastName) : base(firstName, lastName)
 {
 }
 public new void Accelerate()
 {
   Console.WriteLine("In DerivedClass Accelerate() method");
   Console.WriteLine(lastName + " accelerating");
 }

} class MainClass {

 public static void Main()
 {
   Console.WriteLine("Creating a DerivedClass object");
   DerivedClass myDerivedClass = new DerivedClass("Toyota", "MR2");
   Console.WriteLine("Calling myDerivedClass.Accelerate()");
   myDerivedClass.Accelerate();
 }

}</source>

Creating a DerivedClass object
Calling myDerivedClass.Accelerate()
In DerivedClass Accelerate() method
MR2 accelerating

new virtual method

<source lang="csharp">class Control {

   public virtual void Foo() {}

} class MyControl: Control {

   // not an override
   public new virtual void Foo() {}

}</source>

Override virtual functions

<source lang="csharp">using System; class Employee {

   public Employee(string name, float billingRate)
   {
       this.name = name;
       this.billingRate = billingRate;
   }
   // function now virtual
   virtual public float CalculateCharge(float hours)
   {
       return(hours * billingRate);
   }
   // function now virtual
   virtual public string TypeName()
   {
       return("Employee");
   }
   
   private string name;
   protected float billingRate;

} class Manager: Employee {

   public Manager(string name, float billingRate) :
   base(name, billingRate)
   {
   }
   // overrides function in Employee
   override public float CalculateCharge(float hours)
   {
       if (hours < 1.0F)
       hours = 1.0F;        // minimum charge.
       return(hours * billingRate);
   }
   // overrides function in Employee
   override public string TypeName()
   {
       return("Civil Employee");
   }

} class Test {

   public static void Main()
   {
       Employee[]    earray = new Employee[2];
       earray[0] = new Employee("A", 15.50F);
       earray[1] = new Manager("B", 40F);
       
       Console.WriteLine("{0} charge = {1}",
       earray[0].TypeName(),
       earray[0].CalculateCharge(2F));
       Console.WriteLine("{0} charge = {1}",
       earray[1].TypeName(),
       earray[1].CalculateCharge(0.75F));
   }

}</source>

Employee charge = 31
Civil Employee charge = 40

Override virtual method

<source lang="csharp">class Control {

   public virtual void Foo() {}

} class MyControl: Control {

   // an override for Control.Foo()
   public override void Foo() {}

}</source>

Use virtual methods and polymorphism.

<source lang="csharp">using System;

class Shape {

 double pri_width;  // private 
 double pri_height; // private 
 string pri_name;   // private 
 
 public Shape() {  
   width = height = 0.0;  
   name = "null";  
 }  
 
 public Shape(double w, double h, string n) {  
   width = w;  
   height = h;  
   name = n;  
 }  
 
 public Shape(double x, string n) {  
   width = height = x;  
   name = n;  
 }  
 
 public Shape(Shape ob) {  
   width = ob.width;  
   height = ob.height;  
   name = ob.name;  
 }  
 
 // Properties for width, height, and name 
 public double width { 
   get { return pri_width; } 
   set { pri_width = value; } 
 } 

 public double height { 
   get { return pri_height; } 
   set { pri_height = value; } 
 } 

 public string name { 
   get { return pri_name; } 
   set { pri_name = value; } 
 } 
 
 public void showDim() {  
   Console.WriteLine("Width and height are " +  
                      width + " and " + height);  
 }  
 
 public virtual double area() {   
   Console.WriteLine("area() must be overridden");  
   return 0.0;  
 }   

}

class Triangle : Shape {

 string style; // private 
   
 public Triangle() {  
   style = "null";  
 }  
 
 public Triangle(string s, double w, double h) : 
   base(w, h, "triangle") {  
     style = s;   
 }  
 
 public Triangle(double x) : base(x, "triangle") {  
   style = "isosceles";   
 }  
 
 public Triangle(Triangle ob) : base(ob) {  
   style = ob.style;  
 }  
 
 // Override area() for Triangle. 
 public override double area() {  
   return width * height / 2;  
 }  
 
 // Display a triangle"s style. 
 public void showStyle() {  
   Console.WriteLine("Triangle is " + style);  
 }  

}

class Rectangle : Shape {

 public Rectangle(double w, double h) : base(w, h, "rectangle"){ }  
 
 public Rectangle(double x) : base(x, "rectangle") { }  
 
 // Construct an object from an object.  
 public Rectangle(Rectangle ob) : base(ob) { }  
 
 // Return true if the rectangle is square. 
 public bool isSquare() {   
   if(width == height) return true;   
   return false;   
 }   
 // Override area() for Rectangle. 
 public override double area() {   
   return width * height;   
 }   

}

class DynShapes {

 public static void Main() {  
   Shape[] shapes = new Shape[5];  
 
   shapes[0] = new Triangle("right", 8.0, 12.0);  
   shapes[1] = new Rectangle(10);  
   shapes[2] = new Rectangle(10, 4);  
   shapes[3] = new Triangle(7.0);  
   shapes[4] = new Shape(10, 20, "generic"); 
 
   for(int i=0; i < shapes.Length; i++) {  
     Console.WriteLine("object is " + shapes[i].name);  
     Console.WriteLine("Area is " + shapes[i].area());  
 
     Console.WriteLine();    
   }  
 }  

}</source>

object is triangle
Area is 48
object is rectangle
Area is 100
object is rectangle
Area is 40
object is triangle
Area is 24.5
object is generic
area() must be overridden
Area is 0

Virtual Accessor

<source lang="csharp">using System; public class Class1 {

   public static void Main(string[] strings) {
       MyMoney dm = new MyMoney();
       dm.CurrencyValue = 2.50M;
       Console.WriteLine(dm.CurrencyValue);
       Dollar dollar = new Dollar();
       dollar.InitDollar(1.2M);
       dollar.EuroValue = dm.EuroValue;
       Console.WriteLine(dollar.CurrencyValue);
       dollar.CurrencyValue = 2 * dollar.CurrencyValue;
       dm.EuroValue = dollar.EuroValue;
       Console.WriteLine(dm.CurrencyValue);
   }

} abstract public class Currency {

   private decimal mEuroValue = 0M; // [Euro]
   public abstract decimal CurrencyValue { get; set; }
   public decimal EuroValue {
       get {
           return mEuroValue;
       }
       set {
           mEuroValue = value;
       }
   }

} public class MyMoney : Currency {

   private static decimal mDMtoEuro = 1.96M;
   public override decimal CurrencyValue {
       get { return EuroValue * mDMtoEuro; }
       set { EuroValue = value / mDMtoEuro; }
   }

} public class Dollar : Currency {

   public decimal mDollartoEuroConversion;
   public void InitDollar(decimal mDollartoEuro) {
       mDollartoEuroConversion = mDollartoEuro;
   }
   public override decimal CurrencyValue {
       get { return EuroValue * mDollartoEuroConversion; }
       set { EuroValue = value / mDollartoEuroConversion; }
   }

}</source>

Virtual method in a multilevel hierarchy

In a multilevel hierarchy, the system executes the first override-virtual method found in the hierarchy.


<source lang="csharp">using System;

class BaseClass {

 // Create virtual method in the base class.   
 public virtual void who() {  
   Console.WriteLine("who() in BaseClass");  
 }  

}

class Derived1 : BaseClass {

 // Override who() in a derived class.  
 public override void who() {  
   Console.WriteLine("who() in Derived1");  
 }  

}

class Derived2 : Derived1 {

 // This class also does not override who().  

}

class Derived3 : Derived2 {

 // This class does not override who().  

}

class MainClass {

 public static void Main() {  
   Derived3 dOb = new Derived3();  
   BaseClass baseRef; // a base-class reference  
 
   baseRef = dOb;   
   baseRef.who(); // calls Derived1"s who()  
 }  

}</source>

who() in Derived1

Virtual Methods and Overriding

  1. A virtual method is declared as virtual in a base class.
  2. A virtual method is redefined in one or more derived classes.
  3. When redefining a virtual method in the derived class, the override modifier is used.
  4. When overriding a method, the type signature of the method cannot be changed.
  5. A virtual method cannot be static or abstract.

7.23.virtual 7.23.1. Virtual Methods and Overriding 7.23.2. <A href="/Tutorial/CSharp/0140__Class/Overridevirtualfunctions.htm">Override virtual functions</a> 7.23.3. <A href="/Tutorial/CSharp/0140__Class/newvirtualmethod.htm">new virtual method</a> 7.23.4. <A href="/Tutorial/CSharp/0140__Class/Overridevirtualmethod.htm">Override virtual method</a> 7.23.5. <A href="/Tutorial/CSharp/0140__Class/Definevirtualfunctioninbaseanditssubclass.htm">Define virtual function in base and its subclass</a> 7.23.6. <A href="/Tutorial/CSharp/0140__Class/Classinheritancewithvirtualmethod.htm">Class inheritance with virtual method</a> 7.23.7. <A href="/Tutorial/CSharp/0140__Class/Illustratesversioningvirtualnew.htm">Illustrates versioning: virtual/new</a> 7.23.8. <A href="/Tutorial/CSharp/0140__Class/Illustratespolymorphism.htm">Illustrates polymorphism</a> 7.23.9. <A href="/Tutorial/CSharp/0140__Class/Demonstrateavirtualmethod.htm">Demonstrate a virtual method.</a> 7.23.10. <A href="/Tutorial/CSharp/0140__Class/Whenavirtualmethodisnotoverriddenthebaseclassmethodisused.htm">When a virtual method is not overridden, the base class method is used</a> 7.23.11. <A href="/Tutorial/CSharp/0140__Class/Virtualmethodinamultilevelhierarchy.htm">Virtual method in a multilevel hierarchy</a> 7.23.12. <A href="/Tutorial/CSharp/0140__Class/Usevirtualmethodsandpolymorphism.htm">Use virtual methods and polymorphism.</a> 7.23.13. <A href="/Tutorial/CSharp/0140__Class/VirtualAccessor.htm">Virtual Accessor</a>

When a virtual method is not overridden, the base class method is used

<source lang="csharp">using System;

class BaseClass {

 // Create virtual method in the base class.  
 public virtual void who() { 
   Console.WriteLine("who() in BaseClass"); 
 } 

}

class Derived1 : BaseClass {

 // Override who() in a derived class. 
 public override void who() { 
   Console.WriteLine("who() in Derived1"); 
 } 

}

class Derived2 : BaseClass {

 // This class does not override who(). 

}

class MainClass {

 public static void Main() { 
   BaseClass baseOb = new BaseClass(); 
   Derived1 dOb1 = new Derived1(); 
   Derived2 dOb2 = new Derived2(); 

   BaseClass baseRef; // a base-class reference 

   baseRef = baseOb;  
   baseRef.who(); 

   baseRef = dOb1;  
   baseRef.who(); 

   baseRef = dOb2;  
   baseRef.who(); // calls BaseClass"s who() 
 } 

}</source>

who() in BaseClass
who() in Derived1
who() in BaseClass