当派生类仅因“上下文”和返回类型而异时,在哪里实现方法
本文关键字:上下文 方法 实现 在哪里 返回类型 派生 | 更新日期: 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逻辑
但我也想听听其他更有经验的人的意见:)希望这有帮助!