Sie sind auf Seite 1von 30

Problem Solving

Inheritance

INTERNAL
April 06, 2009

Problem Context
Connection manager
A local grocery shop in our society is an authorized distributor for GSM mobile connections for Talk the Talk" service provider. The shop sells new connections, provide easy recharge, topups and monthly payments. The shopkeeper has got his personal account which keeps track of the balance amount for easy recharge and topups. The shop also maintains an inventory of new connections and the connections sold in the locality for audits and reports. Talk the Talk offers various plans for convenience of usage in terms of charge per pulse rate. Mr X and Mr Y are two friends decide to take new connections, visits the shop. Mr Y decides to take prepaid connection and Mr X gets convinced for a postpaid connection. Mr Y gets initially recharged with INR 200 and a topup of INR 20 and Mr X was charged INR 500 for connection. The usage of Mr Y is limited by the amount available on last topup and will have to put topups till validity of the card. Incase validity of the connection expires he needs to recharge again. The amount deducted as per the usage and the pulse rate plan. Mr X is charged monthly with a rental of INR 200 in addition with a charge the total usage (duration recorded) and the pulse rate plan. If not paid the connection is deactivated till payment.

-2-

OOP Orientation INTERNAL

Visualization of the scenario

Connection

Plan PostPaid Connection

Plan PrePaid Connection

INR 0.01 / sec Connection# : 96XXXXXX06 Mr X Validity Status: Valid Monthly Rent: INR 200 Recorded Pulse : TBD
-3-

INR 0.02 / sec Connection# : 81XXXXXX10 Validity Status: Valid Recharge: INR 200 Top Up: INR 20

Mr Y

OOP Orientation INTERNAL

Layers of System in real world


The Real World user Interactions
Layer1: Interaction with Mr X and Mr Y and they speak Mr X and Mr Y get new connections (96XXXXXX06 & 81XXXXXX10) and activated with respective plans (INR 0.01/sec and INR0.02/sec) Layer2 : Interaction with Service Provider and he says Talk the Talk provides Prepaid connections which needs recharge and topup as per assigned Plan. Talk the Talk provides Postpaid connections which needs monthly rental and usage payment as per assigned Plan. Layer3: Interaction with Shopkeeper and he says Shopkeeper sells new Connections to Customers and manages inventory and records for Customers, Connections, Plans.

Each user interaction layer describes the system at different level of abstractions: Mr X and Mr Y [Layer 1] -> Customer [Layer 3] 96XXXXXX06 [Layer 1] -> Prepaid [Layer 2] 81XXXXXX10 [layer 1] -> Postpaid [layer 2] INR 0.01/sec & INR0.02/sec [layer 1] -> Plan [Layer2 & Layer3] Prepaid & Postpaid [Layer2] -> Connection [Layer3]

-4-

OOP Orientation INTERNAL

Inheritance
Inheritance is to visualize the system in different layers of abstraction Each layer of abstraction is taken from different stakeholders involved in that system The system can be designed at each layer by leveraging abstraction (knowing and doing responsibilities) Example : Shopkeeper can maintain inventory of Connections. The connections can be Prepaid or Postpaid, and can be further be elaborated as the actual connections.

The approach of inheritance is bottom up. The bottom most layer is concrete and the top most layer is abstract. The concrete layer reuses and refines the abstraction [knowing and doing responsibilities] of abstract layer. Since abstract classes cannot have definitions, we cannot create its instances*, the instances can be only for concrete classes. The abstractions can be realized through the objects of concrete classes, only if it is an IS_A type of relationship.

-5-

OOP Orientation INTERNAL

Inheritance

In a is-a relationship child inherits abstractions of the parent In a is-a class hierarchy A child class of one parent can be the parent of another child Common features should be put as high in the hierarchy as is reasonable. The is-a relationship is transitive Example: 96XXXXXX06 is a PostPaid Connection, where PostPaid Connection is a Connection, thus 96XXXXXX06 is a Connection

-6-

OOP Orientation INTERNAL

Inheritance

Its the generalization/specialization relationship between classes. The inheriting class inherits all the methods and fields of the class it inherits from. The code of the inheriting class consists only of the changes and additions to the base class. If class B inherits from class A, then objects of class B are also of type A. It must make sense to call the methods of class A on an object of class B.

-7-

OOP Orientation 7 INTERNAL

Class Relationship
Plan pulseRate : double getPulseRate : double Connection Number : string activeStaus : bool calculateTotalAmount :double

getPulseRate : double
PrePaid recharges : Recharge [] topups : Topup [] PostPaid callRecords : Duartion [] monthlyRental : double billingAmount : Rental [] calculateTotalAmount :double calculateTotalRental :double calculateBillingAmount : double

