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 of pluginbase, if change method pluginbase.invoke protected, concreteexecutableplugin have no access (aside hacks reflection).
  • all 'reused' methods , properties needed composed (née base) class executablejobplugin need rewired in concreteexecutableplugin. 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 opposed new within)
  • decoupling via interfaces improves testability of class hierarchy
  • * sealing executablejobplugin won't prevent others subclassing public superclasses pluginbase , jobplugin. prevent this, keep base classes in same assembly , mark these internal, 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

Popular posts from this blog

Fail to load namespace Spring Security http://www.springframework.org/security/tags -

sql - MySQL query optimization using coalesce -

unity3d - Unity local avoidance in user created world -