创建“派生类”类型的对象

时间:2011-12-09 16:41:34

标签: c# inheritance derived-class

我最近一直在研究类继承,并且我不断遇到这段特定的代码。

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();

我不明白为什么它会像在代码中那样被创建。

6 个答案:

答案 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可以是FooBar,而DoSomethingWithAFoo则无需了解或关注。

答案 3 :(得分:0)

Bar派生自Foo,因此创建Bar的实例并分配给Foo - 引用完全有效。我怀疑您显示的示例代码仅显示BarFoo,因此可以分配。

答案 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功能。