c#:BaseClass虚拟方法使用在子类中定义的对象

时间:2019-01-16 10:17:39

标签: c#

我有一个基础班和许多孩子班。 在每个子类中,我都使用对象A-因此,将其放在基类中。 在子类的一半中,我使用对象B,因此我没有将B放在基类中。 我希望我的基类包含尽可能多的功能,因此,如果定义了对象B,我希望基类中的方法能够“执行某些操作”。这有道理吗?

我可能是从错误的角度看问题,希望您能以正确的方向指导我。让我知道我是否对问题没有足够的解释

我试图将对象B放在基类中,但我不希望每个子类都能够使用对象B。

abstract class BaseClass
{
    public Object A { get; set; }

    protected virtual void SomeMethod()
    {
        if (!(A is null))        
        {
            //Do thing with A
            //This works fine
        }

        if (!(B is null))        
        {
            //Do thing with B
            //This doesnt work - But I want to it work
        }
    }
}

class ChildClass : BaseClass
{
    public Object B { get; set; }
}

2 个答案:

答案 0 :(得分:5)

最简单的解决方案是从基类派生另一个类,向其添加B属性和相关功能,并使所有共享该属性和功能的类均从该类派生,而不是直接从该类派生基类。

类似这样的东西:

abstract class BaseClassB : BaseClass
{
    public object B {get;set;}

    protected override void SomeMethod()
    {
        base.SomeMethod();
        if (B != null)        
        {
            //Do thing with B
            //
        }
    }
}

答案 1 :(得分:1)

我想补充一些有关类,抽象类和接口的要点:

  • 可重用性:当您谈论基类并希望向其添加尽可能多的功能以便子类可以重用它时, 请确保您没有违反Single Responsibility Principle 。而不是将所有内容塞满课堂, 考虑它的作用并相应地添加责任。

  • 继承与直接用法:您谈到了在基类中使用ObjectB,但也希望将用法限制为有限的子类,而不是所有人都可以使用。这是不可能的,也不是一个好的方法。而是为ObjectB创建一个单独的类,并使用Dependency Injection在特定的子类中使用它。这样,您就可以在子类中使用Test的实例,并且也不会创建紧密的耦合:

    //Class to be used in specific child classes public class Test { public object B { get; set; } }

    //Child class implementation using Constructor Injection public class SpecificChild { public Test _test { get; set; } public SpecificChild(Test test) { _test = test; } }

    我也可以在上面的代码中使用继承,但这不是很好,因为C#不能 支持多级继承,将来您可能需要继承其他一些类

  • 虚拟/重写冲突:在子类中重写虚拟方法并完全重写它时,最好使用抽象方法并仅定义方法定义,以便实现类可以相应地编写它。

    abstract class BaseClass
    {
        public Object A { get; set; }
    
        //protected virtual void SomeMethod()
        //{
        //    if (!(A is null))
        //    {
        //        //Do thing with A
        //        //This works fine
        //    }
    
        //    if (!(B is null))
        //    {
        //        //Do thing with B
        //        //This doesnt work - But I want to it work
        //    }
        //}
    
        public abstract void SomeMethod();
    }
    
    class ChildClass : BaseClass
    {
        public Object B { get; set; }
    
        public override void SomeMethod()
        {
            //    if (!(A is null))
            //    {
            //        //Do thing with A
            //        //This works fine
            //    }
    
            //    if (!(B is null))
            //    {
            //        //Do thing with B
            //        //This doesnt work - But I want to it work
            //    }
        }
    }
    

额外阅读:如果您对Abstract类和接口感到困惑,我很久以前就写过一篇对您有用的文章:https://www.c-sharpcorner.com/UploadFile/d0e913/abstract-class-interface-two-villains-of-every-interview/