我真的不明白 - 我什么时候应该使用虚拟功能?如果有人能向我解释,我会很高兴,谢谢。
答案 0 :(得分:13)
虚拟方法是polymorphism的关键。标记为虚拟的方法可以在派生类中重写,以更改或专门化类的行为。
示例:
class Base
{
public virtual void SayHello()
{
Console.WriteLine("Hello from Base");
}
}
class Derived : Base
{
public override void SayHello()
{
Console.WriteLine("Hello from Derived");
}
}
static void Main()
{
Base x = new Base();
x.SayHello(); // Prints "Hello from Base"
x = new Derived();
x.SayHello(); // Prints "Hello from Derived"
}
请注意,您可以重新声明(不覆盖)非虚拟方法,但在这种情况下,它不会参与多态:
class Base
{
public void SayHello() // Not virtual
{
Console.WriteLine("Hello from Base");
}
}
class Derived : Base
{
public new void SayHello() // Hides method from base class
{
Console.WriteLine("Hello from Derived");
}
}
static void Main()
{
Base x = new Base();
x.SayHello(); // Prints "Hello from Base"
x = new Derived();
x.SayHello(); // Still prints "Hello from Base" because x is declared as Base
Derived y = new Derived();
y.SayHello(); // Prints "Hello from Derived" because y is declared as Derived
}
答案 1 :(得分:1)
虚函数是子类可以覆盖的函数
//在父母
中 public virtual string someMethod()
{
return "someting";
}
//在孩子身上
public override string someMethod()
{
return "someting else";
}
答案 2 :(得分:1)
通过一个例子可能最容易理解所以想象我们有如下代码
class Base{
public virtual string VirtualMethod(){
return "base virtual";
}
public string NotVirtual(){
return "base non virtual";
}
}
class Derived : Base{
public override string VirtualMethod(){
return "Derived overriden";
}
public new string NotVirtual(){
return "new method defined in derived";
}
}
}
如果您使用以下代码
Base b = new Base();
Derived d = new Derived();
Base b2 = d;
Console.WriteLine(b.VirtualMethod());
Console.WriteLine(d.VirtualMethod());
Console.WriteLine(b2.VirtualMethod());
Console.WriteLine(b.NotVirtual());
Console.WriteLine(d.NotVirtual());
Console.WriteLine(b2.NotVirtual());
值得注意的是b2和d是完全相同的对象!
上述结果将是:
基础虚拟
派生覆盖
派生覆盖
基础非虚拟
在派生
中定义的新方法基础非虚拟
尽管最后两行在同一对象上调用方法名称NotVirtual。因为te变量声明为Base和Derived,并且方法不是虚拟的,所以声明的变量类型确定调用的方法,而如果方法是虚拟的,则对象的运行时类型是将被调用的方法的决定因素
答案 3 :(得分:0)
如果您希望更改(覆盖)子类中函数的行为,则使用虚函数。
class Order
{
public virtual long GetOrderNumber { return nextOrderNumber; }
}
class ExpressOrder : Order
{
public override long GetOrderNumber { return nextOrderNumber + 1000000; }
}
答案 4 :(得分:0)
如果您已设置继承链,并且希望覆盖派生类中基类中定义的函数的默认实现,则只需要虚函数。
经典的例子如下:
public class Animal
{
public virtual void Speak()
{
Console.WriteLine("...");
}
}
public class Dog : Animal
{
public override void Speak()
{
Console.WriteLine("Bow-wow");
}
}
public class Human : Animal
{
public override void Speak()
{
Console.WriteLine("Hello, how are you?");
}
}
Dog
和Human
类都继承自基类Animal
类,因为它们都是动物类型。但它们都以非常不同的方式说话,所以他们需要覆盖Speak
函数来提供自己独特的实现。
在某些情况下,在设计自己的类时使用相同的模式会很有用,因为这会启用polymorphism,这实际上是不同的类共享一个公共接口,并且可以通过代码进行类似处理。 / p>
但我会回应其他人在评论中提出的建议:正确学习面向对象的编程并不是你可以通过询问一些Stack Overflow问题来做的事情。这是一个复杂的话题,值得投入时间作为开发人员学习。我强烈建议你选择一本关于面向对象编程的书(特别是一本为C#语言编写的),并通过这些例子。如果使用得当,OOP是一个非常强大的工具,但如果设计得很差,肯定会成为一个障碍!
答案 5 :(得分:0)
给定基类:
class SomeBaseClass()
{
public virtual string GetName()
{
return "SomeBaseClass";
}
}
当你覆盖它时,你继承了函数
class SomeDerivedClass() : SomeBaseClass
{
}
所以当你说:
SomeDerivedClass sdc = new SomeDerivedClass();
Console.WriteLine(sdc.GetName()); //outputs "SomeBaseClass"
GetName()
返回“SomeBaseClass”
但是,您可以override
。
class SomeDerivedClass()
{
public override string GetName()
{
return "SomeDerivedClass";
}
}
此处GetName()
现在将返回“SomeDerivedClass”
答案 6 :(得分:-1)
public abstract class Weapon
{
public virtual abstract FireOnTarget();
}
public class Pistol : Weapon
{
public override FireOnTarget()
{
LoadPowder();
LoadBullet();
CockIt();
PullTheTrigger();
}
}
public class SucideBomber : Weapon
{
public override FireOnTarget()
{
BuyTruck();
LoadWithC4();
DriveToTarget();
ActivateDetonator();
}
}
好了,现在你有两个班级。关键是在不知道实际类是什么的情况下引用虚函数,例如:
public void PerformFiring(Weapon W)
{
// do stuff
W.FireOnTarget();
// do more stuff
}
此方法将使用您从Weapon派生的任何对象,并在该对象上调用FireOnTarget。例如:
Pistol p=new Pistol();
PerformFiring(p);