CS60 Lecture 18 ------------------- Announce ------------------- - hw12 due! - proj4 due friday - hw13 posted This Week ------------------- - inheritance - polymorphism - templates Today ------------------- - review of classes - basic inheritance Review ------------------- - the class - user defined type - encapsulates data/functionality - allows for data hiding, 'safe' types - bundles data/functionality into one notion 'object' - special member functions - constructor - destructor - copy constructor - operator overloading - allows programmer to use shorthand notation for function calls - friends - allows us to give functiosn/classes access to private members - used to avoid function call overhead Basic Inheritance ------------------------ - classes obviously have many special features - next special thing we can do is define heirarchies of classes - concept known as inheritance - again, idea is to reduce code duplication as much as possible - also, make clean type abstractions - in C, if we had many complex data types that shared SOME features, all had to be in their own structs OR we had one giant struct that had all possible variables - many times, groups of data types share a great deal in common and only differ in a few ways - ex: vehicles - motorcycle, skateboard, boat, kayak, airplane, helicopter common characteristics - all have a driver - all have a 3d position - all move in at least 2 dimensions motorcycle - has # of wheels - has an engine - has a passenger skateboard - has # of wheels boat - has an engine airplane - has a copilot helicopter vehicle #water air road boat kayak airplane helicopter motorcycle skateboard - C++ lets us 'share commonalities' among types by using inheritance class vehicle { private: char *driver; int posx, posy, posz; int velx, vely; public: char *getdriver() {return driver;}; ... }; class motorcycle : public vehicle { private: int numwheels; int enginecc; char *passenger; public: int setnumwheels(int in) {numwheels = in;}; char *getpassenger() {return(passenger);}; ... } class skateboard : public vehicle { private: int numwheels; public: int setnumwheels(int in) {numwheels = in;}; ... } - now in main motorcycle mybike; cout << mybike.getdriver() << endl; - but we have a problem, all our data values are declared as private which expressly means ONLY OBJECTS OF THE SAME TYPE HAVE ACCESS - new qualifier 'protected' - simply means that other same type classes or any class derived from class have access to protected data - now mybike can run 'getdriver()'. Further inheritance -------------------- - notice that we have some common data in the parent class, but the child nodes are also sharing some data - numwheels/setnumwheels are specified in two child classes - can make more levels of inheritance road vehicles - have some set # of wheels water vehicles - have some # of lifejackets air vehicles - can move in one more dimension class roadvehicle : public vehicle { private: int numwheels; public: void setnumwheels(int in) {numwheels = in;}; ... } class motorcycle : public roadvehicle { private: int enginecc; char *passenger; public: ... }; * DRAW NEW PICTURE OF CLASS HIERARCHY - now, all of our specific vehicle classes need only to implement details that are unique to the specific vehicle. Multiple Types ----------------- - when a class is a child of another class, it has more than one type. any function that accepts a parent type can also accept a child type void foofunc(vehicle &in) { cout << in.getdriver() << endl; } - can call with any 'vehicle' type or any child derived from 'vehicle' motorcycle mybike; boat myboat; skateboard myboard; foofunc(mybike); foofunc(myboat); foofunc(myboard); Redefining functions ------------------------- - child classes inherit all data/functions from parent classes. - if we want some child to do somthing different for some function, we can 'redefine' the function - just put a new definition with the same name and args in the class definition, and the new function code will run when invoked on a child class instance class motorcycle : public roadvehicle { public: char *getdriver() {cout << "no driver!" << endl; return(NULL);}; }; vehicle a; motorcycle b; a.getdriver() // calls getdriver code implemented in 'vehicle' b.getdriver() // calls getdriver code implemented in 'motorcycle' Functions Not Inherited ------------------------- - constructors, overloaded = operator, destructor - ALL classes must define these if they want to use them - why? well they initialize variables that may only exist in the child class - initialization section syntax makes it easier class roadvehicle { ... public: roadvehicle() : vehicle() { numwheels=1; }; };