Introduction to Inheritance by HC121104002213

VIEWS: 0 PAGES: 29

									Introduction to Inheritance
               Objective
• Understand inheritance
• Be able to override base class member
  functions
            Classes So Far
• Creating class provides way to create new
  type of object composed of one or more
  old types
  • Called composition
  • Has-a relationship
    • Point has an x value, has a y value
       Classes the New Way
• Using Inheritance
  • Is-a relationship
• Have ClassA, ClassB inherits from ClassA
  • ClassB is a more specific type of ClassA
What Are You?
     EE Major


    Midshipman


   College Student


    Young Adult


       Human
 Simple Programming Example
• TradStack defines templated stack
  following traditional stack ADT
• Now need new stack<string>
  • But Dr Crabbe insists it have a popuntil(x)
    function
    • Apparently it’s important to artificial intelligence
    • Pops from stack until it pops off value equal to x
              CrabbeStack
• Dr Crabbe’s stack has everything
  TradStack has, plus more
• It is a stack
  • More specialized stack
• We can use new thing we learned…
               CrabbeStack Example
#include <string>
#include "TradStack.h"
using namespace std;

class CrabbeStack : public Stack<string> { declares CrabbeStack is a stack
  public:                                             of strings (i.e. a Stack<string> object)
   void popuntil(string x) {  declares, in addition to usual Stack<string> stuff, it's got
     bool found = false;     popuntil function
     while(!isEmpty() && !found)  since CrabbeStack is a Stack<string>, it has isEmpty
      found = (pop() == x);          member function
   }
};
             IMPORTANT
• "class CrabbeStack : public Stack<string>"
  declares that CrabeStack is new class
  derived from (i.e. inherits from) class
  Stack<string>
• Means can do anything with CrabbeStack
  object can do with Stack<string>
                    Usage Example
#include "CrabbeStack.h"
int main() {
  CrabbeStack S;
  cout << "Enter strings terminated with \"end\": ";
  string s;
  while(cin >> s && s != "end")
   S.push(s);
  cout << "What's in there is: ";
  while(!S.isEmpty())
   cout << S.pop() << ' ';
  cout << endl;                          Can do anything with CrabbeStack that
  return 0;                              you can do with traditional stack
}
                         Usage Example
#include "CrabbeStack.h"
int main() {
  CrabbeStack S;
  cout << "Enter strings terminated with \"end\": ";
  string s;
  while(cin >> s && s != "end")
   S.push(s);

    cout << "Enter one of your strings: ";
    cin >> s;                                But can also use popuntil
    S.popuntil(s);

    cout << "What's left is: ";
    while(!S.isEmpty())
     cout << S.pop() << ' ';
    cout << endl;
    return 0;
}
              Inheritance
• When a class is derived from another it
  “inherits” all data members & member
  functions from its parent
                 Terms
• Parent – base class – super class
• Child – derived class – sub class
                                Old Friend
#ifndef _Point_
#define _Point_
#include <iostream>
#include <cmath>
using namespace std;
//-- class Point --------------------------------//
class Point {
  private:
    double x,y;
  public:
    Point(double a = 0, double b = 0) : x(a), y(b) { }
    double magnitude() { return sqrt(x*x + y*y); }
    void write() { cout << '(' << x << ',' << y << ')'; }
    void read() { char c; cin >> c >> x >> c >> y >> c; }

   //-- overloaded arithmetic and i/o operators ----//
   friend Point operator-(Point,Point);
   friend Point operator+(Point,Point);
   friend Point operator*(Point,double);
   friend Point operator/(Point,double);
}; #endif
              But Need More
• Point is pretty good
• But doesn’t give all we need
• Maybe would like Point that has label
  • Why rewrite Point just to add label
  • Or just cut & paste
     • Lots of copies of same thing = bad
  • Inheritance!
                  LPoint
• LPoint (labeled point) is a point, but has a
  label
• Like CrabbeStack added a function LPoint
  can add a data member
                       class LPoint : public Point {
                       private:
                       char label;
                       };
                          Problem   class LPoint : public Point {
                                    private:
                                    char label;
• LPoint is a Point                 };

