如何为多级组合设计继承类
How to design inheritance for multilevel composition classes
我必须解决一个非常棘手的问题,我会尽力解释这个问题。我有一个复杂的对象,它有两个级别的组合,不知何故我应该为低级别的组合定义两个 classes 并反映更高级别的新类型。为了体现low composition的变化,我在higher levels中也定义了两个classes。
我正在使用抽象工厂方法来创建更高级别 classes 的实例。所有 class 都是可序列化的。
下图中的C 对应高级别classes,A 对应低级别classes。 A classes 的对象由级别 2 classes 的对象组成,它们由 C classes 的对象组成。
在抽象工厂方法中,我试图反序列化对象 return 作为父对象 class。我收到与铸造相关的错误。但是,我认为设计中存在一些我无法弄清楚的基本问题。我知道父对象不能转换为子对象。
public class A {
public virtual Double [] Prop1 { get; set; }
public virtual Double [] Prop2 { get; set; }
}
public class A1 : A {
public override double[ ] Prop1 {
get {
// implementation other than base class
}
set {
// implementation other than base class
}
}
}
public class A2 : A {
public override double[ ] Prop2 {
get {
// implementation other than base class
}
set {
// implementation other than base class
}
}
}
public class B {
public virtual A A_obj { get; set; }
}
public class B1 : B {
public override A A_obj {
get {
// want to retun the object of A1
}
set {
// want to handle the object A1
}
}
}
public class B2 : B {
public override A A_obj {
get {
// want to retun the object of A2
}
set {
// want to handle the object A2
}
}
}
public class C {
public virtual B [] B_obj { get; set; }
}
public class C1 : C {
public override B[ ] B_obj {
get {
// want to retun the object of B1
}
set {
// want to handle the object B1
}
}
}
public class C2 : C {
public override B[ ] B_obj {
get {
// want to retun the object of B2
}
set {
// want to handle the object B2
}
}
}
泛型可能是解决问题的方法。根据我对您 post 的解释,问题似乎是 B1 只能引用 A1 对象,B2 -> A2 和类似的 C 对象。
下面的想法会让你输入安全并消除转换的必要性:
public abstract class A { };
public class A1 : A { };
public class A2 : A { };
public abstract class B<T> where T : A {
public T A_obj { get; set; }
};
public class B1 : B<A1>
{
};
public class B2 : B<A2>
{
};
public abstract class C<T, U> where T : B<U> where U : A
{
public List<T> B_objs { get; private set; }
public C() {
B_objs = new List<T>();
}
};
public class C1 : C<B1, A1>
{
};
public class C2 : C<B2, A2>
{
};
public static void Test()
{
A1 a1 = new A1();
B1 b1 = new B1();
b1.A_obj = a1;
A2 a2 = new A2();
B2 b2 = new B2();
b2.A_obj = a2;
// The following line fails: cannot implicitly convert A1 to A2
//b2.A_obj = a1;
C1 c1 = new C1();
c1.B_objs.Add(b1);
// The following fails:
// c1.B_objs.Add(b2);
}
我必须解决一个非常棘手的问题,我会尽力解释这个问题。我有一个复杂的对象,它有两个级别的组合,不知何故我应该为低级别的组合定义两个 classes 并反映更高级别的新类型。为了体现low composition的变化,我在higher levels中也定义了两个classes。
我正在使用抽象工厂方法来创建更高级别 classes 的实例。所有 class 都是可序列化的。
下图中的C 对应高级别classes,A 对应低级别classes。 A classes 的对象由级别 2 classes 的对象组成,它们由 C classes 的对象组成。
在抽象工厂方法中,我试图反序列化对象 return 作为父对象 class。我收到与铸造相关的错误。但是,我认为设计中存在一些我无法弄清楚的基本问题。我知道父对象不能转换为子对象。
public class A {
public virtual Double [] Prop1 { get; set; }
public virtual Double [] Prop2 { get; set; }
}
public class A1 : A {
public override double[ ] Prop1 {
get {
// implementation other than base class
}
set {
// implementation other than base class
}
}
}
public class A2 : A {
public override double[ ] Prop2 {
get {
// implementation other than base class
}
set {
// implementation other than base class
}
}
}
public class B {
public virtual A A_obj { get; set; }
}
public class B1 : B {
public override A A_obj {
get {
// want to retun the object of A1
}
set {
// want to handle the object A1
}
}
}
public class B2 : B {
public override A A_obj {
get {
// want to retun the object of A2
}
set {
// want to handle the object A2
}
}
}
public class C {
public virtual B [] B_obj { get; set; }
}
public class C1 : C {
public override B[ ] B_obj {
get {
// want to retun the object of B1
}
set {
// want to handle the object B1
}
}
}
public class C2 : C {
public override B[ ] B_obj {
get {
// want to retun the object of B2
}
set {
// want to handle the object B2
}
}
}
泛型可能是解决问题的方法。根据我对您 post 的解释,问题似乎是 B1 只能引用 A1 对象,B2 -> A2 和类似的 C 对象。
下面的想法会让你输入安全并消除转换的必要性:
public abstract class A { };
public class A1 : A { };
public class A2 : A { };
public abstract class B<T> where T : A {
public T A_obj { get; set; }
};
public class B1 : B<A1>
{
};
public class B2 : B<A2>
{
};
public abstract class C<T, U> where T : B<U> where U : A
{
public List<T> B_objs { get; private set; }
public C() {
B_objs = new List<T>();
}
};
public class C1 : C<B1, A1>
{
};
public class C2 : C<B2, A2>
{
};
public static void Test()
{
A1 a1 = new A1();
B1 b1 = new B1();
b1.A_obj = a1;
A2 a2 = new A2();
B2 b2 = new B2();
b2.A_obj = a2;
// The following line fails: cannot implicitly convert A1 to A2
//b2.A_obj = a1;
C1 c1 = new C1();
c1.B_objs.Add(b1);
// The following fails:
// c1.B_objs.Add(b2);
}