我最近一直在研究类继承,并且我不断遇到这段特定的代码。
public class Foo {
public bool DoSomething()
{
return false;
}
}
public class Bar : Foo {
public new bool DoSomething()
{
return true;
}
}
public cass Test {
public static void Main () {
Foo test = new Bar ();
Console.WriteLine (test.DoSomething ());
}
}
让我感到困惑的是,如果是我,我会按类型Bar创建一个Bar实例...
Bar test = new Bar();
我不明白为什么它会像在代码中那样被创建。
答案 0 :(得分:3)
此代码可能是为了演示覆盖和隐藏基类方法之间的区别而编写的:
在这种情况下,使用Bar
变量实例化Foo
对象将使用基类方法DoSomething()
并打印出false
。如果DoSomething
方法在基类中被声明为虚拟并在派生类中被覆盖,则输出将为true
,如以下示例所示:
public class Foo {
public virtual bool DoSomething()
{
return false;
}
}
public class Bar : Foo {
public override bool DoSomething()
{
return true;
}
}
答案 1 :(得分:1)
在现实世界的物体中思考这些东西会更容易。
试着想一辆车。您可以拥有不同品牌/型号的汽车,但每辆汽车都具有相同的基本功能。
您的代码可以以相同的方式处理对象。您编写的代码可以与任何汽车一起使用,但您可以真正指定您想要的任何汽车品牌/型号:
public class Car
{
public virtual void Drive()
{
}
}
public class ChevyVolt : Car
{
public override void Drive()
{
// Initialize the battery and go
}
}
public class CadillacEscalade : Car
{
public override void Drive()
{
// Check to ensure you have an oil field worth of gas and go
}
}
现在,有了这些定义......你可以创建一个负责驾驶汽车的班级。什么车都没关系。你只需要担心驾驶:
public class Commuter
{
public void GoToWork()
{
// Garage.PickCar() could return either ChevyVolt or an Escalade
Car todaysRide = Garage.PickCar();
// Now that we have a car, go to work
todaysRide.Drive();
}
}
答案 2 :(得分:0)
一般情况下,它不会。一个更现实的例子是
void DoSomethingWithAFoo(Foo f) {
f.DoSomething();
}
在这种情况下,f
可以是Foo
或Bar
,而DoSomethingWithAFoo
则无需了解或关注。
答案 3 :(得分:0)
Bar
派生自Foo
,因此创建Bar
的实例并分配给Foo
- 引用完全有效。我怀疑您显示的示例代码仅显示Bar
是Foo
,因此可以分配。
答案 4 :(得分:0)
您可以使用不太通用的类型(Boo)分配更通用的(Foo),这通常在您利用多态时完成。经典的例子是拥有Animal,Dod和Cat然后你可以说Animal=new Dog()
或Animal=new Cat()
,然后你可以调用它上面的虚函数并自动调用正确的函数。这不是你的情况,因为你将函数DoSomething与new ...
答案 5 :(得分:0)
如果您认为它只需要Foo
所实现的Bar
定义的功能,那么它可能更有意义。 Bar
可以免费添加与Bar
相关的更多功能。
public class Bar : Foo {
public new bool DoSomething()
{
return true;
}
public bool IsValid {get;}
}
现在调用代码只关心Foo
定义的抽象,所以,尽管你创建了Bar
,但只获得{{1}定义的契约(仅Foo
),因此不是我刚定义的DoSomething
功能。