c# - Looking for other ways to hide abstract inheritance method from a subclass? -
i want inherited method invoke() hidden final subclass concreteexecutableplugin.
whole situation:
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 want method invoke() has been hiden //!!!or use base.invoke() better? protected override void initialize(idictionary parameters) { //concrete plugin initialization } } i have found 1 solution. now, i'm using sealed this. think solution?
do know ways hide abstract inheritance method?
re: visibility
a public method signals design intention visible - if isn't designed intention, change method's visibility accordingly, e.g. protected (but subclass has access), or if classes allowed use invoke in same assembly, invoke can declared protected internal abstract.
re: sealed
as per lasse's point, sealed override methods disrupt polymorphic virtual / override chain during inheritance, still, can not change fact base method public. however, applying sealed class prevent other classes inheriting all, restricting access protected methods.
solution
i believe underlying problem relates over-using inheritance - seemingly want inherit functionality obtain reuse, @ same time need restrict access @ point in chain "untrustworthy" subclass. other point making methods internal + moving "trustworthy" subclasses base class assembly, have little control when using full chain of subclasses.
i believe decoupling hierarchy via interfaces, , applying principle of composition on inheritance, better achieve after. in fact, decorator pattern looks option here.
you can set 'trustworthiness' boundary making 'last trustworthy' subclass (executablejobplugin) sealed *.
example:
// expose visible final subclass on interface public interface iexecutablejobplugin { bool isactive { get; set; } void checkparameter(); void initialize(idictionary parameters); } // sealed prevent other classes inheriting class. public sealed class executablejobplugin : jobplugin, iexecutablejobplugin { // default implementation. nb, not abstract public void initialize(idictionary parameters) {} // isn't visible on interface protected override sealed void invoke(idictionary parameters) { //final realization of invoke() method } } public class concreteexecutableplugin : iexecutablejobplugin { // compose decoupled iexecutablejobplugin instead of direct inheritance private readonly iexecutablejobplugin _wrappedjobplugin; public concreteexecutableplugin(iexecutablejobplugin wrapped) { _wrappedjobplugin = wrapped; } // invoke() isn't on interface cannot accessed here public void initialize(idictionary parameters) { // call 'super' if needed. _wrappedjobplugin.initialize(parameters); //concrete plugin initialization code here ... } public bool isactive { { return _wrappedjobplugin.isactive; } set { _wrappedjobplugin.isactive = value; } } public void checkparameter() { _wrappedjobplugin.checkparameter(); } } notes
- because
concreteexecutablepluginno longer subclass ofpluginbase, if change methodpluginbase.invokeprotected,concreteexecutablepluginhave no access (aside hacks reflection). - all 'reused' methods , properties needed composed (née base) class
executablejobpluginneed rewired inconcreteexecutableplugin. although tedious, allow additional interception, e.g. cross cutting concerns logging. - the
executablejobpluginclass may no longer abstract, since instance needed composition work. - ideally,
executablejobpluginshould injected externally (as opposednewwithin) - decoupling via interfaces improves testability of class hierarchy
*sealingexecutablejobpluginwon't prevent others subclassing public superclassespluginbase,jobplugin. prevent this, keep base classes in same assembly , mark theseinternal, or continue apply interface decoupling / decorator pattern instead of inheritance across entire chain.
the pattern repeated multiple levels of class hierarchy, , interface segregation principle should applied ensure interfaces remain lean , focused.
Comments
Post a Comment