1 / 18

Inheritance

Inheritance Inheritance occurs when one type of entity inherits properties from another type of entity. For example, cats and dogs both inherit properties from a general class of animal known as mammals. We can represent this inheritance hierarchy as:. superclass. base class. mammals.

erol
Télécharger la présentation

Inheritance

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Inheritance Inheritance occurs when one type of entity inherits properties from another type of entity. For example, cats and dogs both inherit properties from a general class of animal known as mammals. We can represent this inheritance hierarchy as: superclass base class mammals dogs derived class subclass cats We can apply similar patterns to object oriented design. A subclass can inherit properties and methods from a superclass. In C++ we refer to a subclass as a derived class and to a superclass as a base class.

  2. Example: class Clock{public: Clock( int hours = 0, int mins = 0, int secs = 0 ); void setTime( int hours, int mins, int secs ); int getHours( void ) const; int getMins( void ) const; int getSecs( void ) const; virtual void tick( void ); virtual void display( void ) const; private: int m_hours; int m_mins; int m_secs;};

  3. The final implementation of this class is presented in the examples section of the course website. The class represents a simple clock. Now suppose we want to write a class to represent an alarm clock. An alarm clock has all the properties of a regular clock but also has functions that allow you to set the time of the alarm and to turn the alarm on or off. One approach we could take would be to copy and paste the code used to define the Clock class into new files and edit them. However, this flies in the face of our principle of code re-use. A better approach is to realize that an AlarmClockis-aClock with some additional attributes and methods. Is-a relationships can be represented using inheritance…

  4. When we say that AlarmClockis-aClock, it is like saying that a cat is-a mammal. A cat has all the properties of a mammal plus some additional properties that distinguish it from other mammals. The mammal is the superclass and the cat is the subclass. Similarly Clock is the superclass (or base class) and AlarmClock is the subclass (or derived class). Clock Alarm Clock

  5. Suppose that class B wants to inherit all of the properties and methods of class A, then class B is declared as follows: class B : public A{}; Methods of class B now have access to public methods of class A, however, they cannot access private methods or private attributes of class A. Moreover, a client of class B also has access to the public methods of class A (with the exception of constructors, the destructor and the overloaded assignment operator) since these methods are inherited by class B.

  6. Declaration of AlarmClock classclass AlarmClock : public Clock{public: AlarmClock( int hours=0, int mins=0, int secs=0 ); void setAlarmTime( int hours, int mins, int secs ); void setAlarm( bool isOn ); bool isAlarmSet( void ) const; void tick( void ); void display( void ) const; // not a complete set of operations // need accessors for alarm time private: int m_alarmHours; int m_alarmMins; int m_alarmSecs; bool m_isSet;};

  7. In addition to a constructor, we only supply methods associated with the alarm function: void setAlarmTime( int hours, int mins, int secs ); void setAlarm( bool isOn ); bool isAlarmSet( void ) const; and those that are behave differently for AlarmClock: void tick( void ); void display( void ) const; Note that when we apply the display function to a Clock object we expect to see the time. When we apply this function to AlarmClock we also want to see the time of the alarm and whether or not the alarm is set. The setTime, getHours, getMins,… functions are inherited from the Clock base class.

  8. Consider our two new data types from a client’s perspective: Clock myClock( 12, 59, 59 );myClock.display();cout << endl << endl;myClock.tick();myClock.display();cout << endl << endl; AlarmClock myAlarmClock;int secCount;myAlarmClock.display();cout << endl << endl;myAlarmClock.setTime( 12, 45, 50 );myAlarmClock.setAlarmTime( 12, 46, 0 );myAlarmClock.setAlarm( true );myAlarmClock.display();cout << endl << endl; for( secCount = 0; secCount < 10; secCount++ ) myAlarmClock.tick();

  9. Here’s the corresponding output: 12:59:59 13:00:00 00:00:00Alarm is not set.Alarm time: 00:00:00 12:45:50Alarm is set.Alarm time: 12:46:00 12:46:00Alarm is set.Alarm time: 12:46:00***ALARM***

  10. We will now implement the member functions that are specific to the AlarmClock class AlarmClock::AlarmClock( int hours, int mins, int secs ) : Clock(hours, mins, secs){ m_alarmHours = m_alarmMins = m_alarmSecs = 0; m_isSet = false; } Notice that the constructor makes a call to the base class constructor and passes on the relevant parameters. Data members that are particular to the AlarmClock class are initialized within the body of the constructor. Alternatively, these data members could be initialized using a member initialization list as follows:

  11. AlarmClock::AlarmClock( int hours, int mins, int secs ) : Clock(hours, mins, secs), m_alarmHours(0), m_alarmMins(0), m_alarmSecs(0), m_isSet(false) { } Notice that in this example, all the data members that are particular to the AlarmClock class are fundamental data types – we can therefore choose either method for initializing them. However, if a data member is an instance of a class, it should be initialized using the member initialization syntax shown above. The member initialization syntax must also be used to initialize any data members that are reference types.

  12. The constructors are called in the following order: • base class constructor- constructors for any data members of the derived class- body of the derived class constructor • So, in the current example, if a client constructs an AlarmClock object: • AlarmClock wakeMe( 14, 23, 2); • the constructors are called in the following order: • Clock(14, 23, 2) • AlarmClock(14, 23, 2) • Note that destructors are called in the opposite order of the corresponding constructors.

  13. Continuing with our implementation of AlarmClock… void AlarmClock::setAlarm( bool isOn ){ m_isSet = isOn; } void AlarmClock::display( void ) const{ Clock::display(); cout << endl << "Alarm is " << (m_isSet ? "" : "not ") << "set." << endl; … } Note that the private members of the base class are not accessible to a derived class. So, in order to print an AlarmClock time, we must call the display function in the base class.

  14. void AlarmClock::tick( void ) const{ Clock::tick(); if( getHours() == m_alarmHours && getMins() == m_alarmMins && getSecs() == m_alarmSecs && m_isSet ) { display(); cout << endl << "***ALARM***" << endl; } } Again notice that this function does not have direct access to the private data members of the base class so accessors are used to find the current time.

  15. We now have two display functions that are accessible to member functions of the AlarmClock class: Clock::display() and AlarmClock::display(). The same is true of the tick() function. We say that AlarmClock::display()overridesClock::display(). In other words, if the display() function is invoked on an object of type AlarmClock then AlarmClock::display() will be called rather than Clock::display(). Note: a function in a derived class overrides a function in a base class only if their signatures are identical – this includes the const modifier at the end of the function declaration! If two functions have the same name but their signatures are different, then the function is overloaded.

  16. Casting & Type Conversion Our AlarmClock class has an is-a relationship with its base class Clock. It is therefore no surprise that an AlarmClock object can be cast to a Clock object. However, when we do this, the attributes that are particular to an AlarmClock object (i.e., the alarm time and whether or not it is set) are lost – we call this object slicing… Clock myClock( 14, 44, 0 );AlarmClock myAlarm( 23, 19, 0 );myAlarm.setAlarmTime( 5, 23, 0 );myAlarm.setAlarm( true ); myAlarm.display();myClock = myAlarmClock; // object of type AlarmClock // assigned to object of // type clockmyClock.display();

  17. Here’s the corresponding output: 23:19:00Alarm is set.Alarm time: 05:23:00 23:19:00

  18. Note that the following assignment is not allowed: myAlarmClock = myClock; In other words, there is no way to promote a Clock object to an AlarmClock object (unless of course we supply a convert constructor). This makes sense because a Clock object is not an AlarmClock; Clock objects do not have an alarm time or a variable to indicate whether or not the alarm is set.

More Related