从基类创建继承的类

时间:2010-05-20 16:20:34

标签: c# design-patterns inheritance decorator

public class Car 
{ 
    private string make;
    private string model;
    public Car(string make, string model)
    {
         this.make = make;
         this.model = model;
    }
    public virtual void Display()
    {
       Console.WriteLine("Make: {0}", make);
       Console.WriteLine("Model: {0}", model);
    }
    public string Make
    {
       get{return make;}
       set{make = value;}
    }
    public string Model
    {
       get{return model;}
       set{model = value;}
    }
}

public class SuperCar:Car
{
    private Car car;
    private int horsePower;
    public SuperCar(Car car)
    {
        this.car = car;
    }
    public int HorsePower
    {
       get{return horsePower;}
       set{horsepower = value;}
    }
    public override void Display()
    {
       base.Display();
       Console.WriteLine("I am a super car");
}

当我做

之类的事情时
Car myCar = new Car("Porsche", "911");
SuperCar mySupcar = new SuperCar(myCar);
mySupcar.Display();

我只得到“我是超级跑车”,但不是我的基类属性。我应该在SuperCar构造函数中显式分配我的基类的属性吗?事实上,我正在尝试使用Decorator模式,我想要一个类向基类添加行为。

7 个答案:

答案 0 :(得分:8)

或者:

public class Car
{
    public Car(string make, string model)
    {
         this.make = make;
         this.model = model;
    }


    public Car (Car car):this(car.Make, Car.Model){}
}

public class SuperCar : Car
{
  SuperCar(Car car): base(car){}
}

通过这种方式,您可以从汽车继承任何类,并从提供的对象中填充汽车内容。继承的对象不需要知道要设置什么。它们只是将当前的Car对象传递给基类,它就能完成工作。

答案 1 :(得分:5)

我可能会在这里来晚一点,但是如果有人发现这个有用的话:

您可以使用反射。它需要的代码多于你提出的代码,但我认为它仍然提供了你正在寻找的简洁。

public SuperCar(Car car)
{
    var props = typeof(Car).GetProperties().Where(p => !p.GetIndexParameters().Any());
    foreach (var prop in props)
    {
        if (prop.CanWrite)
            prop.SetValue(this, prop.GetValue(car));
    }

    // Set SuperCarcentric properties
    // .
    // .
    // .
}

我从你的例子中明确地写了这个,以清楚地说明这个概念,但我认为这最好是一个通用方法,可以在你的解决方案的所有类似实例中使用。

希望这有帮助。

答案 2 :(得分:1)

查看您的代码我不确定它是如何编译的。你的构造函数是错误的,因为基础构造函数不知道如何运行类型为car的构造函数。看起来您正在尝试实现装饰器模式但尚未正确完成。您应该拥有的ICar界面实际上是Display()SuperCar car.Display()你应该调用public interface ICar { string Make {get; set;} string Model {get; set;} void Display(); } public class Car :ICar { private string make; private string model; public Car(string make, string model) { this.make = make; this.model = model; } public virtual void Display() { Console.WriteLine("Make: {0}", make); Console.WriteLine("Model: {0}", model); } public string Make { get{return make;} set{make = value;} } public string Model { get{return model;} set{model = value;} } } public class SuperCar:ICar { private ICar car; private int horsePower; public SuperCar(ICar car) { this.car = car; } public string Make { get{return car.Make;} set{car.Make = value;} } public string Model { get{return car.Model;} set{car.Model = value;} } public int HorsePower { get{return horsePower;} set{horsepower = value;} } public override void Display() { car.Display(); Console.WriteLine("I am a super car"); } 你还需要在超级跑车上实施制造和模型并让他们返回汽车。制造& car.Model正确实现装饰模式。

{{1}}

答案 3 :(得分:0)

将私有属性更改为受保护的属性,除了创建它们的类之外,任何人都无法访问private,而受保护的变量可以由继承的类访问。

答案 4 :(得分:0)

是的,要让这个工作,你需要设置如下的基本构造函数:

public SuperCar(Car car):base(car.make,car.model)
{
  this.car = car;
}

答案 5 :(得分:0)

您还没有完全实现decorator pattern

你需要一个抽象的基类来装饰装饰的汽车

  public abstract class CarDecorator
  {
    protected Car DecoratedCar { get; private set; }

    protected CarDecorator(Car decoratedCar)
    {
      DecoratedCar = decoratedCar;
    }
  }

  public class SuperCar : CarDecorator
  {
    public SuperCar(Car car)
      : base(car)
    {
    }
    public int HorsePower
    {
      get { return horsePower; }
      set { horsepower = value; }
    }
    public override void Display()
    {
      DecoratedCar.Display()
      Console.WriteLine("Plus I'm a super car.");
    }
  }

答案 6 :(得分:0)

基于@JoshWheelock回答我写了这个方法,我把它放在我的Xamarin项目的共享文件中

它克隆类,所以你可以用来复制女继承人的基础classe,你可以调整 T param

//...
#if WINDOWS_UWP
using System.Reflection;
#endif
//...

public void CloneIn<T>(T src, T dest)
{
#if WINDOWS_UWP
    var props = typeof(T).GetTypeInfo().DeclaredProperties.Where(p => !p.GetIndexParameters().Any());
#else
    var props = typeof(T).GetProperties().Where(p => !p.GetIndexParameters().Any());
#endif
    foreach (var prop in props)
    {
        if(prop.SetMethod!=null)
            prop.SetValue(dest, prop.GetValue(src));
    }
}

尚未在Android和iOS中测试过,关于Android我的模拟器自从一周以后就已经停止正常工作......