Inheritance

Door Class

object type:

  • Door

attributes:

  • Open or close

methods:

  • Init as closed door

  • Open if possible

  • Close

  • State if opened

// A generic door class (Door.h)
#pragma once
class Door {
protected:
  bool shut_;
public:
  Door(); // Constructs a shut door
  bool isOpen() const; // Is the door open?
  void open(); // Opens the door, if possible
  void close(); // Shuts the door
};

We used protected so that subclasses can use the attribute as well.

  • class: Door

  • objects: BigHouseDoor, BathroomDoor

New Feature - version 2.0

Now the manager has added another feature to implement: track how many door at every instance of the game

An inexperienced would solve the problem by using a global variable and increment each time we added a new door and viceversa.

  • This complicates the process and can cause errors later down the road.

  • This also contradicts the OOD principle

Solution

Definition of a static class that is a friend. That counts the amount of doors at run and is incremented by the constuctor of each new door and decrements in the destructor.

Remember: A static method is part of the class and only one instance exists and not a different one for each object

Added features

  • ~Door() will decrement each time a door is removed

  • the static variable count_

  • static method getDoorCount, returns count_

Remember: the static variable must be defined init in the .cpp file

Inheritance - version 3.0

There are 2 ways to use a class:

  • make a new instance of the class (what we did until now)

  • Inherit from an existing class

Question

Which fields and methods from the base class can be accessed from the derived class?

Answer

public and protected

Therefore, each sub-class of Door can use every method and variable of Door

Example of sub-class

In a game there may be many types of doors. Here we will design a door with a lock

object type:

  • LockableDoor

attributes:

  • Open or close

  • Locked or not locked

methods:

  • Init as closed door and locked

  • Open if not locked

  • Close

  • State if opened

  • Lock

  • Open lock

  • State if locked

Notice: that this is more compact that Door.h this is because we will reuse Door and dont have to redefine everything a second time.

when we inherit using public before Door we can access any public and protected variables and methods. If not specified the default is private

We could also inherit from multiple classes as so:

Lets now define our .cpp file

and our main.cpp

or in one file for simplicity

What is the size of the following?

This question was asked to me by a fellow student

As we can see even though b doesn't have access to i (unless we use a setter/getter) it will still use memory

Inheritance: order of construction / destruction

Class objects are constructed from the bottom up:

  1. The base.

  2. The members (may want to use init list)

  3. The derived class itself

They are destroyed in the opposite order:

  1. The derived class itself.

  2. The members.

  3. The base.

How to rember: Think about this, first someones parents were born and then him (construction). Now this makes alot of sense because our parent class probably has to initialize a few fields and only after can we use them.

In our LockableDoor example

  1. Doors' constuctor, which inits shut_ and count_

  2. Initialize _locked

  3. LockableDoor constuctor which is empty

Base and Derived Compatibility

Lets say we have 2 functions and 2 objects

Giving a derived type to a base type is compatible

The opposite is not true

and

myDoor = keyedDoor can cause object slicing, since the compiler will ignore any variables or methods not in the base type. We will explore how to solve some of the problems with virtual methods later on.

Has-a and Is-a relationship

  • Is-A relation- Interface Inheritance: creating a subtype of an existing class for purpose of setting up dynamic binding.

    • Circle is a subclass of Shape (i.e., Is-A relation).

    • A Birthday is a subclass of Date.

  • Has-A relation - Code Reuse: reusing an implementation to create a new class type.

    • Class Clock that inherits from class Window the ability to represent itself graphically. A stack is not really a subtype or specialization of Vector.

    • In this case, inheritance makes implementation easier, because there is no rewrite and debug existing code.

    • This is called using inheritance for reuse, i.e., a pseudo-Has-A relation.

Now here LockableDoor is-a Door

Adding more Classes

Build visual Chest

Makefile

main.cpp

Instructions:

  • O opens chest

  • C closes chest

  • L locks chest

  • U unlocks chest

Needs files:

  • ariel.ttf

  • chest.png

Door spritearrow-up-right

Ariel fontarrow-up-right

Another Example

C++ Inheritance examplearrow-up-right

Last updated