从基类创建继承类
Posted
技术标签:
【中文标题】从基类创建继承类【英文标题】:Create inherited class from base class 【发布时间】:2011-02-21 23:25:28 【问题描述】: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
getreturn make;
setmake = value;
public string Model
getreturn model;
setmodel = value;
public class SuperCar:Car
private Car car;
private int horsePower;
public SuperCar(Car car)
this.car = car;
public int HorsePower
getreturn horsePower;
sethorsepower = 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 构造函数中明确分配我的基类的属性吗?事实上,我正在尝试装饰器模式,我希望一个类向基类添加行为。
【问题讨论】:
为了让 Supercar 成为真正的装饰者,请将 Car 的所有方法委托给您的包裹汽车。如果 Decorator 是正确的模式,这是值得怀疑的,尤其是当您处理具体的类时。 假设您将 Car 重命名为 Container 并将 SuperCar 重命名为 Box。你说“盒子是一种容器(因为它继承自容器),每个盒子都包含一个容器(因为它在其构造函数中接受一个容器并将其保存在一个字段中)”。这真的是你想要建模的吗?为什么一个盒子应该包含一个容器?为什么 SuperCar 既包含 Car 又是 Car 的一种? 【参考方案1】:或者:
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 继承任何类,并从提供的对象中填充 car 内容。继承的对象不需要知道要设置什么。他们只是将当前的 Car 对象传递给基类,它就完成了工作。
【讨论】:
【参考方案2】:我可能来晚了一点,但万一有人觉得这很有用:
您可以使用反射。它需要的代码比您建议的多一点,但我认为它仍然提供您正在搜索的简洁性。
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
// .
// .
// .
我从您的示例中明确地写了这个来清楚地说明这个概念,但我认为这最好是一种通用方法,可以在您的解决方案的所有类似实例中使用。
希望这会有所帮助。
【讨论】:
【参考方案3】:查看您的代码,我不确定它是如何编译的。您的构造函数是错误的,因为基本构造函数不知道如何运行采用 car 类型的构造函数。看起来您正在尝试实现装饰器模式,但没有正确完成。真正你应该拥有的是一个ICar
接口,它既可以实现,又可以从SuperCar
中的Display()
调用car.Display()
你还必须在超级汽车上实现Make 和Model 并让它们返回car.Make & 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
getreturn make;
setmake = value;
public string Model
getreturn model;
setmodel = value;
public class SuperCar:ICar
private ICar car;
private int horsePower;
public SuperCar(ICar car)
this.car = car;
public string Make
getreturn car.Make;
setcar.Make = value;
public string Model
getreturn car.Model;
setcar.Model = value;
public int HorsePower
getreturn horsePower;
sethorsepower = value;
public override void Display()
car.Display();
Console.WriteLine("I am a super car");
【讨论】:
我接受了凯文的回答,因为在我的情况下,我没有接口,我想向现有类添加额外的行为。但是,我感谢您对装饰器模式的完整解释。 是否使用装饰器模式是一个问题。真的,听起来您不想要装饰器模式,因为您只想扩展汽车(这就是继承的用途)而不是包装它并改变它的工作方式,在这种情况下,Kevin's 是正确的解决方案。【参考方案4】:你没有完全实现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.");
【讨论】:
但是我可以将 SuperCar 对象分配给 Car 对象,例如将 SuperCar 添加到 List将私有属性更改为受保护的属性,除了创建它们的类之外,任何人都无法访问私有属性,而继承的类可以访问受保护的变量。
【讨论】:
这是否意味着我必须从用于创建 SuperCar 对象的 Car 对象属性中显式分配受保护的变量?【参考方案6】:是的,要让它按照你的意愿工作,你需要设置基本构造函数,如下所示:
public SuperCar(Car car):base(car.make,car.model)
this.car = car;
【讨论】:
【参考方案7】:基于@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,我的模拟器一周后就彻底停止了正常工作......
【讨论】:
以上是关于从基类创建继承类的主要内容,如果未能解决你的问题,请参考以下文章
错误:与 'operator=' 不匹配。试图从基类继承并从基类初始化?