Download
expressing common behavior n.
Skip this Video
Loading SlideShow in 5 Seconds..
Expressing Common Behavior PowerPoint Presentation
Download Presentation
Expressing Common Behavior

Expressing Common Behavior

93 Vues Download Presentation
Télécharger la présentation

Expressing Common Behavior

- - - - - - - - - - - - - - - - - - - - - - - - - - - E N D - - - - - - - - - - - - - - - - - - - - - - - - - - -
Presentation Transcript

  1. Expressing Common Behavior • Example: General Purpose Interface Bus (GPIB) • Interchangeable Hardware vs. Special-Purpose Software • Interface Base Classes • Create Objects, Use Interfaces • Multiple Interfaces • Interfaces as Components

  2. Forms of Inheritance • Specialization: The derived class is a subtype, a special case of the base class. • Specification: The base class defines behavior that is implemented in the derived class. • Construction: The derived class makes use of the behavior provided by the • base class, but is not a subtype of the base class. • Generalization: The derived class modifies some of the methods of the base. • Extension: The derived class adds new functionality to the base, but does not • change any inherited behavior. • Limitation: The derived class restricts the use of some of the behavior • inherited from the base. • Variance: The derived class and the base class are variants of each other, • and the base/derived class relationship is arbitrary. • Combination: The derived class inherits from more than one base class.

  3. Example: General Purpose Interface Bus (GPIB) An Acme 130 voltage supply GPIB A VoltyMetrics voltmeter

  4. class GPIBController_Stub { • public: • void insert(const char* device_name, unsigned int address) { • cout << "(" << device_name << " now at address " << address • << ")" << endl; • } • void send(unsigned int address, const char* cmd) { • cout << "(" << "GPIB instrument #" << address << " sends " • << cmd << ")" << endl; • } • void send(unsigned int address, float f) { • cout << "(" << "GPIB instrument #" << address • << " sends value " << f << ")" << endl; • } • float receive(unsigned int address) { • cout << "(" << "Please enter number for GPIB instrument #" • << address << ": "; • float f; • cin >> f; • cout << ")" << endl; • return f; • } • }; GPIB Protocol Instead of bits on a GPIB cable we write bytes on cout ...

  5. Class for Acme 130 voltage supply • class Acme130 { • public: • Acme130(GPIBController_Stub& controller, int gpib_address); • void set(float volts); • double minimum() const; • double maximum() const; • private: • GPIBController_Stub my_controller; • int my_gpib_address; • }; • An object has identity, state and behavior. Declare member data private.

  6. Using an Acme 130 object • Acme130::Acme130(GPIBController_Stub& controller, int gpib_address) : • my_controller(controller), • my_gpib_address(gpib_address) { • my_controller.insert("Acme130", gpib_address); • } • void Acme130::set(float volts) { • if (volts > maximum() || volts < minimum()) { • throw "Acme 130 voltage out of range"; • } • my_controller.send(my_gpib_address, volts); • } • GPIBController_Stub gpip; • Acme130 volt_supply(gpip, 12); • volt_supply.set(3.6); Output: (Acme130 now at address 12) GPIB instrument #12 sends value (3.6)

  7. An Acme 130 voltage supply GPIB A VoltyMetrics voltmeter Hardware is Interchangeable Hey, can I borrow your power supply?

  8. Special-Purpose Software • float checkCalibration(Acme130& supply, VoltyMetrics& meter, • float tst_voltage) { • // Relative error at specified test voltage. • supply.set(tst_voltage); • return abs(tst_voltage - meter.read()) / tst_voltage; • } • VoltyMetrics meter(gpip, 14); • Acme130 supply1(gpip, 12); • ... • cout << "Acme130 rel. error at 1 volt is:" • << checkCalibration(supply1, meter, 1.0) << endl; • VoltOn59 supply2(gpip, 17); • ... • cout << "VoltOn59 rel. error at 1 volt is:" • << checkCalibration(supply2, meter, 1.0) << endl; Both Acme130 and VoltOn59 act like voltage supplies, but we did not say that in our code

  9. Interface Base Classes A pure specification: An abstraction representing voltage supplies. • class VoltageSupply { • public: • virtual void set(float volts) = 0; • virtual float minimum() const = 0; • virtual float maximum() const = 0; • virtual ~VoltageSupply(); • }; • VoltageSupply::~VoltageSupply() {} Declare a virtual destructor in every interface base class unless it is derived from another interface base class that provides a virtual destructor.

  10. float checkCalibration(VoltageSupply& supply, VoltyMetrics& meter, • float tst_voltage) { • // Relative error at specified test voltage. • supply.set(tst_voltage); • return abs(tst_voltage - meter.read()) / tst_voltage; • } Calibrate voltage supplies, not a particular supply.

  11. Attaching Interfaces to Objects Attached to an interface via virtual derivation. • class Acme130_VS : • public VoltageSupply { • public: • Acme130_VS(GPIBController_Stub& controller, int gpib_address); • virtual void set(float volts); • virtual float minimum() const; • virtual float maximum() const; • private: • GPIBController_Stub my_controller; • int my_gpib_address; • }; An implementation: these virtual functions are defined.

  12. Different class, same inteface base. • class VoltOn59_VS : • public VoltageSupply { • public: • VoltOn_59_VS(GPIBController_Stub& controller, int gpib_address); • virtual void set(float volts); • virtual float minimum() const; • virtual float maximum() const; • private: • GPIBController_Stub my_controller; • int my_gpib_address; • }; Redeclare virtual functions as virtual.

  13. Create Objects; Use Interfaces • VoltyMetrics meter(gpib, 14); • Acme130_VS supply1(gpib, 12); • VoltOn59_VS supply2(gpib, 13); • cout << "Acme130_VS relative error at 1 volt is: " • << checkCalibration(supply1, meter, 1.0) << endl; • cout << "VoltOn59_VS relative error at 1 volt is: " • << checkCalibration(supply2, meter, 1.0) << endl; An Acme130_VS is created, checkCalibration uses VoltageSupply

  14. "abstract" VoltageSupply void set(float) float minimum() float maximum() Acme130_VS VoltOn59_VS

  15. Properties of Interface Base Classes: • Interface base classes are not a C++ feature • They are a usage idom 1. No data members 2. Function members only calling members 3. No constructor 4. Remaining functions pure (=0) virtual • Interface bases are abstract • Abstract classes allowed to have data and constructors 5. An virtual destructor with empty body

  16. Multiple Interfaces • class GPIBInstrument { • public: • virtual void send(const char*) = 0; // Command. • virtual void send(float f) = 0; // Command with value. • virtual float receive() = 0; // Data point. • virtual ~GPIBInstrument(); • }; • // Read data from one GPIB instrument and send it to another one • void transferOnGPIB(GPIBInstrument& from, GPIBInstrument& to) { • to.send( from.receive() ); • } Same functions as individual GPIB instruments have to have, abstracted. Using only the abstraction we can write client code.

  17. Attaching Multiple Interfaces Two interfaces, it's a VoltageSupply and it's a GPIBInstrument. • class Acme130_VS_GI : • public VoltageSupply, • public GPIBInstrument { • public: • Acme130_VS_GI(GPIBController_Stub& controller, int gpib_address); • // VoltageSupply interface • virtual void set(float volts); • virtual float minimum() const; • virtual float maximum() const; • // GPIBInstrument interface • virtual void send(const char*); // Command. • virtual void send(float f); // Command with value. • virtual float receive(); // Data point. • private: • GPIBController_Stub my_controller; • int my_gpib_address; • };

  18. Voltmeter GPIBInstrument VoltageSupply VoltOn59 VoltyMetrics Acme130

  19. Interfaces as Components • class GPIBController { • public: • virtual void insert(const char* device_name, unsigned int address)=0; • virtual void send(unsigned int address, const char* cmd) = 0; • virtual void send(unsigned int address, float f) = 0; • virtual float receive(unsigned int address) = 0; • virtual ~GPIBController(); • }; Abstraction of GPIBController_Stub functions

  20. An Interfaced GPIBController • class GPIBController_GC : • public GPIBController { • public: • virtual void insert(const char* device_name, unsigned int address) { • cout << "(" << device_name << " now at address " << address • << ")" << endl; • } • virtual void send(unsigned int address, const char* cmd) { • cout << "(" << "GPIB instrument #" << address << " sends " • << cmd << ")" << endl; • } • virtual void send(unsigned int address, float f) { • cout << "(" << "GPIB instrument #" << address << " sends value " • << f << ")" << endl; • } • .... • } Interface Same functions, same implementation, now virtual.

  21. Attaching Multiple Interfaces • class Acme130_VS_GI_GC : • public VoltageSupply, • public GPIBInstrument { • public: • Acme130_VS_GI_GC(GPIBController& controller, int gpib_address); • // VoltageSupply interface • virtual void set(float volts); • virtual float minimum() const; • virtual float maximum() const; • // GPIBInstrument interface • virtual void send(const char*); • virtual void send(float f); • virtual float receive(); • private: • GPIBController& my_controller; • int my_gpib_address; • }; GPIBController What is in the box? Some GPIBController. Which one? Who cares?

  22. Expressing Common Behavior • Recognizing "is-usable-as" commonality • Interface base classes are the C++ idiom to represent common behavior • The action to be performed is determined by the derived class, not by the base class • Function clients call the interface through references or pointers • Class clients delay calls to interface functions by holding references or pointers