Copyright © 1998-2009 Curt Hill Applets A different type of program.
Copyright © 1998-2014 Curt Hill Inheritance in C++ How to do it.
-
Upload
oswin-gaines -
Category
Documents
-
view
213 -
download
0
Transcript of Copyright © 1998-2014 Curt Hill Inheritance in C++ How to do it.
Copyright © 1998-2014 Curt Hill
Very little new Syntax
• In the header– Ancestral class– Specify the type of derivation– Give the new properties and methods– Virtual methods
• In the class code– Constructors– Ancestral method calls
• How used in client code
Copyright © 1998-2014 Curt Hill
Terminology– Derive
• To make a new class which inherits properties and methods from an older class
– Ancestor• The older class which defines the
inherited properties and methods• Also known as the base class or super
class
– Method• Member function
– Property• Member data
Copyright © 1998-2014 Curt Hill
Declaring a derived class• Normal class syntax is:
class name {– Name is the name of the new class
• Derivation syntax:class name : [visibility] ancestor {– Name is the new class name– Ancestor is the ancestral class name– Visibility is one of the three visibilities– Public is usually best, default is
private
Copyright © 1998-2014 Curt Hill
Notes
• The ancestral class must be accessible via an include– It may also be a derived class
• The visibility type is most frequently public– Other visibilities will be considered
later
Copyright © 1998-2014 Curt Hill
Example:– class student: public person { protected: int hours; college_type college; public: student (); student (char nme[], char m_or_f, date& d,int h=0, char c = 'u'); void set_college(char c); void incr_hours(int h); virtual void ToString(char *)const; }; // student class
Notes
• Every property and method of person now exists in student
• The visibility is not changed• Protected and public properties
and methods may be accessed by student code
Copyright © 1998-2014 Curt Hill
Copyright © 1998-2014 Curt Hill
Adding properties and methods
• Protected is only of importance in derivations– Allows a derived class to access but not
client
• Any methods given may either be new or override an existing method– They augment existing methods
• Properties add to existing properties• The virtual is optional in all but the base
class– Good documentation
Copyright © 1998-2014 Curt Hill
Override
• To override is to create a new method with the same signature as an inherited method
• The override method will be executed and not the overridden– Regardless of where the call occurs
Copyright © 1998-2014 Curt Hill
Removing• There is no remove syntax
– There are tricks
• Restricted derivations reduce everything of a visibility to a lower visibility
• Most properties are hidden from client so that is not a problem
• Methods:– Change the visibility from public to
protected or private• Now inaccessible
– Override to do nothing or error
Copyright © 1998-2014 Curt Hill
Polymorphism
• Objects in the same inheritance tree are interchangable– Any may be called
• Choosing the correct function based on the object at run-time– Dynamic binding – Only possible with pointers– Pointer type must be an ancestral
type
Copyright © 1998-2014 Curt Hill
Binding• Earlier programming languages
used static binding only– At compile or link time determine the
function needed– Examples: Pascal, C, COBOL
• Some programming languages use dynamic binding only– Determine function needed at run time– Examples: LISP and Java
• C++ uses both, depending on situation
Copyright © 1998-2014 Curt Hill
C++ Binding• Stroustrup was walking a fine line
in the design of C++• He wanted the efficiency of C and
the OO power of Smalltalk• Thus he puts in the hands of the
programmer whether the method is polymorphic, that is has dynamic binding
• This is done with presence of virtual keyword
Interchangeability• Polymorphism makes types
interchangeable– These classes have an “is a”
relationship
• A cast converts a value from one type to another
• Interchangeability means to accept that value without cast or other change
• Upcasting is an exampleCopyright © 1998-2014 Curt Hill
Upcasting
• To upcast is to treat an object lower on the inheritance tree as if it were higher– To treat a derived class like one of its
super classes
• It is easy – not actually a cast at all• The storage of the ancestor always
precedes that of the descendent• See the pictures in next two slides
Copyright © 1998-2014 Curt Hill
Example Hierarchy
Copyright © 1998-2014 Curt Hill
person
employee student
grad
name
wage hours
degree
Storage of Grad
Copyright © 1998-2014 Curt Hill
Name
Hours
Degree
Person properties
Student properties
Grad properties
The IBM 360 Floating Point Trick
Copyright © 1998-2014 Curt Hill
C++ Requirements for Polymorphism
• The object must be referenced by a pointer– Pointers are always same length
• The pointer type must be a pointer to the base type
• The function called must be declared virtual in the base type
• All the sub-classes have the function with the same signature
Copyright © 1998-2014 Curt Hill
Polymorphism
• Is enabled by Virtual functions• Any ancestral method that is prefixed
by virtual forces all descendent functions with same signature to also be virtual
• The polymorphism is only demonstrated when a pointer is used.– Pointer must be to ancestral class
• Stack items are of different sizes so are not interchangeable– Unlike pointers
Copyright © 1998-2014 Curt Hill
Polymorphic Non-Example
• Student s, * sptr;Person p, *pptr;st = s.ToString();– This is not polymorphic since we
know exactly what the type of s is.
• sptr->set_name(“Bill Smith”);– This is not polymorphic since
set_name is only defined in Person
Copyright © 1998-2014 Curt Hill
Polymorphic Example
• Person * p;p = new student(…);p = new person(…);// Assignment of any // descendent is legalst = p->ToString();– This is polymorphic since we do not
know whether p is a pointer to a person or any of its descendents
– Run-time system must figure it out for us
Copyright © 1998-2014 Curt Hill
Consider – class X {
void A(){ … B(); …} virtual void B() {…} }; // end of X
– class Y:public X { virtual void B() {…} }; // end of Y
– X * u; Y * v;u->A(); // Calls X.A and then X.Bv->A(); // Calls X.A and then Y.B
– A descendent B is called by an ancestral A
Copyright © 1998-2014 Curt Hill
Constructors
• The idea is that we build the class values when it is created
• There are two related problems having to do with default constructors– Constructing a derived class must
also construct the ancestral– When the constructor starts any
contained classes are already made
Copyright © 1998-2014 Curt Hill
Problem example
• Suppose:class person { protected: date birth; char name[20];…
• Date is a class– It must have a default constructor
Copyright © 1998-2014 Curt Hill
The Person Constructor• Person::person(…){
birth = date(1,2,87);• When the constructor starts (following
the {)• All the contained or ancestral things
have already been constructed• Two problems:
– Default constructor may not be accessible– Wasteful - Default construction plus second
construction
Copyright © 1998-2014 Curt Hill
The solution
• A different notation for construction• Person::person(int m,int d, int y):
birth(m,d,y),name(“Bill Smith”){}• Property names are treated like
functions and initial value is put in them– Even if not a class name– These are executed before any property
construction and before anything in braces
Copyright © 1998-2014 Curt Hill
Same notation for inheritance
• In inheritance the ancestral class name is treated like a variable
• Thus a non-default constructor may be called
• Most things in the initialization list are member data names except the ancestral class
• Example follows
Copyright © 1998-2014 Curt Hill
Example: Student constructor
• student::student(char nme[], char m_or_f, date & d, int h,char c) : person(nme,m_or_f,d), hours(h) { set_college(c);}
Copyright © 1998-2014 Curt Hill
Summary for Construction
• In inheritance the ancestral class name is treated like a variable– Thus a non-default constructor may
be called
• All variable names are treated like functions
• Initialization list is completed before the body of the constructor is executed– Often the body is empty
Copyright © 1998-2014 Curt Hill
Pure Virtual Functions
• Used to define interface• No implementation• The header is assigned zero:virtual int s1(int i)const=0;virtual int s2()=0;
Copyright © 1998-2014 Curt Hill
Abstract Base Classes
• Contain one or more pure virtual functions– Either their own or inherited from a super
class
• Cannot be instantiated• Any descendent must implement all
pure virtual functions to be instantiable• May have a pointer of that type, which
is used for polymorphism for the whole tree
• May not implement = operator
Copyright © 1998-2014 Curt Hill
Example• class shape {
double x,y; public: virtual void move(double dx, double dy); virtual void draw() = 0;… };class circle: public shape{ void draw(); … };…shape * sp;
Copyright © 1998-2014 Curt Hill
Example explained
• Shape is an abstract class• Circle’s draw overrides shape’s
draw – Circle may be instantiated
• Even though shape cannot be instantiated a pointer that will contain several shapes may have that type
Copyright © 1998-2014 Curt Hill
Accessing Overridden Methods
• When a descendent overrides an existing method the method is still available
• The ancestral name and scope resolution operator are used
• Consider following example
Copyright © 1998-2014 Curt Hill
Example 1class anc{
...
int meth(int a);}; // end of anc
class desc: public anc{ ... int meth(int a);}; // end of desc
int desc::meth(int a){ ... c = anc::meth(a); ...}
Example 2• Consider the ToString of the
Student class• It should not re-implement the
ToString of Person– It should just call it
• Such as:wxString student::ToString(){ wxString s = Person::ToString(); s = s << “ “ << hours; …
Copyright © 1998-2014 Curt Hill
Copyright © 1998-2014 Curt Hill
Visibility Again
• There are two ways to modify visibilities of the base class
• Individual methods may be altered by overriding them– Override at a different visibility– Can be done if base class made
something other than private
• All visibilities may be lowered by using derivation visibility
Copyright © 1998-2014 Curt Hill
Exampleclass anc{
protected:
int meth1(int a); int meth2(int a);}; // end of anc
class desc: public anc{ private: int meth1(int a); public: int meth2(int a);}; // end of desc
Copyright © 1998-2014 Curt Hill
Derivation Visibility
• The visibility given in the class header determines the visibility of the items from the superclass in this class
• This can reduce visibility but never make it more visible
• Public derivations preserve the existing visibilities
Copyright © 1998-2014 Curt Hill
New VisibilitiesDerivation type / Base class visibility / Result visibility
Was Public
Was Protected
Was Private
Public Public Protected Private
Protected Protected Protected Private
private Private Private Private
Copyright © 1998-2014 Curt Hill
Other Derivations
• Protected visibility– Hides all methods and properties
from clients– Preserves access to this and sub
classes
• Private visibility– Hides all methods and properties
from clients and sub classes– Similar to composition where
ancestral class is now private
Copyright © 1998-2014 Curt Hill
Multiple Inheritance
• Recall the grad class– It inherited behavior from both
student and person
• Multiple inheritance is the inheriting of behavior from two different classes– These classes are not usually in the
same inheritance tree
Copyright © 1998-2014 Curt Hill
Syntax
• Just about what you expect• class C: public A, public B {• The C class inherits all the
properties and methods of both A and B
• Class C is interchangeable with both A and B classes
Copyright © 1998-2014 Curt Hill
Characteristics of Multiple Inheritance
• When it is good it is wonderful– A good example is iostreams
• Inherit from a string formatting object (stream) and a file I/O object (io)
• Thus have characteristics of both
• When it is bad it is horrendous– C++ is the main language to retain
multiple inheritance– Smalltalk had it then removed it– Java never had – Eiffel seems to have done the most
with it
Copyright © 1998-2014 Curt Hill
Problems with Multiple Inheritance
• Main problem is name clashes and what to do with them– Suppose two classes have a method X– A new class is a derivation of both
• How do we get one X over the other
• When both ancestors are from same tree problems compound
Copyright © 1998-2014 Curt Hill
Example
• Consider:class grademployee: public grad, public employ{…
• This looks reasonable, but now there are two names, two birth dates, two genders
• How do we distinguish between the access to the grad set_name or the employ set_name?
Conclusion• Inheritance is a powerful
mechanism for reusing code• Function parameters allow us to
unite two similar pieces of code into one
• Inheritance works somewhat similarly by giving new functionality without altering the ancestral class or classes
• Better yet, it is not hard to do
Copyright © 1998-2014 Curt Hill