C# 是否正在寻找其他方法来隐藏子类中的抽象继承方法?
我希望继承的方法C# 是否正在寻找其他方法来隐藏子类中的抽象继承方法?,c#,oop,inheritance,overriding,abstract,C#,Oop,Inheritance,Overriding,Abstract,我希望继承的方法Invoke()对最后一个子类ConcreteExecutablePlugin隐藏 整体情况: public abstract class PluginBase { public abstract void Invoke(IDictionary parameters); } public abstract class JobPlugin : PluginBase { protected void CheckParameter(){//....} p
Invoke()
对最后一个子类ConcreteExecutablePlugin
隐藏
整体情况:
public abstract class PluginBase
{
public abstract void Invoke(IDictionary parameters);
}
public abstract class JobPlugin : PluginBase
{
protected void CheckParameter(){//....}
public bool IsActive(){//....}
}
public class ConcreteJobPlugin : JobPlugin
{
public override void Invoke(IDictionary parameters){//...}
}
public abstract class ExecutableJobPlugin : JobPlugin
{
protected abstract void Initialize(IDictionary parameters);
public sealed override void Invoke(IDictionary parameters)
{
//final realization of Invoke() method
}
}
public class ConcreteExecutablePlugin : ExecutableJobPlugin
{
//here i want method Invoke() has been already hiden
//!!!OR use base.Invoke() better?
protected override void Initialize(IDictionary parameters)
{
//concrete plugin initialization
}
}
我只找到了一个解决办法。现在,我用的是密封的。你觉得这个解决方案怎么样
您知道隐藏抽象继承方法的其他方法吗?在派生类中隐藏公共方法是不可能的。
public
的全部要点是,该方法可以在基类及其任何子类中访问
您可以尝试使用受保护的
,然后在派生插件中简单地使用public
方法,如初始化
,或者您可以尝试使用内部
(尽管这可能不是最好的方法)。Re:Visibility
公共方法向设计意图发出信号,表明它对所有人都可见-如果这不是设计意图,则相应地更改方法的可见性,例如受保护的
(但显然任何子类都有访问权限),或者如果允许使用调用的所有类都在同一程序集中,然后可以声明Invoke
受保护的内部摘要
Re:Sealed
根据Lasse的观点,sealed override
方法将在继承期间中断多态的虚拟/override
链,但它仍然不能改变基本方法是公共的这一事实。但是,将sealed
应用于一个类将阻止其他类继承它,从而限制对所有受保护方法的访问
解决方案
我认为潜在的问题与过度使用继承有关-似乎您希望继承功能以获得重用,但同时需要将链中某个点的访问限制为“不可信”子类。除了让方法internal
+将所有“可靠”的子类移动到基类程序集中之外,在使用完整的子类链时,您几乎没有控制权
我相信,通过接口分离您的层次结构,并应用的原则,将更好地实现您的目标。事实上,这看起来是一种选择
您还可以通过将“最后一个可信”子类(ExecutableJobPlugin
)设置为sealed
*)来设置“可信”边界
示例:
// Expose just what is visible to your final Subclass on the interface
public interface IExecutableJobPlugin
{
bool IsActive { get; set; }
void CheckParameter();
void Initialize(IDictionary parameters);
}
// Sealed will prevent other classes from inheriting this class.
public sealed class ExecutableJobPlugin : JobPlugin, IExecutableJobPlugin
{
// Default implementation. NB, not abstract
public void Initialize(IDictionary parameters) {}
// This isn't visible on the interface
protected override sealed void Invoke(IDictionary parameters)
{
//final realization of Invoke() method
}
}
public class ConcreteExecutablePlugin : IExecutableJobPlugin
{
// Compose a decoupled IExecutableJobPlugin instead of direct inheritance
private readonly IExecutableJobPlugin _wrappedJobPlugin;
public ConcreteExecutablePlugin(IExecutableJobPlugin wrapped)
{
_wrappedJobPlugin = wrapped;
}
// Invoke() isn't on the interface so cannot be accessed here
public void Initialize(IDictionary parameters)
{
// Call 'super' if needed.
_wrappedJobPlugin.Initialize(parameters);
//concrete plugin initialization code here ...
}
public bool IsActive
{
get { return _wrappedJobPlugin.IsActive; }
set { _wrappedJobPlugin.IsActive = value; }
}
public void CheckParameter()
{
_wrappedJobPlugin.CheckParameter();
}
}
注释
- 因为
ConcreteExecutablePlugin
不再是PluginBase
的子类,如果将方法PluginBase.Invoke
更改为protected
,则ConcreteExecutablePlugin
将无法访问它(除了反射之类的黑客攻击)
- 组合(née base)类
ExecutableJobPlugin
所需的所有“重用”方法和属性都需要在ConcreteExecutablePlugin
中重新布线。虽然有点乏味,但它确实允许额外的拦截,例如日志记录等横切问题
ExecutableJobPlugin
类可能不再是抽象类,因为合成工作需要一个实例
- 理想情况下,
ExecutableJobPlugin
应该从外部注入(而不是new
内部)
- 通过接口进行解耦可以提高类层次结构的可测试性
*
密封ExecutableJobPlugin
不会阻止其他人子类化公共超类,如PluginBase
和JobPlugin
。为了防止这种情况,您可以将所有基类保留在同一个程序集中,并将它们标记为internal
,或者继续在整个链中应用接口解耦/装饰器模式,而不是继承
显然,该模式可以在类层次结构的多个级别上重复,并且应该应用该模式以确保接口保持精简和集中。基本抽象方法被声明为public
,这将从设计上表明它在意图上是可见的?@StuartLC,实际上,我已经有了更多的继承级别,你不能在派生类型中隐藏公共方法。也许它应该被保护
或者通过接口实现?@LasseV.Karlsen您认为使用sealed解决这个问题怎么样?您仍然无法隐藏您继承的公共方法。将类密封只会阻止声明新的子类型。我添加了一些更多信息