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
concreteexecutableplugin
no longer subclass ofpluginbase
, if change methodpluginbase.invoke
protected
,concreteexecutableplugin
have no access (aside hacks reflection). - all 'reused' methods , properties needed composed (née base) class
executablejobplugin
need rewired inconcreteexecutableplugin
. although tedious, allow additional interception, e.g. cross cutting concerns logging. - the
executablejobplugin
class may no longer abstract, since instance needed composition work. - ideally,
executablejobplugin
should injected externally (as opposednew
within) - decoupling via interfaces improves testability of class hierarchy
*
sealingexecutablejobplugin
won'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