object-oriented design: multiple inheritance (c++ and c#)

30
Copyright@2014 Taylor & Francis Adair Dingle All Rights Reserved ObjectOriented Design Inheritance vs. ComposiAon: Part II Inheritance for Interface: Multiple Inheritance

Upload: adair-dingle

Post on 15-Aug-2015

81 views

Category:

Technology


1 download

TRANSCRIPT

Page 1: Object-Oriented Design: Multiple inheritance (C++ and C#)

Copyright@2014                Taylor  &  Francis              Adair  Dingle      All  Rights  Reserved  

Object-­‐Oriented  Design    

Inheritance    vs.    

ComposiAon:  Part  II  

   Inheritance for Interface: Multiple Inheritance

Page 2: Object-Oriented Design: Multiple inheritance (C++ and C#)

Design  QuesAons  

•  How  to  implement  mulAple  inheritance?  

•  What  type  is  most  important?      – DisAnguish  between  potenAal  base  classes  – Decide  which  type(s)  to  subordinate  

Copyright@2015                Adair  Dingle  

Page 3: Object-Oriented Design: Multiple inheritance (C++ and C#)

Key  ObservaAons  

•  Inheritance  and  composiAon  BOTH  provide  reuse  

•  Interface  inheritance  is  not  true  inheritance  – but  can  serve  to  fulfill  client  needs  

•  Design  impacts  soSware  maintainability  Copyright@2015                Adair  Dingle  

Page 4: Object-Oriented Design: Multiple inheritance (C++ and C#)

Chapter  8:    Design  AlternaAves  &  PerspecAves  

 ComparaAve  Design      Design  types  and  alterna/ves  for  client  use      

 •  Class  design  types  •  Design  for  Inheritance  •  Inheritance  vs.  ComposiAon  •  MulAple  Inheritance  •  Design  Principles      

Copyright@2014                Taylor  &  Francis              Adair  Dingle      All  Rights  Reserved  

Page 5: Object-Oriented Design: Multiple inheritance (C++ and C#)

Why  consider  SoSware  Design?  •  Design  impacts  soSware  use    

–  Efficiency,  OpAmizaAon  (Inlining),  Maintainability,  …  –  Ease  of  subtype  manipulaAon,  heterogeneous  collecAons,  ...  –  Interface  adaptaAon,  type  subordinaAon,  …  

•  Design  impacts  soSware  reuse  –  Type  extensibility  –  Type  checking,  type  extracAon  

•  Class  designers  should  carefully  consider  design  alternaAves  •  Different  costs  and  benefits  

–  Inheritance  vs  composiAon  –  Exposed/echoed/wrapped  interfaces  –  Type  definiAon/idenAficaAon/extracAon  

Copyright@2014                Taylor  &  Francis              Adair  Dingle      All  Rights  Reserved  

Page 6: Object-Oriented Design: Multiple inheritance (C++ and C#)

Class  Design  Types  •  Concrete  –  immediately  usable  

–  Simple,  efficient,  standalone  type  –  Inheritance  NOT  intended  

•  Abstract  –  not  instanAable  –  Defines  common  interface  for  class  hierarchy  –  Inheritance  REQUIRED  

•  Node  -­‐-­‐  Intermediate  class  in  class  hierarchy  –  Inherits  interface  –  provides  resoluAon  or  refined  behavior  –  Inheritance  anAcipated  

Copyright@2014                Taylor  &  Francis              Adair  Dingle      All  Rights  Reserved  

Page 7: Object-Oriented Design: Multiple inheritance (C++ and C#)

Class  Design  Types  -­‐-­‐  conAnued  •  Wrapper  

–  Isolates  client  from  instable  or  proprietary  interface  –  May  echo  porAon  of  wrapped  interface  –  May  augment/coalesce/modified  wrapped  behavior  –  Wrapped  object  replaceable  without  impact  

•  Delegate  –  Wrapped  subObject    –  Replaceable,  possibly  polymorphic  –  ResponsibiliAes  delegated  to  wrapped  subObject  

•  Handle  –  Transparent  resource  manager  –  Tracks  wrapped  subObject  –  No  alteraAon  in  wrapped  behavior  

Copyright@2014                Taylor  &  Francis              Adair  Dingle      All  Rights  Reserved  

Page 8: Object-Oriented Design: Multiple inheritance (C++ and C#)

Encapsulated  SubObjects  •  Wrappers  encapsulate  exisAng  types  

–  reusing  (and  possibly  augmenAng  or  modifying)  funcAonality    –  frequently  isolate  applicaAon  programmer  from  unstable  interfaces    –  wrapped  subObject  may  be  replaced  without  any  impact  –  subObject’s  interface,  if  echoed,    oSen  echoed  in  a  modified  fashion.      

•  Delegate  is  (wrapped)  subObject  –  provides  key  funcAonality  to  the  wrapper  class  –  may  be  exchanged,  replaced,  stubbed  out,  and/or  polymorphic.  

•  Handle  promotes  transparency    –  provides  external  access  to  internal  funcAonality  of  wrapped  subObject    –  e.g.  smart  pointer  –  Unlike  wrappers,  handles  do  not  augment  or  modify  subObject  

funcAonality.      

Copyright@2014                Taylor  &  Francis              Adair  Dingle      All  Rights  Reserved  

Page 9: Object-Oriented Design: Multiple inheritance (C++ and C#)

Abstract  Classes  

•  Define  interface  for  class  hierarchy  –  Determine  funcAonality  accessible  via  heterogeneous  collecAon  

•  May  or  may  not  provide  default  behavior  •  Require  inheritance  •  EffecAve  design  with  polymorphism  

– May  dilute  cohesion  if  designed  but  unnecessary  

Copyright@2014                Taylor  &  Francis              Adair  Dingle      All  Rights  Reserved  

Page 10: Object-Oriented Design: Multiple inheritance (C++ and C#)

Abstract  Classes  •  A  class  is  DESIGNED  as  abstract  when  •  At  least  one  method  is  undefined  •  only  protected  constructors  provided  =>  Client  cannot  instanAate  instance  of  class  

•  C#/Java  provide  keyword  abstract  •  code  more  readable  and  thus  maintainable  

•  C++  does  not  provide  keyword  abstract  

•  UAlity  of  abstract  classes  remains  the  same  –  regardless  of  syntacAcal  differences  across  languages      

Copyright@2014                Taylor  &  Francis              Adair  Dingle      All  Rights  Reserved  

Page 11: Object-Oriented Design: Multiple inheritance (C++ and C#)

Example  8.4    Abstract  Classes  //C++: no keyword abstract C#/Java: just use keyword abstract // C++ => at least one method must be pure virtual class Toy

{ public:

virtual bool safe() = 0; …

};

//Abstract BY DESIGN (C++, C#, Java,…) // => protected constructor, no public constructor

class Vehicle

{ protected:

Vehicle();

public:

};

Copyright@2014                Taylor  &  Francis              Adair  Dingle      All  Rights  Reserved  

Page 12: Object-Oriented Design: Multiple inheritance (C++ and C#)

Example  8.5    Delegate  Use  class seminarAttendee // delegate could be object or pointer { // indirection supports postponed instantiation

idVerifier delegate;

void replaceDelegate(…) { idVerifier newImproved(…);

delegate = newImproved;

}

public:

// pass requests to delegate bool registerD() { return delegate.isSet() }

bool isValid() { return delegate.verify(); }

bool renew()

{ if (!registerD() || !isValid()) return false;

return (delegate.getAge() > 18)

}

};

Copyright@2014                Taylor  &  Francis              Adair  Dingle      All  Rights  Reserved  

Page 13: Object-Oriented Design: Multiple inheritance (C++ and C#)

Example  8.6    Polymorpic  Delegate  class HasADelegate { idVerifier delegate;

BaseType* polyD;

void replaceDelegate()

{ delete polyD;

if (…) polyD = new MinType(…);

else if (…) polyD = new MaxType(…);

else if (…) polyD = new MeanType(…);

}

public:

// simple echo

int getAge() [ return delegate.getAge(); }

// additional layer of indirection supports polymorphism

void dynamicProcess()

{ return polyD->process(); }

};

Copyright@2014                Taylor  &  Francis              Adair  Dingle      All  Rights  Reserved  

Page 14: Object-Oriented Design: Multiple inheritance (C++ and C#)

Table  8.4    Inheritance  Effects  

Copyright@2014                Taylor  &  Francis              Adair  Dingle      All  Rights  Reserved  

Motivation Characteristics Benefits Costs Code reuse Inheritance of Implementation

Reuse existing class May suppress/NOP interface

Reduce : --development time --cut & paste design --maintenance

Code complexity Increased coupling Decreased cohesion Unavoidable overhead Fixed cardinality Dependency on parent Lifetime association

Type extension Inheritance of Interface

Is-a relationship Subtype relevant

Type familiarity Substitutability Polymorphism Heterogeneity Extensibility

Page 15: Object-Oriented Design: Multiple inheritance (C++ and C#)

Inheritance  vs.  ComposiAon  Both  support  Code  Reuse  

Inheritance  supports      type  extensibility    polymorphism    heterogeneous  collecAons  

 

Inheritance  provides      built-­‐in  and  efficient  mechanism  for  type-­‐checking    promotes  design  clarity  and  maintainability    

Copyright@2014                Taylor  &  Francis              Adair  Dingle      All  Rights  Reserved  

Page 16: Object-Oriented Design: Multiple inheritance (C++ and C#)

Inheritance  vs.  ComposiAon  

ComposiAon  affords  the  class  designer  more  control  •  subObject  may  be  manipulated  in  ways  that  a  parent  cannot    •  InstanAaAon  may  be  postponed  •  subObjects  may  be  replaced  •  Cardinality,  lifeAme,  associaAon  and  ownership  may  vary  

–  All  fixed  design  for  inheritance      •  Interfaces  may  be  selecAvely  echoed      •  Overhead  can  be  avoided      •  Unstable  types  may  be  wrapped        

Copyright@2014                Taylor  &  Francis              Adair  Dingle      All  Rights  Reserved  

Page 17: Object-Oriented Design: Multiple inheritance (C++ and C#)

Example  8.8    Inheritance  vs  ComposiAon  

class B { protected:

virtual void filter(); public: … virtual void store();

}; class QueenInheritB: public B { public:

// keyword used for documentation // once virtual always virtual!! virtual void store() { B::store(); filter(); … } …

};

Copyright@2014                Taylor  &  Francis              Adair  Dingle      All  Rights  Reserved  

Page 18: Object-Oriented Design: Multiple inheritance (C++ and C#)

Example  8.8    conAnued  

class QueenComposeB {

B subObject; public:

// cannot access protected B::filter() // virtual nature of B::store() not relevant void store()

{ subObject.store();

… }

};

Copyright@2014                Taylor  &  Francis              Adair  Dingle      All  Rights  Reserved  

Page 19: Object-Oriented Design: Multiple inheritance (C++ and C#)

Example  8.9  ComposiAon  with  Exposed  Interface  

class Be: public B { public:

… // make inherited protected method public void filter() { B::filter(); }

};

class QueenComposeB2

{ Be subObject;

public:

// can filter by using intermediary class void store()

{ subObject.store();

subObject.filter();

}

};

Copyright@2014                Taylor  &  Francis              Adair  Dingle      All  Rights  Reserved  

Page 20: Object-Oriented Design: Multiple inheritance (C++ and C#)

Example  8.10    Inheritance  vs  Polymorphic  Subobjects  

class flexQueen { B* subObjP; public:

// constructor can instantiate any B (sub)type object

// subObjP = 0 or subObjP = new Be or subObjP = Bee …

flexQueen()

{ subObjP = new B;

… // other choices

}

virtual void store()

{ subObjP->store(); // dynamic behavior }

void replaceB(B*& worker)

{ delete subObjP; subObjP = worker; worker = 0;

}

};

Copyright@2014                Taylor  &  Francis              Adair  Dingle      All  Rights  Reserved  

Page 21: Object-Oriented Design: Multiple inheritance (C++ and C#)

MulAple  Inheritance  

•  Like  single  inheritance,  mulAple  inheritance    –  promotes  type  extensibility    –  supports  polymorphism.      

•  MulAple  inheritance  increases  design  complexity      –  two  divergent  ancestral  paths  needed  to  understand    class    –  Two-­‐degree  variance  may  compromise  maintainability      

•  Two  classic  design  difficulAes  –  AMBUGUITY:    parental  interfaces  overlap  –  REDUNDANCY:  common  grandparent  component  

Copyright@2014                Taylor  &  Francis              Adair  Dingle      All  Rights  Reserved  

Page 22: Object-Oriented Design: Multiple inheritance (C++ and C#)

MulAple  Inheritance  

•  Ambiguity  easily  resolved  –  Two  parents  define  same  funcAon  signature  =>    COMPILER  ERROR  –  Child  class  must  override  doubly  inherited  funcAon  

•  redefine  or  direct  call  to  specific  parent  =>  Descendant  class  definiAons  compile  

•  Redundancy  NOT  easily  resolved  –  Two  parents  share  same  ancestor  –  Child  class  inherits  two  copies  of  common  ancestor    –  Duplicate  copy  cannot  be  suppressed  easily  

Copyright@2014                Taylor  &  Francis              Adair  Dingle      All  Rights  Reserved  

Page 23: Object-Oriented Design: Multiple inheritance (C++ and C#)

Example  8.12  Resolving  Ambiguity:    C++  MulAple  Inheritance  

class StudentEmployee: public Employee, public Student { …

public:

int getAge()

{ return Student::getAge(); }

int getSeniority()

{ return Employee::getAge(); } };

Copyright@2014                Taylor  &  Francis              Adair  Dingle      All  Rights  Reserved  

Page 24: Object-Oriented Design: Multiple inheritance (C++ and C#)

Type  SubordinaAon  

•  Inheritance  simulated  via  ComposiAon  –  One  (or  both)  parent  is  defined  as  a  subObject  –  Necessary  when  mulAple  inheritance  NOT  supported  (C#/Java)    

•  Class  designer  selects  subObject  &  thus  subordinates  a  type    •  subObject  does  not  have  visibility  of  a  parent  component  

–  its  interface  is  not  assumed    –  Its  interface  must  be  echoed  if  needed  

•  No  is-­‐a  relaAonship  to  support  type  interchange  in  client    code    –  Design  changes  not  ‘automaAcally’  passed  with  compilaAon  –  No  external  subsAtutability  for  subObject  –  No  heterogeneous  collecAons  typed  to  subObject      

Copyright@2014                Taylor  &  Francis              Adair  Dingle      All  Rights  Reserved  

Page 25: Object-Oriented Design: Multiple inheritance (C++ and C#)

Type  SubordinaAon    

EffecAve  design  technique  •  Permits  simulaAon  of  inheritance    •  adds  flexibility  and  control  over    

–  InstanAaAon  –  Cardinality  –  AssociaAon  –  LifeAme  –  Ownership  –  Interface      

Copyright@2014                Taylor  &  Francis              Adair  Dingle      All  Rights  Reserved  

Page 26: Object-Oriented Design: Multiple inheritance (C++ and C#)

Example  8.17    C#  StudentEmployee:    Student  parent  

interface EmployeeI { … }

public class StudentEmployee3: Student, EmployeeI

{ // contain zero or more Employee components

private Employee e;

// interface forces echo of Employee functionality …

}

// why ‘Employee’ subordinated to ‘Student’?

Copyright@2014                Taylor  &  Francis              Adair  Dingle      All  Rights  Reserved  

Page 27: Object-Oriented Design: Multiple inheritance (C++ and C#)

Table  8.5    Simulate  MulAple  Inheritance  using  ComposiAon    

Motivation Benefits Costs No provision for multiple inheritance in implementation language Clear subordinate parent type Efficiency Type depends on one parent for utility not interface

Variable cardinality Replaceable subobject Insulating layer Shield from parent Polymorphic subobject

Inconvenient loss of: -- Protected interface Design constrained by loss of: --Type familiarity --Substitutability --Polymorphism --Heterogeneity --Extensibility

Copyright@2014                Taylor  &  Francis              Adair  Dingle      All  Rights  Reserved  

Page 28: Object-Oriented Design: Multiple inheritance (C++ and C#)

Interface  SegregaAon  Principle  

Interfaces  should  be  small  and  contain  only  a  few,  related  methods      •  Exalts  interfaces  as  key  design  component    •  Promotes  high  cohesion  and  low  coupling    •  Confines  breadth  of  interface  –  Narrow  interfaces  focus  design  and  imply  specific  uAlity.      – Wide  interfaces  undermine  cohesion  and  maintainability  

•  Targets  interacAng  class  design  –  whether  for  inheritance  or  composiAon.  

Copyright@2014                Taylor  &  Francis              Adair  Dingle      All  Rights  Reserved  

Page 29: Object-Oriented Design: Multiple inheritance (C++ and C#)

Program  to  Interface    Not  to  ImplementaAon  

Model  func/onality,  decoupled  from  implementa/on,  by  using  abstract  classes  and  interfaces.  =>    Implementa/on  can  then  vary  independently.      •  Exalts  interfaces  as  key  design  component    •  Upholds  OOD  abstracAon  and  encapsulaAon    –  Isolate  client  from  volaAle/arbitrary  implementaAon    

•  Drives  complementary  class  design  –  whether  for  inheritance  or  composiAon.  

Copyright@2014                Taylor  &  Francis              Adair  Dingle      All  Rights  Reserved  

Page 30: Object-Oriented Design: Multiple inheritance (C++ and C#)

Dependency  Inversion  Principle  

High-­‐level  abstrac/ons  are  more  stable.    If  dependencies  exist,  preferable  that  low-­‐level  abstrac/ons  depend  on  high-­‐level  abstrac/ons      •  reinforces  value  of  an  extensible,  possibly  abstract,  interface  at  the  base  of  a  class  hierarchy.      

•  suggests  choice  when  determining  subordinate  class    –  Client  should  be  isolated  from  the  least  abstract  type.      –  if  any  lower-­‐level  details  change,  client  code  is  shielded.  

Copyright@2014                Taylor  &  Francis              Adair  Dingle      All  Rights  Reserved