当派生类仅由“上下文”和返回类型不同时,在何处实现方法

时间:2011-05-11 13:33:54

标签: c# oop

我有一个基类“BaseClass”和n派生类DerivedCLass1,DerivedClass2 ...... (我不知道“派生”是否是正确的术语,但我的DerivedClassX只是BaseClass 添加的方法很少。像车辆对汽车/摩托车/卡车)

所有派生类共享一个生成/存储pdf的storePDF函数。 不应该从BaseClass实例调用此方法,因为这是无关紧要的。 但我不希望代码在所有派生类中重复。 我该如何组织课程? (或接口)

public class BaseClass
{
    public static string select = "
    select Derivedclass1DT.* from Derivedclass1DT union
    select Derivedclass2DT.* from Derivedclass2DT where type='foo' union
    select * from Derivedclass2DT where type='foo'
    ...    
    "

    public static string objecttype= "";    

    public List<Baseclass> getInstance(string id)
    {
        /* create instance from db using the select ...  */
    }

    public PDFObject storePDF()
    {
        /* 
            generate a pdf shouldn't be called directly from an BaseClass instance
        */
    }        
}

public class DerivedCLass1:BaseClass
{
    public static string select = "select Derivedclass1DT.* from Derivedclass1DT";
    public static string objecttype= "some text specific to this class";

    public List<DerivedCLass1> getInstance(string id)
    {
        /* same code as is the base class just using a different select and return type */    
    }

    /*
        Don't want to store storePDF() implementation here. It is the same for each derived Class
    */
}
public class DerivedCLass2:BaseClass
{
    public static string select = "select Derivedclass2DT.* from Derivedclass2DT where type='foo'";
    public static string objecttype= "some other text specific to this class";

    public List<DerivedCLass1> getInstance(string id)
    {
        /* same code as is the base class just using a different select and return type */    
    }

    /*
        Don't want to store storePDF() implementation here. It is the same for each derived Class
    */
}

5 个答案:

答案 0 :(得分:0)

您应该在基类中创建和抽象或虚拟方法storePdf 并且在派生类中重写此方法如果您有一些默认行为,则应将其移动到虚拟基本方法中,否则您可以使用此方法创建和抽象方法或接口 在你的情况下,你可以在基类中创建一个公共虚方法,并使基类抽象它避免实例化这个类的对象

答案 1 :(得分:0)

这个想法是将所有公共代码保留在基类中,如果要实现不同的功能,派生类可能会覆盖某些函数,这没有任何害处。如果需要,也可以从base.DoSomething() derive.DoSomething()调用基类方法和派生类方法。希望这个帮助

答案 2 :(得分:0)

建议将storePDF()标记为在基类中受保护,以便除了从其继承的类之外,任何人都无法访问它。这可以防止任何人在基类上调用storePDF()。

然后对于子类,您可以在基类中使用一个抽象方法,该方法将被基类覆盖,这将调用受保护的storePDFHelper方法:

public abstract class BaseClass
{
    //(...)

    protected PDFObject storePDFHelper() { /* Do stuff here */ }
    public abstract PDFObject storePDF();
}
public class ChildClass : BaseClass, IPDFGenerator
{
    public override PDFObject storePDF() { return base.storePDFHelper(); }
}

从语义上讲,我认为这是一个不错的选择,因为你会: 1)无法从BaseClass调用storePDF,你提到它会很好 2)能够在BaseClass的所有子项上重用storePDF逻辑

但是我想听听其他更有经验的人:) 希望这有帮助!

答案 3 :(得分:0)

两个派生类中的List<DerivedCLass1> getInstance(string id)函数不会返回不同的类型 - 这是正确的还是拼写错误?

在任何情况下,因为它们返回的类型与基类不同,所以它们不能覆盖等效函数。将您的基类更改为abstract,并尝试以下内容:

public abstract class BaseClass      //note the abstract modifier!
{

    public abstract List<Baseclass> getInstance(string id);

    public PDFObject storePDF()
    {
        /* 
            generate a pdf shouldn't be called directly from an BaseClass instance
        */
    }        
}

public class DerivedCLass1:BaseClass
{
    public override List<BaseClass> getInstance(string id)
    {
        List<BaseClass> myList = new List<BaseClass>();
        myList.Add(new DerivedClass1() { ... } );       // note the type of the class beng added!    
    }

    /* there is no need to override storePDF(), it is already visible via this class */
}

使用storePDF()方法,将其实现保留在基类中 - 任何使用者都必须通过派生类调用它,因为基类是抽象的,不能直接创建。

答案 4 :(得分:0)

应该将StorePdf提取到自己的类中。是否应将此注入到派生类中,或者StorePdf应将它们作为参数接收,这取决于实现细节。首先,您将其移开以消除违反SRP的行为。