强制继承的类调用基助手方法
本文关键字:方法 调用 继承 | 更新日期: 2023-09-27 17:50:35
我有一个包含helper方法的基类。如何强制继承的类调用这个助手方法?是否有一种方法可以警告消费者必须调用GenerateId ?我应该让这个助手方法成为基本构造函数逻辑的一部分吗?
例如:public class FooBar
{
public int GenerateId(string productCode)
{
//..some logic to return an integer;
}
}
public class AnotherFooBar : FooBar
{
public void Save()
{
var fooBarId = this.GenerateId("myproduct");
//fooBarId will be used in this code block
}
}
你可以这样做:
public abstract class FooBar
{
public void Save()
{
var fooBarId = this.GenerateId("myproduct");
SaveCore(fooBarId);
//fooBarId will be used in this code block
}
protected abstact void SaveCore(int id);
}
当Save被调用时,子类现在强制调用该方法。我不知道SaveCore是否需要id,如果是,你可以像在示例中一样将其作为参数传递。
之后,如果不需要,您可以将GenerateId设置为私有,因为从名称来看,它可能不是您想让人们自由使用的东西。
无论如何,考虑记录好SaveCore和id代表什么,因为继承增加了实现的复杂性,并且子类可能以错误的方式实现。
你不能在一个被覆盖的方法上"强制"任何东西。你看问题的角度不对。
请参阅Martin Fowler的文章,了解正确的方法。
基本上,如果你的基类需要在每次调用重写时执行特定的代码,那么你应该只重写基方法的"一部分",就像这样:
class A
{
void MethodOne()
{
//Here you perform your obligatory logic.
//Then, call the overridable logic.
MethodOneCore();
}
virtual void MethodOneCore()
{
//Here you perform overridable logic.
}
}
class B: A
{
override void MethodOneCore()
{
//Here you override the "core" logic, while keeping the obligatory logic intact.
}
}
可以使基类抽象,并强制派生类实现一个方法。把必须调用GenerateId()
的方法放在基类中,让它调用抽象方法:
public abstract class FooBar
{
protected abstract string Product { get; }
private int GenerateId(string productCode)
{
//..some logic to return an integer;
}
public void Save()
{
var fooBarId = this.GenerateId(Product);
SaveInternal(fooBarId);
}
protected abstract void SaveInternal(int id);
}
public class AnotherFooBar : FooBar
{
protected override string Product { get { return "myproduct"; } }
protected override void SaveInternal(int id)
{
// id will be used in this code block
}
}
此外,由于派生类可能想要为不同的产品生成id,因此还可以在基类中创建一个抽象只读Product
属性,从而强制派生类提供产品名称。
这是你要找的吗?(你的问题不完全清楚……)
public class FooBar
{
public abstract int GenerateId(string productCode);
public void Save()
{
var fooBarId = this.GenerateId("myproduct");
//fooBarId will be used in this code block
}
}
public class AnotherFooBar : FooBar
{
public override int GenerateId(string productCode)
{
//..some logic to return an integer;
}
}