You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何实现子类仅继承父类数据一次?避免重复属性问题

问题:创建仅顶层父类使用且不被子类重复实例化的属性

我需要创建一个名为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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.22 16:43:12