我只有一个基本问题:
public class virtualTest
{
public virtual void vTest()
{
Console.WriteLine("Base Class");
}
}
public class derivedVirtualTest : virtualTest
{
public override void vTest()
{
Console.WriteLine("Derived Class");
}
}
这里我使用函数覆盖函数vTest()
但如果我:
public class virtualTest
{
public void vTest()
{
Console.WriteLine("Base Class");
}
}
public class derivedVirtualTest : virtualTest
{
public void vTest()
{
Console.WriteLine("Derived Class");
}
}
从相应位置删除虚拟和覆盖关键字,然后代码也可以工作。
这怎么可能?
或者如果代码在没有虚拟和覆盖的情况下正常工作,那么覆盖和虚拟(整个函数覆盖)的用途是什么?
修改
我在上面调用类的方法
static void Main(string[] args)
{
derivedVirtualTest objderivedVirtualTest = new derivedVirtualTest();
objderivedVirtualTest.vTest();
virtualTest objvirtualTest = new virtualTest();
objvirtualTest.vTest();
Console.ReadLine();
}
答案 0 :(得分:5)
首先,你可以实现polimorphism。第二个你不能。
首先调用overriding
,第二个调用hidding
或shadowing (Vb.Net)
关于它的问题有很多问题。
答案 1 :(得分:3)
正如qwr所解释的那样,OOP方面的主要区别在于多态性。这意味着如果您通过基本类型引用访问覆盖基本成员的类,则对可覆盖成员执行的调用将重定向到覆盖。
如果一个类阴影/隐藏基类成员,则不会重定向调用,并且正在执行基类'方法。
所以,给定:
class Base
{
public virtual void OverrideMe()
{
Console.WriteLine("I'm the base");
}
}
class Derived : Base
{
public override void OverrideMe()
{
Console.WriteLine("I'm derived");
}
}
class Shadowing : Base
{
public void OverrideMe()
{
Console.WriteLine("I'm shadowing");
}
}
以这种方式使用它们:
var instances = new Base[] {new Base(), new Derived(), new Shadowing()};
foreach (var instance in instances)
{
instance.OverrideMe();
}
将产生:
我是基地
我是派生的
我是基地
另外一点是,在覆盖的情况下,您可以改进基类,例如更改基本成员的签名或完全删除它,而不更改隐藏的基类。在某些情况下,这可能恰好适合某些需求 - 而不是那么多。
如果覆盖,必须也会更改覆盖成员的签名,否则您的代码将无法编译。
答案 2 :(得分:1)
在第二个例子中,您可能会像这样测试您的代码:
derivedVirtualTest deviTest = new derivedVirtualTest();
deviTest.vTest(); //Result "Derived Class"
试试这个,你会发现该功能已被覆盖:
virtualTest deviTest = new derivedVirtualTest();
deviTest.vTest(); //Result "Base Class"
//This will result "Dervived class" in the first one