calculateTotalAmount :double
calculateTopupAmount : double calculaterechargeAmount : double

-8-

OOP Orientation INTERNAL

Derived Classes
A derived class inherits properties of its base class / classes which includes its data members and member functions. The inherited base class function can be redefined in the derived class. New members can be added to the derived class. Members of the base can be referred to as if they were members of derived class.

OOP Orientation INTERNAL

Derived Classes (contd.)


class Connection { //Attributes defines the state: string number; protected: bool activeStatus; public: Connection(string number) { this->number = number; this->activeStatus = false; }// A constructor that initializes the fields double getPulseRate(){ Invokes the constructor //method definition } of Connection }; class Prepaid : public Connection { //Attributes //Methods define Behaviours of Objects public: Prepaid(string number) : Connection(number){ } string getNumber(){ return number;} // Gives error as number is private in super class bool getStatus(){ return activeStatus;} OOP Orientation - 10 }; INTERNAL

Derived Classes (Contd)

Private Members of the base class are not accessible to the derived class. Protected members of the base class can be used in the member functions of the derived class. Public members of the base class are accessible to the member of the derived class but may or may not be a accessible to the external users. What is not inherited? Base class constructor Base class destructor Friends

OOP Orientation INTERNAL

Multiple Inheritance
A Research Scientist in a University is an Employee of the University as he assists in teaching and get paid for it as well as a Student of the University attending lectures and sessions on various courses. Thus a class may be derived from any number of base classes class Employee {}; class Student {}; class ResearchScientist : public Employee, public Student {};

A class cannot be specified as a direct base class of a derived class more than once. For e.g. class A{}; class B{}; class C{}; class D : public A,public B public A // error {};
Indirect inheritance more than once is allowed. class L{}; class A ; public L {}; class B ; public L {}; class C : public A, public B {}; The object of C will have two sub-objects of class L.

C
OOP Orientation INTERNAL

Virtual base class

The problem of multiple copies of base class in child class is solved by making the base class virtual base class.

Grand parent

Parent1

Parent2

Child

OOP Orientation INTERNAL

Virtual base class


class A //Grand parent { }; class B: virtual public A //Parent 1 { .. }; class C: virtual public A //Parent2 { ------\ }; class D: public B, public C { //Only cone copy of A will be inherited }

OOP Orientation INTERNAL

Public and private inheritance


When a class is inherited by a derived class, the private members of the base class are not inherited. If a class inherits from the base class using public, the public data remains public and protected data becomes protected. If the derived class inherits the base class using protected, all the public data and protected data of base class become protected in child class. If a class inherits from the base class using private, all the public data and protected data become private.

OOP Orientation INTERNAL

Example
class employee { char *name; short age; short department; float salary; public; void print _ Name (); }; /* Public inheritance for class Manager*/ class Manager : public employee { int level; public ; void print _ level (); }; class Branch_Manager : public Manager { char * branch; public : void print(); }; void Branch_Manager :: print (){ print_Name (); print_level (); printf (%s,branch); }

/*Private inheritance for Manager in the same example*/ class Manager : employee { int level; public : void print (); };
void Branch Manger :: Print() { print Name(); inheritance print_level (); printf (%s,branch); }

// error private

OOP Orientation INTERNAL

Public and private inheritance

Good practices: Public inheritance signifies is a relation ship and it is an instance of interface inheritance. Private inheritance on the other hand is an implementation inheritance.

OOP Orientation INTERNAL

Static Members are not inherited


Class A { public: static a; } Class B : public A{}; Class C : public A{}; Class D : public B,public A{}; D pd; pd.a = 1; // OK a is a static Hence, no ambiguity Static members are not inherited.

OOP Orientation INTERNAL

Constructor rule for inheritance


Constructor of Base cannot be inherited. For a class derived from another class that has constructors in it : The constructors of the derived class must pass parameters to anyone, of the base class constructors, if no default constructor is defined. class Employee { char *name; int age; public; Employee( ){ name = Mr X; age = 20; } Employee(char *name, int age){ this->name = name; this->age = age; } void printName (); }; class Manager : public Employee { int level; public ; Manager(){ level = 2; } // Default Constructor of Employee class is called first Manager(char *name, int age, int level) : Employee(name,age) //Invoking parameterized constructor of Employee { this->level = level; } void print _ level (); };
OOP Orientation INTERNAL

Multiple Inheritance
Class A { public : A (int); }; Class B { public : B (char *); }; Class C : public A, public B { Public : C(int, char *); }; C :: C (int c, char *s) : A ( c ),B(s) {}

OOP Orientation INTERNAL

Destructor rule for Inheritance


Destructors of the base classes cannot be inherited. Destructors for derived classes - Should only do clean up required for itself - Should not worry about clean up related to inherited properties Destructor of base class is automatically called after the destructor derived class.
e.g., class Employee { protected : char *name; public : Employee (char *s) (name = strdup (s);} ~ Employee () {if (name) free (name);} };

class Manager : public Employee { char *dname; public : Manager (char *s) : Employee(s) { dname = new char [20]; strcpy (dname ,OOP;} ~ Manager() {if dname) delete dname;} }; main () { Manager Tom (string) // calls constructor of Employee and then the constructor of Manager // calls destructor of Manager then the destructor of Employee }

OOP Orientation INTERNAL

Destructor rule for Inheritance (Contd)


class employee { char *name; short dept; public : employee (char *nam,short dpt) { name = strdup (nam); dept = dpt; } ~employee () {free (name);} }; class manager : public employee { char * area_name; public : manager (char *nam, short dpt,char *amam); ~manager(); }; manager :: manager (char *nam, short dpt,char *amam) : employee (nam, dpt) { area_name = strdup (amam); } Manager :: ~manager () { free (area_name); }
OOP Orientation INTERNAL

Copy Constructors
The copy Constructor of a derived class calls the copy constructor of the base class first and then the copy constructor of its own class. If the derived class does not have a user-defined copy constructor and base class has a user-defined copy constructor, the base class user-defined copy constructor is called first and then the default copy constructor derived class. Class A { public : A (A&); // user-defined copy constructor A (int); }; Class B:public { public : B (int); }; B b(3); //call B :: B(int) B bb =b; //calls the copy construtor A :: A (A&) and then the //default copy constructor of B ie B :: B(B&)

OOP Orientation INTERNAL

Inheritance and Pointers


class A{ int a; public: func(){cout<<"A"<<endl;} A(){a=100;} }; class B : public A { public: int b; func(){cout<<"B"<<endl;} B(){b=200;} }; main() { A * ptrA = new B; //Base class pointer pointing to an instance of a child class. ptrA->func(); // executes A::func() cout<<ptrA->b<<endl; //Error; Why is this wrong? A a; B *ptrB =(B*)&a; //Pointer of a child class pointing an instance of the base class!! Bad practice. cout<<ptrB->b<<endl; ptrB->func(); // executes B::func() }

OOP Orientation INTERNAL

Virtual functions
class Animal{ public: virtual void whoAreYou(){cout<<"Me, Animal"<<endl;} }; class Cat : public Animal { public: void whoAreYou(){cout<<"Me, Cat"<<endl;} }; main() { Animal * ptr1 = new Cat; //Base class pointer pointing to an instance of a child class. ptr1->whoAreYou(); // Me, Cat Animal a; Cat *ptr2 =(Cat*)&a; //Pointer of a child class pointing an instance of the base class!! Bad practice. ptr2->whoAreYou(); // Me, Cat }

OOP Orientation INTERNAL

Virtual functions
If a base class contains a virtual functions f which is re-defined in the derived class, then a call f() for an object of derived class invokes derived::f() even if access is through the a pointer of base class. Run time polymorphism is achieved using virtual functions.

OOP Orientation INTERNAL

Virtual functions
class A { public: virtual void f(){cout<<A<<endl;} }; class B { public: virtual void g(){ cout<<B<<endl;} }; class C : public A, public B { public: void f(){cout<<C<<endl;} void g() { cout<<C<<endl;} }; main() { C cc; A* ptrA=&cc; B* ptrB= &cc; ptrA->f(); ptrB->g(); }

OOP Orientation INTERNAL

Access control for virtual functions


The access controls of a virtual function are determined by its declaration and not affected by rules for a function that later override it!! class A{ public: virtual void who(){cout<<"A"<<endl;} };

class B: public A { private: void who(){cout<<"B"<<endl;}


}; void main() { A* ptrA= new B; ptrA->who(); B* ptrB= new B; ptrB->who(); //This wont do!! } ptrA will be able to access who() defined in the derived class although it is placed under private. However, ptrB will not be able to access it since it is declared private.

OOP Orientation INTERNAL

Explicit scope resolution

An inheriting class that redefines virtual function can call the function of its parent class by calling it explicitly using scope resolution operator. class A{ public: virtual void who(){cout<<"A"<<endl;} }; class B: public A { private: void who(){cout<<"B"<<endl; A::who();} };

OOP Orientation INTERNAL

Happy Learning !

Das könnte Ihnen auch gefallen