当派生类仅因“上下文”和返回类型而异时,在哪里实现方法

本文关键字:上下文 方法 实现 在哪里 返回类型 派生 | 更新日期: 2023-09-27 17:55:59

我得到了一个基类"BaseClass"和n个派生类DerivedCLass1,DerivedClass2...(我不知道"派生"是否是正确的术语,但我的派生类X是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
    */
}

当派生类仅因“上下文”和返回类型而异时,在哪里实现方法

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

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

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

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

建议在基类中将 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逻辑

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