CSCI 104 Inheritance - USC Viterbi

Transcription

1CSCI 104InheritanceMark RedekoppDavid Kempe

2Files for Today mkdir inh cd inh wget http://ee.usc.edu/ redekopp/cs104/inh.tar tar xvf inh.tar make

3Constructor Initialization Listsclass Person{public:Person();Person(string myname);Person(string myname, int myid);string get name() { return name; }void add grade(int score);int get grade(int index);private:string name ;int id ;};Person::Person() { }Person::Person(string myname){ name myname;id -1;}Person::Person(string myname, int myid){ name myname;id myid;}.string nameint id C constructors often have a bunch of assignments and initializations to thedata members.

4Constructor Initialization ListsPerson::Person() /* mem allocated here */{name("Tommy Trojan");id 12313;}You can't call memberconstructors in the { }Person::Person(string myname) :name(myname), id(12313){ }You would have to call the memberconstructors in the initialization list context Rather than writing many assignment statementswe can use a special initialization list techniquefor C constructors– Constructor(param list) : member1(param/val), , memberN(param/val){ } We are really calling the respective constructorsfor each data member

5Constructor Initialization ListsPerson::Person(){name "Tommy Trojan";id 12313}You can still assign datamembers in the { }Person::Person() :name(), id()// calls to default constructors{name "Tommy Trojan";id 12313}But any member not in the initialization list willhave its default constructor invoked before the{ } You can still assign values in the constructor butrealize that the default constructors will havebeen called already So generally if you know what value you want toassign a data member it's good practice to do itin the initialization list

6Constructor Initialization ListsPerson::Person() { }Person::Person(string myname){ name myname;id -1;}Person::Person(string myname, int myid){ name myname;id myid;}.String Operator () Calledstring nameint idname mynameid myidMemory isallocatedbefore the '{' then valuescopied in whenassignmentperformedInitialization usingassignmentPerson::Person() { }Person::Person(string myname) :name (myname), id (-1){ }Person::Person(string myname, int myid) :name (myname), id (myid){}.String Copy ConstructorCalledInitialization Listapproachname mynameid myidMemory isallocated andfilled in "onestep"

7INHERITANCE

8Object Oriented Design Encapsulation– Combine data and operations on that data into asingle unit (e.g. a class w/ public and privateaspects) Inheritance– Creating new objects (classes) from existing ones Polymorphism– Using the same expression to denote differentoperations

9Inheritance A way of defining interfaces, re-using classes andextending original functionality Allows a new class to inherit all the data members andmember functions from a previously defined class Works from more generalobjects to more specific objects– Defines an “is-a” relationship– Square is-a rectangle is-a shape– Square inherits from Rectangle whichinherits from Shape– Similar to classification of organisms: Animal - Vertebrate - Mammals - Primatesbasechildgrandchild

10Base and Derived Classes Derived classes inheritall data members andfunctions of base class Student class inherits:– get name() and get id()– name and id membervariablesclass Person {public:Person(string n, int ident);string get name();int get id();private:string name ; int id ;};class Student : public Person {public:Student(string n, int ident, int mjr);int get major();double get gpa();void set gpa(double new gpa);private:int major ; double gpa ;};Class PersonClass Studentstring namestring nameint idint idint majordouble gpa

11Base and Derived Classes Derived classes inheritall data members andfunctions of base class Student class inherits:– get name() and get id()– name and id membervariablesclass Person {public:Person(string n, int ident);string get name();int get id();private:string name ; int id ;};class Student : public Person {public:Student(string n, int ident, int mjr);int get major();double get gpa();void set gpa(double new gpa);private:int major ; double gpa ;};int majorint main(){Student s1("Tommy", 1, 9);// Student has Person functionality// as if it was written as part of// Studentcout s1.get name() endl;double gpa}Class PersonClass Studentstring namestring nameint idint id

12Inheritance ExampleComponent Component– Draw()– onClick()WindowInheritance Diagrams(arrows shown baseto derived classrelationships)ListBox Window– Minimize()– Maximize() ListBox– Get Selection() ScrollBox– onScroll() DropDownBox– onDropDown()ScrollBoxDropDownBox

13Constructors and Inheritance How do we initialize baseclass data members? Can't assign base classmembers if they areprivateclass Person {public:Person(string n, int ident);.private:string name ;int id ;};class Student : public Person {public:Student(string n, int ident, int mjr);.private:int major ;double gpa ;};Student::Student(string n, int ident, int mjr){name n;// can't access name in Studentid ident;major mjr;}

