2012-10-12 21 views
5

我已经了解到,虚拟方法的使用为方法/函数提供了默认行为。我的查询是,当我们可以在派生类中使用“new”实现一个名称相同的方法(和基类中的方法相同),并且可以分别使用对象调用它时,那么虚拟方法的用法是什么。例如;使用虚拟方法只有单实例生成的优势?

class A 
{ 
     public void F() 
     { 
     //default behavior 
     } 

     public virtual void G() 
     { 
     //default behavior 
     } 
} 

class B:A 
{ 
    new public void F() 
    { 
     //new behavior from that of class A 
    } 
    public override void G() 
    { 
     //new behavior from that of class A 
    } 
} 

class Test 
{ 
    public static void Main(string[] args) 
    { 
     //For calling A's method use same compile time and run time object 
     A obj1 = new A(); 

     //For calling B's method use compile time object of A and run time of B 
     A obj2 = new B(); 

     obj1.F(); //O/P is A's method result 
     obj2.F(); //O/P is A's method result 
     obj1.G(); //O/P is A's method result 
     obj2.G(); //O/P is B's method result 
} 

我的问题是为什么需要虚拟G()在A类时,我们可以通过使用相同的编译时对象提供默认行为以及衍生行为和运行两个类A的时间对象和B作为这样的:

A obj1 = new A(); //for calling A's methods 
B obj2 = new B(); //for calling B's methods 
A obj3 = new B(); //for having default behavior of class A using B's run time object. 

我提取的只是在虚拟情况下,我们不需要再制作一个具有相同编译和运行时类型的对象。它可以通过A类编译时间和B类运行时间的单个对象来实现。

回答

6

我的问题是为什么我们可以使用相同的方法提供默认行为时需要类A中的虚拟G()编译时间和使用编译时间目标运行时对象和派生的行为和运行B.

时间

因为这样你可以这已经知道B只有使用的代码。多态性的一半是允许您编写不关心它实际与哪个子类一起工作的代码。

例如,我可以编写一种方法,使用Stream.ReadStream.Write将一个流的内容复制到另一个流中,这正是因为它们是虚拟或抽象方法。不要紧,哪个实现通过。

你应该很少使用new作为方法修饰符 - 如果你真的想为非虚拟方法提供不同的行为,如果你创建一个完全不同的方法方法名,这样任何阅读代码的人都能理解这是一个与基类中声明的方法非常分离的方法。

+0

也许我的想法没有通过回复来解决......我无法清楚地理解它。你能否给它更逼真的感觉,谢谢你的及时答复。 – user1740176

+0

恐怕我不知道你的意思是“更逼真的接触”。 –

+0

对不起,不太清楚。我试图问:使用虚拟方法是否仅仅节省内存?那么为什么不创建更多的对象或它有不同的原因?通过逼真的触摸,我的意思是任何真实的生活例子 – user1740176

0

Jon指出另一个原因是,如果隐藏了使用new的实现,那么对基类中的方法的任何引用都是针对基本实现,而如果在基类中重写任何调用,则使用覆盖方法

protected virtual void Foo(){ 
} 

private void Bar() { 
    //do generic stuff 
    Foo(); 
} 

如果一个类重写foo,那么这将改变调用bar的效果。这是某些设计模式的基础,例如AbstractTemplate

+0

感谢您的回复符文。道歉,无法得到你的榜样。 – user1740176

相关问题