Section 14g

C++ Class Inheritance


 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Extending the Simple to the Slightly Complex

As previously discussed, object oriented programming (OOP) is based on the natural distribution of tasks that commonly occur in our normal world. From grocery departments to automobile specialists to the framers, plumbers, electricians, painters and so on who contribute to building houses, OOP uses this strategy to build programs that are more robust, scaleable to larger sizes, and less prone to bugs in addition to being easier to maintain.

One other natural outgrowth of OOP is the possibility of inheritance. There are plumbers who build showers and there are plumbers who lay piping under house foundations. There are electricians who pull 110 volt wiring, there are electricians that hang fixtures, and there are electricians that handle low-voltage connectivity such as TV cable, Ethernet, and low voltage lighting under the kitchen cabinets. All of these folks start with basics of being a plumber or electrician but then the extend their expertise to narrower or more focused tasks. In OOP, this is called inheritance.

In the current case, a StudentClass has been declared and defined. The first benefit here is that a programmer trusts that previous classes are already tested so this code does not have to be reviewed. The next benefit is that the programmer starts with a student class and extends or derives (i.e., inherits) that class to a more specifically focused kind of student, which is a college student. It is specified that the college student is a specialized case of a student, so this is referred to as an ISA condition. The college student IS A student, but has extended capabilities.

In contrast, the StudentClass has a dynamically allocated name which leads to the the term HASA. The StudentClass HAS A dynamically allocated C-Style string. To be clear, the name is not a kind of student; it is just one of the data items. Another example is that a motorcycle or automobile are specific kinds of vehicles. Therefore, it would be said that an automobile ISA vehicle, which HASA steering wheel. Make sure you can clearly understand and identify the difference between the ISA and HASA conditions.

In the previous section of this reference, we looked at a StudentClass. What if we wanted to extend this StudentClass to become a specific student such as a college student? In C++, this is pretty easy to do, and here is what that would look like:

class CollegeStudentClass: public StudentClass
{

}

Declaration/Header File

Much of the rest of the code looks like the code you would use for any other class but there are some tricks. Start with the normal stuff, shown here:

class CollegeStudentClass: public StudentClass
{

public:

// class constants

// none

// constructors

// default
CollegeStudentClass();

// initialization
CollegeStudentClass ( const char *name, int inId,
char inGender, int qPoints, int tCredits );

// copy
CollegeStudentClass( const CollegeStudentClass &copied );

// destructor

~CollegeStudentClass( );

// overloaded operators

// None

// accessors
double getGpa() const;

// mutators/modifiers
void setQualityPoints( int qPoints );
void setTotalCredits( int tCredits );

private:

// methods
// none

// data
int qualityPoints;
int totalCredits;
};

Here is a brief overview of the inherited class.

This new class will rely on the original, or parent StudentClass to handle the name, student ID, and gender, and the derived, or child CollegeStudentClass will handle the items specific to the new class.

Definition/Implementation File

The implementation file will look very much like the one from the StudentClass so that will not be covered here in the text, although it will be provided in the video. However, there are a few interesting things about the constructors, so they will be provided here.

The default constructor. Here is the code for the default constructor. Note that no action needs to be taken for the StudentClass data because this inherited constructor will automatically call the parent's default constructor as part of the process.

/*
Name: CollegeStudentClass - default constructor
Process: initializes all data to default states
Function Input/Parameters: none
Function Output/Parameters: none
Function Output/Returned: none
Device Input: none
Device Output: none
Dependencies: none
*/
CollegeStudentClass::CollegeStudentClass
(
// data loaded via initializers
)
: qualityPoints( 0 ), totalCredits( 0 )
{
// other default data is set in the parent class
}

The initialization constructor. Here is the code for the initialization constructor. In this case, the constructor can set the CollegeStudentClass data with the intializer list but it must set the StudentClass data with mutator methods since the StudentClass data is private and not directly accessible to the child class. This constructor, as all the constructors, would still call the parent's default constructor but for the initialization case, the data must all be overwritten.

/*
Name: CollegeStudentClass - initialization constructor
Process: initializes all data to parameters
Function Input/Parameters: name (char *), student id (int),
gender (char), gpa (double)
Function Output/Parameters: none
Function Output/Returned: none
Device Input: none
Device Output: none
Dependencies: setName, setGender, setStudentId
*/
CollegeStudentClass::CollegeStudentClass
(
const char *inName, // in: student name
int inId, // in: student id
char inGender, // in: student gender
int qPoints, // in: quality points
int tCredits // in: total credits
)
: qualityPoints( qPoints ), totalCredits( tCredits )
{
// set name in parent class
// function: setName
setName( inName );

// set gender in parent class
// function: setGender
setGender( inGender );

// set student ID in parent class
// function: setStudentId
setStudentId( inId );
}

The copy constructor. The copy constructor conducts the same operations as the initialization constructor but all the data is acquired from the parameter copied object. Note again here that the copied object is passed by reference so that only its address is passed to the method instead of all the class data. Take a look.

/*
Name: CollegeStudentClass - copy constructor
Process: initializes all data from copied object
Function Input/Parameters: copied object (CollegeStudentClass &)
Function Output/Parameters: none
Function Output/Returned: none
Device Input: none
Device Output: none
Dependencies: setName, setGender, setStudentId
getName, getGender, getStudentId
*/
CollegeStudentClass::CollegeStudentClass
(
const
CollegeStudentClass &copied // in: copy of CollegeStudentClass object
)
: qualityPoints( copied.qualityPoints ), totalCredits( copied.totalCredits )
{
// set name in parent class
// function: setName
setName( copied.getName() );

// set gender in parent class
// function: setGender
setGender( copied.getGender() );

// set student ID in parent class
// function: setStudentId
setStudentId( copied.getStudentId() );
}

Wrapping Up Inheritance

There is so much more that can be discussed about inheritance but it is not necessary to go very far for purposes of this reference. You should know two things: 1) What inheritance is and the parent/child relationship involved, and 2) how to implement it at least at a fundamental level.

The industry perspective is not consistent. In some cases, a software development company can buy a class or set of classes that are verified and tested, and then derive classes from the purchased ones as needed. While the cost of this kind of software is usually significant, it is ordinarily not as expensive as starting from scratch, and then developing and testing this kind of product. On the other hand, inheritance can get pretty complicated pretty fast. It is always a judgement call to use it but your knowledge and understanding of the tools and the company goals is why you will be paid well.

The videofor this topic will round out what is not provided on this page, and will provide you more opportunity to practice writing this advanced form of code. The only thing remaining to discuss is the idea of managing data whose type is not known by the managing system. This is called managing generic data and it's pretty cool. Read on.