14Constructors and Inheritance Constructors are only called whena variable ‘enters scope’ (i.e. iscreated) and cannot be calleddirectly– How to deal with baseconstructors? Also want/need base class orother members to be initializedbefore we perform this object'sconstructor code Use initializer format instead– See example belowclass Person {public:Person(string n, int ident);.private:string name ;int id ;};class Student : public Person {public:Student(string n, int ident, int mjr);.private:int major ;double gpa ;};Student::Student(string n, int ident, int mjr){// How to initialize Base class members?Person(n, ident); // No! can’t call Construc.//as a function}Student::Student(string n, int ident, int mjr) : Person(n, ident){cout "Constructing student: " name endl;major mjr;gpa 0.0;}

15Constructors & Destructors Constructors– A Derived class will automatically call its Base classconstructor BEFORE it's own constructor executes,either: Explicitly calling a specified base class constructor in theinitialization list Implicitly calling the default base class constructor if nobase class constructor is called in the initialization listbasechildgrandchildConstructor call ordering Destructors– The derived class will call the Base class destructorautomatically AFTER it's own destructor executes General idea– Constructors get called from base- derived (smaller tolarger)– Destructors get called from derived- base (larger tosmaller)basechildgrandchildDestructor call ordering

16Constructor & Destructor Orderingclass A {int a;public:A() { a 0; cout "A:" a endl; } A() { cout " A" endl; }A(int mya) { a mya;cout "A:" a endl; }};class B : public A {int b;public:B() { b 0; cout "B:" b endl; } B() { cout " B "; }B(int myb) { b myb;cout "B:" b endl; }};class C : public B {int c;public:C() { c 0; cout "C:" c endl; } C() { cout " C "; }C(int myb, int myc) : B(myb) {c myc;cout "C:" c endl; }};Sample Classesint main(){cout "Allocating a B object" endl;B b1;cout "Allocating 1st C object" endl;C* c1 new C;cout "Allocating 2nd C object" endl;C c2(4,5);cout "Deleting c1 object" endl;delete c1;cout "Quitting" endl;return 0;Test Program}Allocating a B objectA:0B:0Allocating 1st C objectA:0B:0C:0Allocating 2nd C objectA:0B:4C:5Deleting c1 object C B AQuitting C B A B AOutput

17Protected Members Private members of a baseclass can not be accesseddirectly by a derived classmember function– Code for print grade report()would not compile since ‘name ’ isprivate to class Person Base class can declarevariables with protectedstorage class– Private to anyone not inheritingfrom the base– Derived classes can access directlyclass Person {public:.private:string name ; int id ;};class Student : public Person {public:void print grade report();private:int major ; double gpa ;};void Student::print grade report(){cout “Student “ name .}class Person {public:.protected:string name ; int id ;};X

18Public/Private/Protected Access Derived class sees base class membersusing the base class' specification– If Base class said it was public or protected,the derived class can access it directly– If Base class said it was private, the derivedclass cannot access it directly public/private identifier before baseclass indicates HOW the public baseclass members are viewed by clients(those outside) of the derived class– public public base class members arepublic to clients (others can access)– private public & protected base classmembers are private to clients (notaccessible to the outside world)class Person {public:Person(string n, int ident);string get name();int get id();private: // INACCESSIBLE TO DERIVEDstring name ; int id ;};Base Classclass Student : public Person {public:Student(string n, int ident, int mjr);int get major();double get gpa();void set gpa(double new gpa);private:int major ; double gpa ;};class Faculty : private Person {public:Faculty(string n, int ident, bool tnr);bool get tenure();private:bool tenure ;};Derived Classes

