如何实现子类仅继承父类数据一次?避免重复属性问题
问题:创建仅顶层父类使用且不被子类重复实例化的属性
我需要创建一个名为DoNotShareWithGrandChildren的属性,仅允许最顶层父类使用,子类不能继承该属性的实例。目前的困境是找不到合适的架构,既能让子类继承父类的其他属性,又不会导致该属性被多次实例化。
尝试1:初始继承实现的问题
直接让子类继承父类,但每次创建子类实例时,都会继承并实例化父类的DoNotShareWithGrandChildren属性,导致多个实例产生:
class A { bool DoNotShareWithGrandChildren = true; public A() { DoNotShareWithGrandChildren = true; } } class Child :A { bool other = false; AnotherChild grandchild; public Child() : base() { grandchild = new AnotherChild(); // 此处会创建另一个DoNotShareWithGrandChildren实例 } } class AnotherChild : A { bool somemore = false; public AnotherChild() : base() {} }
尝试2:使用MasterClass存储属性的问题
尝试将属性移到外部的MasterClass中,但父类A无法访问该属性,达不到预期效果:
class MasterClass { A a; bool DoNotShareWithGrandChildren = true; class MasterClass { A a; bool DoNotShareWithGrandChildren = true; public MasterClass(A a) { this.a = a; } } class A { public A() { // 无法访问DoNotShareWithGrandChildren! } } class Child :A { bool other = false; AnotherChild grandchild; public Child() : base() { grandchild = new AnotherChild(); } } class AnotherChild :A { bool somemore = false; public AnotherChild() : base() { } } }
解决方案
方案1:使用静态字段
将DoNotShareWithGrandChildren设为父类的静态字段,这样整个类只有一个实例,子类继承后不会重复创建该属性的实例:
class A { // 静态字段,属于类本身,仅存在一个实例 private static bool DoNotShareWithGrandChildren = true; public A() { } // 若子类需要访问该值,可提供protected方法 protected bool GetDoNotShareValue() { return DoNotShareWithGrandChildren; } } class Child : A { bool other = false; AnotherChild grandchild; public Child() : base() { grandchild = new AnotherChild(); // 如需使用该值,通过父类方法获取 // var value = GetDoNotShareValue(); } } class AnotherChild : A { bool somemore = false; public AnotherChild() : base() {} }
静态字段属于类而非实例,无论创建多少父类或子类实例,该字段只会存在一个,完全符合“不创建多个实例”的需求。
方案2:组合代替继承
如果不需要子类完全继承父类的所有成员,可采用组合方式让子类持有父类实例,而非继承父类,这样子类不会拥有DoNotShareWithGrandChildren属性:
class A { bool DoNotShareWithGrandChildren = true; public A() { DoNotShareWithGrandChildren = true; } // 暴露子类需要复用的方法 public void CoreFunction() { if(DoNotShareWithGrandChildren) { // 执行顶层父类专属逻辑 } } } class Child { bool other = false; AnotherChild grandchild; // 持有父类实例以复用功能 private A aInstance = new A(); public Child() { grandchild = new AnotherChild(); aInstance.CoreFunction(); } } class AnotherChild { bool somemore = false; private A aInstance = new A(); public AnotherChild() { aInstance.CoreFunction(); } }
若需要全局仅一个DoNotShareWithGrandChildren实例,可将aInstance设为静态,让所有子类共享同一个父类实例。
内容的提问来源于stack exchange,提问作者Caleb Laws
相关产品推荐
相关产品推荐

