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

本文关键字:类型 对象 派生类 派生 创建 | 更新日期: 2023-09-27 18:17:34

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

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

我不明白为什么它会以代码中的方式创建

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

这段代码可能是为了演示覆盖隐藏基类方法之间的区别:

在这种情况下,使用Foo变量实例化Bar对象将使用基类方法DoSomething()并打印出false。如果在基类中将DoSomething方法声明为虚方法,并在派生类中重写,则输出将是true,如下例所示:

public class Foo {      
 public virtual bool DoSomething() 
 { 
   return false; 
 } 
}  
public class Bar : Foo { 
 public override bool DoSomething() 
 { 
   return true; 
 } 
} 

用现实世界中的对象来考虑这些事情比较容易。

试着想象一辆车。你可以有不同的品牌/型号的汽车,但每辆车执行相同的基本功能。

你的代码可以用同样的方式处理对象。您编写的代码可以处理任何汽车,但实际上您可以指定任何您想要的汽车的品牌/型号:

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

一般来说,它不会。更实际的例子是

void DoSomethingWithAFoo(Foo f) {
    f.DoSomething();
}

在这种情况下,f可以是FooBar, DoSomethingWithAFoo不需要知道或关心。

Bar派生自Foo,因此创建Bar的实例并将其分配给一个Foo引用是完全有效的。我怀疑您所展示的示例代码只是显示BarFoo,因此是可分配的。

您可以用一个不那么泛型的类型(Boo)分配一个更泛型的(Foo),这通常是在您利用多态性时完成的。经典的例子是有动物,Dod和Cat,然后你可以说Animal=new Dog()Animal=new Cat(),然后你可以在上面调用虚函数,并自动调用适当的函数。这不是你的情况,因为你重叠的功能DoSomething与new…

如果您认为它只需要Bar实现的Foo定义的功能,那么它可能更有意义。Bar可以自由地添加与Bar相关的更多功能。

public class Bar : Foo { 
 public new bool DoSomething() 
 { 
   return true; 
 } 
 public bool IsValid {get;}
}  

现在调用代码只关心由Foo定义的抽象,因此,尽管您正在创建Bar,但您获得由Foo(仅DoSomething)定义的合约,因此不是我刚刚定义的Bar.IsValid功能。