简体   繁体   English

从基类创建继承的类

[英]Create inherited class from base class

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

When I do something like 当我做的事情

Car myCar = new Car("Porsche", "911");
SuperCar mySupcar = new SuperCar(myCar);
mySupcar.Display();

I only get "I am a supercar" but not the properties of my base class. 我只得到“我是一辆超级跑车”,但不是我基地的属性。 Should I explicitly assign the properties of my base class in the SuperCar constructor? 我应该在SuperCar构造函数中显式分配我的基类的属性吗? In fact I'm trying Decorator pattern where I want a class to add behaviour to a base class. 事实上,我正在尝试使用Decorator模式,我想要一个类向基类添加行为。

alternatively: 或者:

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){}
}

This way you can inherit any class from car, and have the car contents populate from the provided object. 这样,您可以从汽车继承任何类,并从提供的对象中填充汽车内容。 The inherited objects don't need to know anything about what to set. 继承的对象不需要知道要设置什么。 They just pass the current Car object onto the base class and it does the work. 它们只是将当前的Car对象传递给基类,它就完成了工作。

I might be coming in a little late here, but just in the event that someone finds this useful: 我可能会在这里来晚一点,但只要有人发现这个有用:

You can use reflection. 你可以使用反射。 It requires a little more code than what you proposed, but I think it still offers the brevity you're searching for. 它需要比你提出的更多的代码,但我认为它仍然提供了你正在寻找的简洁性。

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
    // .
    // .
    // .
}

I wrote this explicitly from your example to clearly illustrate the concept, but I think this would be best made a generic method that can be used in all similar instances of your solution. 我从你的例子中明确地写了这个,以清楚地说明这个概念,但我认为这最好是一个通用方法,可以在你的解决方案的所有类似实例中使用。

Hope this helps. 希望这可以帮助。

Looking at your code I am not sure how it compiles. 看看你的代码,我不确定它是如何编译的。 Your constructors are wrong because the base constructor won't know how to run a constructor that takes type car. 你的构造函数是错误的,因为基础构造函数不知道如何运行类型为car的构造函数。 It looks like you are trying to implement the decorator pattern but have not done it correctly. 看起来您正在尝试实现装饰器模式但尚未正确完成。 Really what you should have is an ICar interface that both implement and from Display() in SuperCar you should call car.Display() You'll also have to implement Make and Model on Super car and make them return car.Make & car.Model to implement the decorator pattern properly. 真正应该拥有的是一个ICar界面,它既可以实现,也可以从SuperCar Display()中调用car.Display()你还需要在超级跑车上实现Make和Model并让它们返回car.Make&car。模型正确实现装饰器模式。

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

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

yep to get this to work as you want you need to set the base constructor like below: 是的,为了让你的工作,你需要设置如下的基本构造函数:

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

You are not quite implementing the decorator pattern 你没有完全实现装饰模式

You need an abstract base class to hold the decorated car 你需要一个抽象的基类来装饰装饰的汽车

  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.");
    }
  }

Based on @JoshWheelock answer I wrote this method that I put in a shared file of my Xamarin project 根据@JoshWheelock的回答,我写了这个方法,我把它放在我的Xamarin项目的共享文件中

It clones classes, so you can use to duplicate a base classe the heiress, you could adjust the T param 它克隆了类,所以你可以使用复制基础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));
    }
}

Not yet tested in Android and iOS, concerning Android I have my emulator that soddenly stopped working properly since a week ... 尚未在Android和iOS中测试过,关于Android我有我的模拟器,自从一周以后就已经停止了正常工作......

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM