ppt

advertisement
Object Oriented Programming
COP3330 / CGS5409


Inheritance
Assignment 5


Many types of classes that we create can have
similarities.
Useful to take advantage of the objectoriented programming technique known as
Inheritance. To do this, we :
◦ factor out the common features into a single class,
usually referred to as a base class.
◦ build derived classes that will share all of the data
and functionality found in the base class.
◦ derived class will inherit all of the base class
features.






This base class / derived class relationship referred to as
an "is a" relationship
Derived object really is an instance of the base object -it's usually just a bit more specific (like a subcategory).
Examples:
A class called Geometric_Object. From this base class we
could derive classes like Circle, Square, and Line.
A class called Sport. From this class we could derive
classes like Football, Baseball, and Soccer, because each
one is a Sport.
A class called BankAccount. From this we could derive the
classes Savings, Checking, Debit (each is a type of
account).
A class called Vehicle. From this we could derive classes
Car, Train, Bus (each one is a vehicle). Furthermore, we
could use the Car class as a base class from which to
derive more new classes, such as Ford, Toyota, and Honda.

To declare a class as a derived class, just add a little
bit of syntax to the class declaration block. Here is
the format:
class derivedClassName : public baseClassName


The word "public" in this format causes
derivedClassName to be publicly derived from
baseClassName.
The base class would be declared normally
somewhere above (or in an included file). This
essentially means that the protection levels in the
derived class are the same as in the base class.
(Note: It is possible to derive with different
protection levels -- we will not worry about those
here).

So, the class declarations for some of the above examples might look
like this:
class Sport
{
....
};
class Football : public Sport
{
....
};
class
class
class
class
Checking : public Account
Baseball : public Sport
Car : public Vehicle
Honda : public Car

Notice that in the last two declarations,
◦ Car inherits everything in the Vehicle class, and
◦ Honda inherits everything in the Car class. Because
of this,
◦ Honda has also inherited everything from the
Vehicle class as well.

Example: classes in a drawing program

Remember that the protection levels we have are
public and private.
◦ public - Any member that is public can be accessed by
name from anywhere.
◦ private - Any member that is private can be accessed
directly only by the class in which it is declared.

This poses a problem, since we would like derived
classes to have access to the members that it
inherited from the base class, but we still want
protection from outside access. For this reason,
there is a third level of protection for member data
and functions, called protected.
◦ protected - Any member that is protected can be accessed
directly by the class in which it is declared, and by any
classes that are derived from that class (but not from
anywhere else).

Protection levels in the drawing program example


We know that when an object is created, its
constructor runs.
However, what happens when a derived
object is created?
◦ In this case, the derived object "is-an" instance of
the base class as well.
◦ So, when a derived object is created, the
constructors from the base and derived classes will
run. The order in which they run is important, too - the base class constructor runs first, then the
derived.
Vehicle obj1;
Car obj2;
Honda obj3;





In the first declaration, only the Vehicle() constructor
runs.
In the second declaration, the Vehicle() constructor
runs for obj2, followed by the Car() constructor.
In the third declaration, the constructors that run, in
order, are: Vehicle(), Car(), Honda()
Note: When an object goes out of scope, the
destructors will run in reverse order: ~Honda(),
~Car(), ~Vehicle()
You can verify for yourself in code what order the
constructors and destructors run in.


Since no parameters were specified in the above
examples, the default constructors (i.e. no
parameters) are used.
What if we have parameters? Remember in the
Fraction class, we could declare the following:

Fraction f(3,4);
parameters
// calls constructor with

So, with a derived class, we might want to
declare:

Honda h(2,3,4,"green","Accord");
send in 5 parameters
// wants to


However, the 2 and 3 might be codes intended for a variables
like "vehicleCategory" and "idNumber" in the Vehicle class; the 4
and "green" might be intended for variables like "numDoors" and
"carColor" in the Car class; and the "Accord" might be intended
for a variable "model" in the Honda class. This means that the
first two parameters are needed by the Vehicle constructor, the
second two are needed by the Car constructor, and the last is
needed in the Honda constructor. How do we distribute the
parameters to the appropriate places?
To do this with derived classes, use an Initialization List. And
initialization list is something that can go along with any
function definition. The format is:
function prototype : initialization list
{
function body
}
Vehicle::Vehicle(int c, int id)
// this parent constructor uses the first two parameters
{
vehicleCategory = c;
idNumber = id;
}
Car::Car(int c, int id, int nd, char* cc) : Vehicle(c, id)
// this function passes the first two parameters up to Vehicle, and uses nd and cc
{
numDoors = nd;
strcpy(carColor,cc);
}
Honda::Honda(int c, int id, int nd, char* cc, char* mod) : Car(c, id, nd, cc)
// This function passes the first four parameters up to car, and uses mod
{
strcpy(model, mod);
}

Suppose we have the following base class:
class Student
{
public:
void GradeReport();
... (other member functions and data)
};

Let's assume that the "GradeReport" function will
print out a grade report for a Student

Now, take the following as classes derived from Student:
class Grad : public Student
class Undergrad : public Student

Since these classes are derived from Student, they inherit
everything from the Student class. So, we could build the
following objects and make the following function calls:
Student s;
Grad g;
Undergrad u;
s.GradeReport();
g.GradeReport();
u.GradeReport();

The Grad and Undergrad classes both inherited the GradeReport
function, so they can call it. However, what if grade reports look
different for undergrads and grads? Then, these classes need to have
their own functions! With inheritance, a derived class can create its own
version of a function in the base class, with the exact same prototype,
which will override the base class version:
class Grad : public Student
{
public:
void GradeReport();
... (other stuff)
};
class Undergrad : public Student
{
public:
void GradeReport();
... (other stuff)
};

So, in the calls listed above, each object calls it's own
version of the GradeReport function:
s.GradeReport();
g.GradeReport();
u.GradeReport();

// runs Student's version
// runs Grad's version
// runs Undergrad's version
Now, does this mean that for the grad object g, the
parent version is no longer accessible? No!
Remember, a derived class inherits everything from
its parent class. If, inside the Grad's version of
GradeReport, you would like to call upon the parent's
version as well (usually done if you want to split the
work and let the parent function do as much as
possible, based on data stored in the base class), you
can.

Here's an example -- these are outlines of the function definitions:
void Student::GradeReport()
{
... processing done by parent function ...
}
void Grad::GradeReport()
{
Student::GradeReport(); // explicit call to parent function
// other processing specific to Grad's version
}

Notice that you can explicitly call the parent's version of the function by
specifying the parent class name and the scope resolution operator:
className::memberName
Examples of function overriding for the drawing program example.



From this directory from our textbook (Ch. 14 on
inheritance):
http://www.cs.fsu.edu/~myers/savitch3c++/Ch14/
Several classes that go together in an inheritance
hierarchy:
◦ Employee (employee.h and employee.cpp) -- base class for
Employee hierarchy
◦ HourlyEmployee (hourlyemployee.h and hourlyemployee.cpp) -- a
subclass
◦ SalariedEmployee (salariedemployee.h and salariedemployee.cpp)
-- another subclass
◦ 14-07.cpp -- a sample main program that uses the Employee and
subcategory objects

This one is fairly basic -- but it does illustrate things we've
seen so far, including the handling of constructors in base
and derived classes, as well as some simple function
overrides.


http://www.cs.fsu.edu/~myers/savitch3c++/
Ch14/
Inheritance features:
◦ Basic use of base and derived classes
◦ use of initialization list in derived class constructors
to explicitly call appropriate base class constructor
◦ Derived class functions (like printCheck() ) calling
base class member functions
◦ In this example be sure to point out that the
derived functions need to call the accessors to get
data declared in the parent class -- because that
data is private to the base class
Download