C# 关于继承和OOPC的问题#

C# 关于继承和OOPC的问题#,c#,oop,C#,Oop,我有一个持久对象,为了这个问题,我将使用car类 public class Car { public string model {get;set} public int year {get;set} } 显然,它被大大简化了 现在,随着代码的开发,我自然地创建了一个函数,它接受CAR作为参数。例如: public void PaintCar (Car theCar) { //Does some work } 到目前为止还不错,但我有一个场景,我需要另一个类,它非常类似于CAR

我有一个持久对象,为了这个问题,我将使用car类

public class Car
{
   public string model {get;set}
   public int year {get;set}
}
显然,它被大大简化了

现在,随着代码的开发,我自然地创建了一个函数,它接受CAR作为参数。例如:

public void PaintCar (Car theCar)
{
  //Does some work
}
到目前为止还不错,但我有一个场景,我需要另一个类,它非常类似于CAR,但CAR缺少一些字段。没问题,我想,为了营救,我将从车上继承下来,最终得到:

public class SuperCar : Car
{
   public string newProp {get;set}
   // and some more properties
}
再一次,一切看起来都很美好,直到我遇到了一个非常有用的实用函数,我用它来填充汽车的原始属性

Public void SetCarProperties(Car theCar)
{
    //sets the properties for car here
}
我想,嗯,我希望我可以使用相同的函数来设置我的超级跑车类的属性,而不需要重写。我也不想更改基本汽车定义,以包括超级汽车类的所有属性

在这一点上,我陷入了两难境地。覆盖将起作用,但这是额外的工作。有更优雅的解决方案吗。基本上,我希望将超类传递给一个需要基类的函数。使用c#是否可以实现这一点

我的最终代码结果如下:

Car myCar = new Car(); 
SetCarProperties(myCar); // ALL GOOD

SuperCar mySuperCar = new SuperCar(); 
SetCarProperties(mySuperCar); // at the moment this function is expecting type Car...

更优雅的解决方案是将函数
setcarproperty
放在
Car
类上,并在
SuperCar
中重写它,以使用
base
填充
Car
的属性,并使用一些附加代码填充
SuperCar
属性


编辑:也称为多态性。

引入覆盖,但让原始调用基类版本来设置公共属性:

public void SetCarProperties(Car car)
{
    // set general properties
}

public void SetCarProperties(SuperCar veyron)
{
    this.SetCarProperties((Car) veyron);

    // SuperCar specific properties
}

超级跑车sCar=作为超级跑车的汽车; if(sCar!=null) { 设置scar的属性; }


设置汽车的属性

您应该在Car类中使用protected virtual创建一个方法。因此,每个想要设置自己属性的子类都可以从该函数内部执行此操作。因此,您的代码可以如下所示:

   public class Car
   {
      public string model {get;set}
      public int year {get;set}

      public void SetCarProperties(Car theCar)
      {
          //sets the properties for car here
         ….
        //at the end:
          SetExtraProperties();
       }

      protected virtual void SetExtraProperties()
      {
      }

  }
在任何想要设置自己属性的子类中,它必须将该方法重写为 如下:


我认为在
Car
类中使用此
SetCarProperties
方法更合适,并在子类
SuperCar
中重写它。如果不这样做,我认为重写将是一个最干净的解决方案。否则称为非常优雅的解决方案。非常感谢。你甚至可以更进一步。就像汽车不是自己造的,而是在工厂里造的一样,也许多态建筑行为也可以用同样的方式表达。比如,找一个更具衍生性的建筑商,而不是使用一个更具衍生性的汽车的方法。安东尼·佩格拉姆的建议被称为工厂模式——你可以仔细阅读。但是,它有引入两个并行继承层次结构的缺点。类型检查可能会变得无法维护。每次添加新的派生car时,都必须使用此方法并对其进行更新。您已经将层次结构颠倒过来,
car
是这里的基类,它的方法应该第二个调用。更重要的是,这不是多态的,所以如果你有一辆
SuperCar
作为
Car
公开(一旦这个片段被修复*),它将编译为使用派生较少的方法,并完全跳过派生较多的类的方法。@Anthony Pegram:谢谢,修复了。我想我是被“Super”这个词甩了。事实上,这是一个不幸的用法,特别是如果你来自不同的背景(如Java)。@Mark H:谢谢,但是
base
不起作用,因为这是一个类外的过程。我加入了必要的演员阵容。进一步的证据表明,这些东西都应该分流到汽车和超级跑车本身。
    public class SuperCar : Car
     {
      public string newProp {get;set}
       // and some more properties
      protected override void SetExtraProperties()
       {
       this.newProp = "";
        …
       }

     }