如何为多级组合类设计继承

时间:2015-10-15 16:00:42

标签: c# oop inheritance composition

我必须解决一个非常棘手的问题,我会尽力解释这个问题。我有一个复杂的对象,它有两个级别的组合,不知何故,我应该定义两个低级别的组合类,并反映更高级别的新类型。为了反映低成分的变化,我也在更高层次中定义了两个类。

我使用抽象工厂方法来创建更高级别的类的实例。所有类都是可序列化的。

下图中的C对应于更高级别的类,A对应于低级别类。 A类的对象由2级类的对象组成,它们由C类的对象组成。

在抽象工厂方法中,我试图反序列化对象并作为父类返回。我正在投射相关的错误。但是,我认为设计中存在一些基本问题,我无法弄清楚。我知道父对象不能作为子对象传播。

enter image description here

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

1 个答案:

答案 0 :(得分:1)

泛型可能是去这里的方式。根据我对你的帖子的解释,问题似乎是B1只能引用A1对象,B2 - >对于C对象,A2和类似。

以下想法可以让您输入安全性并消除投射的必要性:

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