• So we should be able to
  LPoint P(2.2,3.1);
  cout << P.magnitude() << endl;

• But we get error
  • Constructors not inherited from base class!
  • Must create constructor
class LPoint : public Point {
 private:
   char label;
 public:
   LPoint(double s = 0, double t = 0) {
         // How do we set the x and the y from the Point part of LPoint?
         label = '?';
     }
};
                   Constructors
• Could use constructor to set x & y
• Parent (Point) already did that
• We can use parent’s constructor
      class LPoint : public Point {
        private:
         char label;
        public:
         LPoint(double s = 0, double t = 0) : Point(s,t) {
           label = '?';
         }
      };
            Polymorphism
• LPoint works fine
• LPoint constructor calls Point constructor
  then adds own code
• Now can even use LPoint where Point is
  needed because LPoint is a Point
  • Need a human? A midshipman will do
     Polymorphism Example
LPoint P(2.0,-1.5);
cout << P.magnitude() << endl;
Point A(3.0, 2.5), B;
B = P + A;
A.write();
B.write();
P.write();
  Overriding Inherited Member
           Functions
• Think of this…you have classW derived
  from classHW
• ClassHW has function loveBarabara()
• You want classW to have loveBarbara()
  • But it should NOT do the same thing
        Modifying Behavior
                            class LPoint : public Point {
                              private:
                               char label;
• Back to the Point…          public:
                               LPoint(double s = 0, double t = 0) : Point(s,t) {
                                 label = '?';
                               }
                            };




• We can write a program that use labeled
  points like this:
                  LPoint P1('a',0.5,2.0), P2('b',1.0,1.5);
                  Point M = (P1 + P2)/2;
                  M.write();
                  P1.write();
                  P2.write();
                  Where is the Label?
CODE:                                      class LPoint : public Point {
LPoint P1('a',0.5,2.0), P2('b',1.0,1.5);     private:
Point M = (P1 + P2)/2;                        char label;
M.write();                                   public:
                                              LPoint(double s = 0, double t = 0) : Point(s,t) {
P1.write();                                     label = '?';
P2.write();                                   }
                                           };
                                     class Point {
                                       private:
                                        double x,y;
OUTPUT:                                public:
(.75,1.75)(.5,2)(1,1.5)                 Point(double a = 0, double b = 0) : x(a), y(b) { }
                                        double magnitude() { return sqrt(x*x + y*y); }
                                        void write() { cout << '(' << x << ',' << y << ')'; }
                                        void read() { char c; cin >> c >> x >> c >> y >> c; }
                                        //-- overloaded arithmetic & i/o operators ----//
                                        friend Point operator-(Point,Point);
                                        friend Point operator+(Point,Point);
                                        friend Point operator*(Point,double);
                                        friend Point operator/(Point,double);
                                     };
                       Why?
• Call to LPoint’s write() is really call to
  Point’s write()
• Point doesn’t know about labels

• We need to change LPoint’s write()’s
  behavior
  • Override write()
            Overriding Functions
• Redefine member function from base calls
  inside derived class
• Call to function in derived class will
  execute derived class’s version NOT base
  class’s version
   class LPoint : public Point {
     private:
      char label;
     public:
      LPoint(char c = '?', double s = 0, double t = 0) : Point(s,t) { label = c; }
      void write() {
        cout << label << ':' << '(' << x << ',' << y << ')';
      }
   };
                        SWEET!
• But we get and error :-(
• Problem is we are trying to access x &y
  • They are private data members of Point
  • Cannot be accessed outside of Point
• Need to access x &y from inside Point, not
  from inside LPoint
  • Use full name of write() inside Point
     • Point::write()
        Updated LPoint
class LPoint : public Point {
  private:
   char label;
  public:
   LPoint(char c = '?', double s = 0, double t = 0) :
Point(s,t) { label = c; }
   write() {
     cout << label << ':‘;
     Point::write();
   }
};
Questions?

								
To top