19Inheritance Access Summary Base class– Declare as protected if you want toallow a member to be directlyaccessed/modified by derived classes Derive as public if –You want users of your derived class to beable to call base class functions/methods Derive as private if –You only want your internal workings to callbase class otectedPrivatePrivatePrivatePrivatePrivateExternal client access to Base class membersis always the more restrictive of either the basedeclaration or inheritance levelclass Person {public:Person(string n, int ident);string get name();int get id();private: // INACCESSIBLE TO DERIVEDstring name ; int id ;Base Class};class Student : public Person {public:Student(string n, int ident, int mjr);int get major();double get gpa();void set gpa(double new gpa);private:int major ; double gpa ;};class Faculty : private Person {public:Faculty(string n, int ident, bool tnr);bool get tenure();private:bool tenure ;};int main(){Student s1("Tommy", 73412, 1);Faculty f1("Mark", 53201, 2);cout s1.get name() endl; // workscout f1.get name() endl; // fails}

20When to Inherit Privately Suppose I want to create a FIFO (Firstin, First-Out) data structure where youcan only– Push in the back– Pop from the front FIFO is-a special List Do I want to inherit publicly from List NO!!! Because now the outside usercan call the base List functions andbreak my FIFO order Inherit privately to hide the base classpublic function and make users gothrough the derived class' interface– Private inheritance defines an "as-a"relationshipclass List{public:List();void insert(int loc, const int& val);int size();int& get(int loc);void pop(int loc;)private:IntItem* head;};Base Classclass FIFO : public List // or private List{ public:FIFO();push back(const int& val){ insert(size(), val); }int& front();{ return get(0); }void pop front();{ pop(0); }};Derived ClassFIFO f1;f1.push back(7); f1.push back(8);f1.insert(0,9)

21Overloading Base Functions A derived class may want toredefined the behavior of amember function of thebase class A base member function canbe overloaded in the derivedclass When derived objects callthat function the derivedversion will be executed When a base objects callthat function the baseversion will be executedclass Car{public:double compute mpg();private:string make; string model;};Class Carstring makestring modeldouble Car::compute mpg(){if(speed 55) return 30.0;else return 20.0;}class Hybrid : public Car {public:void drive w battery();double compute mpg();private:string batteryType;};Class Hybridstring makestring modelstring batterydouble Hybrid::compute mpg(){if(speed 15) return 45; // hybrid modeelse if(speed 55) return 30.0;else return 20.0;}

22Scoping Base Functions We can still call the base functionversion by using the scope operator(::)–class Car{public:double compute mpg();private:string make; string model;};base class name::function name()class Hybrid : public Car {public:double compute mpg();private:string batteryType;};double Car::compute mpg(){if(speed 55) return 30.0;else return 20.0;}double Hybrid::compute mpg(){if(speed 15) return 45; // hybrid modeelse return Car::compute mpg();}

23Inheritance vs. Composition Software engineers debate aboutusing inheritance (is-a) vs.composition (has-a) Rather than a Hybrid “is-a” Car wemight say Hybrid “has-a” car in it,plus other stuff– Better example when we get to Lists,Queues and Stacks While it might not make completesense verbally, we could re-factorour code the following ways Interesting article I’d recommendyou read at least once:– evil-and-must-be-destroyed/class Car{public:double compute mpg();public:string make; string model;};Class Carstring makestring modeldouble Car::compute mpg(){if(speed 55) return 30.0;else return 20.0;}class Hybrid {public:double compute mpg();private:Car c ; // has-a relationshipstring batteryType;};Class Hybridstring c.makestring c.modelstring batterydouble Hybrid::compute mpg(){if(speed 15) return 45; // hybrid modeelse return c .compute mpg();}

24Another Composition We can create a FIFO that "has-a" a Listas the underlying structure Summary:– Public Inheritance "is-a" relationship– Composition "has-a" relationship– Private Inheritance "as-a" relationship"implemented-as"class List{public:List();void insert(int loc, const int& val);int size();int& get(int loc);void pop(int loc;)private:IntItem* head;};Base Classclass FIFO{ private:List mylist;public:FIFO();push back(const int& val){ mylist.insert(size(), val); }int& front();{ return mylist.get(0); }void pop front();{ mylist.pop(0); }int size() // need to create wrapper{ return mylist.size(); }};FIFO via Composition

Inheritance A way of defining interfaces, re-using classes and extending original functionality Allows a new class to inherit all the data members and member functions from a previously defined class Works from more general objects to more specific objects –Defin