Lecture of 31 January 1995

Code now, text later! #include <iostream.h> class Animal{ public: virtual void name () = 0; // // The keyword virtual indicates that this member function may be // redefined by derived classes and that if I treat a derived class // object as an Animal, then the derived class member function is // executed. virtual void tease () = 0; // // The = 0 definition of name and tease indicates that objects of class // Animal cannot be constructed because these behaviors are undefined // for the general class of animals, but must be well-defined for // sub- or derived classes of animal for which specific objects can // be constructed. // In Smalltalk, such a member is called a subclass responsibility. // In C++ it is called an abstract virtual function, and the class // Animal is referred to as an abstract base class because no (physical) // objects belonging to the class can exist. virtual void sound (); }; void Animal::sound() { cout << "(nothing)"; } class Snail : public Animal{ // The class Snail is derived from Animal. // It thus must redefine all the abstract virtual functions of Animal, // that is, name and tease. public: Snail (){} virtual void name (); virtual void tease (); }; // Snail does not redefine sound, therefore, when the sound member // function of a snail is invoked, the one inherited from the // Animal class is used. void Snail::name() { cout << "snail"; } void Snail::tease() { cout << "pour salt on"; } // The livestock class defines a non-virtual tease function which can // be inherited by all derived classes of livestock. // It also redefines the sound function, but leaves the // name member function virtual, thus derived classes of Livestock must // define a name member function. class Livestock : public Animal{ public: virtual void name () = 0; virtual void tease (); virtual void sound (); }; void Livestock::tease () { cout << "pull the tail"; } void Livestock::sound () { cout << "Moo"; } class Cow:public Livestock{ public: Cow (){} virtual void name (); }; void Cow::name() { cout << "cow"; } class Buffalo:public Livestock{ public: Buffalo (){} virtual void name (); }; void Buffalo::name () { cout << "buffalo"; } // The harass function takes an Animal reference argument. // Functions that take such a reference to a class such as Animal // may actually be passed a reference argument object of a derived // class of Animal. When an animal virtual member function is invoked // within the body of harass, the member function defined by the // argument object's class is used. void harass(Animal &a) { cout << "If you "; a.tease (); cout << " a "; a.name (); cout << ", then it will say "; a.sound (); cout << "." << endl; } int main() { Snail s; Cow c; Buffalo b; harass(s); harass(c); harass(b); return 0; }

Hierarchy

Multiple Inheritance

Aggregation

Typing


This document is copyright 1995 by Joseph N. Wilson.
$Id: Jan.31.html,v 1.1 1995/02/22 15:05:16 jnw Exp jnw $