Создать унаследованный класс из базового класса - PullRequest
5 голосов
/ 20 мая 2010
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 ]

8 голосов
/ 20 мая 2010

альтернативно:

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 в базовый класс, и он выполняет свою работу.

5 голосов
/ 15 июня 2014

Я мог бы прийти сюда немного поздно, но только в том случае, если кто-то сочтет это полезным:

Вы можете использовать рефлексию.Требуется немного больше кода, чем вы предлагали, но я думаю, что он все еще предлагает краткость, которую вы ищете.

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

Я написал это явно из вашего примера, чтобы ясно проиллюстрировать концепцию, но я думаю,Лучше всего сделать общий метод, который можно использовать во всех подобных случаях вашего решения.

Надеюсь, это поможет.

1 голос
/ 20 мая 2010

Глядя на ваш код, я не уверен, как он компилируется.Ваши конструкторы не правы, потому что базовый конструктор не будет знать, как запустить конструктор, который принимает тип car.Похоже, вы пытаетесь реализовать шаблон декоратора, но не сделали это правильно.На самом деле у вас должен быть ICar интерфейс, который реализует и из Display() в SuperCar вы должны позвонить car.Display() Вам также нужно будет реализовать Make и Model на Super car и заставить их вернуть автомобиль.car.Model для правильной реализации шаблона декоратора.

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");
}
0 голосов
/ 13 ноября 2017

На основе ответа @JoshWheelock я написал этот метод, который я поместил в общий файл моего проекта Xamarin

Он клонирует классы, поэтому вы можете использовать для дублирования базового класса наследницу, вы можете настроить T параметр

//...
#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 У меня есть эмулятор, который через неделю перестал нормально работать ...

0 голосов
/ 20 мая 2010

Вы не совсем реализуете шаблон декоратора

Вам нужен абстрактный базовый класс, чтобы держать украшенную машину

  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.");
    }
  }
0 голосов
/ 20 мая 2010

Да, чтобы заставить это работать так, как вам нужно, вам нужно установить базовый конструктор, как показано ниже:

public SuperCar(Car car):base(car.make,car.model)
{
  this.car = car;
}
0 голосов
/ 20 мая 2010

Измените закрытые свойства на защищенные, частные не доступны никому, кроме создавшего их класса, а защищенные переменные могут быть доступны унаследованным классам.

...