Can't find the diagram, but I used composition for communication with a family of devices. Device class contained "transport", "firmware version", "key map", etc. Transport (serial VISA, FTDI dll, custom .net dll) had read and write methods - no abstract parent. Firmware Version parent class had specific functions (one per Byte, kind of thing) for version 1. Version 2 inherited from version 1 - some overrides, some extras. Version 3 inherited from version 2, etc. Key map turned scanned ADC arrays into other things. It worked very well, even at six firmware versions. Selection of each type of object was done via enum/case statement. This allowed direct selection and trial-and-error detection of each object in the device.