Inheritance & Polymorphism

Inheritance

What is inheritance good for?

Class Relationships: Has-a vs. Is-a

General syntax

To declare a derived (child) class use class DerivedClass : access BaseClass

Using protected access specifier on fields and methods

Access mode member/class combinations

Access specifiers on members of the base class
private protected public
private inheritance The member is inaccessible. The member is private. The member is private.
protected inheritance The member is inaccessible. The member is protected. The member is protected.
public inheritance The member is inaccessible. The member is protected. The member is public.

Constructors destructors and inheritance

class A {
protected:
    double d;
public:
    A(double num = 0): d(num) { };
};

class B : public A {
private:
    int b;
public:
    // implicitly invokes default A():
    B(int val = 0): b(val) { };

    // Put A(dval) in initializer list to call non-default constructor of A:
    B(int bval, double dval): A(dval), b(bval) { };
};
Constructor and destructor execution order with inheritance

Virtual member functions

Virtual functions

Overriding vs overloading vs hiding

Other details

Implicit conversions between base and derived classes

Derived class objects can be passed as base class objects - will implicitly slice off any derived class fields:
void poly(Point2D p)
{ // .. p will just be a true 2D point
}      
int main()
{
     Point3D p3(30, 40, 50);
     poly(p3); // 3D point will be copy converted to 2D point - z gone
}
Also derived class references can be passed as base class references - derived class fields implicitly there for virtual methods to "see"
void poly(Point2D &p)
{ // .. p will still have the z field
}      
int main()
{
     Point3D p3(30, 40, 50);
     poly(p3); // reference to 3D point passed
}
Similarly to references, base class pointer types can also point to derived class objects:
void poly(Point2D *p)
{ // .. *p will still have the z field
}      
int main()
{
     Point3D p3(30, 40, 50);
     poly(&p3); // address of 3D point passed
}

Explicit type conversions

Syntax:
Base * base;
dynamic_cast<Derived*>(base);
Other forms of more hazardous cast that should be used sparingly

Abstract base classes

Defining abstract base classes with pure virtual functions Other lesser points about coding abstract classes Declared variables of abstract classes

Multiple Inheritance

Multiple inheritance means subclass class can be derived from multiple base classes. A simple example of multiple inheritance for an interface:
class Widget
{
public:
    virtual void click();
    virtual void update();
};

class Drawable
{
public:
    virtual void draw() = 0; // Drawable is an abstract class with no code
  
};

class Snowman : public Widget, public Drawable
{
    void draw(); // override pure virtual draw to draw Snowman
};

class Bunny : public Widget, public Drawable
{
    void draw(); // override pure virtual draw to draw a Bunny
};

void fun(Drawable &d) // d can be either a Snowman or a Bunny - both "have the Drawable interface"
{
    d.draw();
}

The Diamond Problem

A thorny issue for any language supporting multiple inheritance is the following scenario:
     A
  /     \
 B       C
  \     /
     D
Example:
class Person {
public:
    long getSSN() { return SSN; };
private:
    long SSN;
};

class Employee : public virtual Person {     };
class Student : public virtual Person {     };
class GradAsst: public Employee, public Student {     };

int main()
{
    GradAsst  ga;
    ga.getSSN();  // not ambiguous with virtual above; remove virtual and get error
}