Download as ppt, pdf, or txt
Download as ppt, pdf, or txt
You are on page 1of 30

Facultad de ciencias

físico - matemáticas

Herencia
Lunes, 28 de Febrero de 2011
Introducción
 Definición de herencia.
 Beneficios de la
herencia y el
polimorfismo.
 Clases base y clases
derivadas.
 Tipos de herencia:
simple y múltiple.
 Herencia simple
Ejemplo de herencia simple
Código de ejemplo de herencia simple

Herencia pública,
protegida y
privada1.
//POINT.H
//Definition of class Point
#ifndef POINT_H
#define POINT_H
#include <iostream>
#include <iomanip>
using namespace std;
class Point {
friend ostream &operator<<(ostream &, const Point &);
public:
Point (float = 0, float = 0); //default constructor
void setPoint (float, float); //set coordinates
float getX() const {return x;} //get x coordinate
float getY() const {return y;} //get y coordinate
protected: //accessible by derivate classes
float x, y; //x and y coordinates of the Point
};
#endif /*POINT_H*/
//POINT.CPP
//Member functions for class Point
#include <iostream>
#include "Point.h"

//Constructor for class Point


Point::Point(float a, float b)
{
x = a;
y = b;
}

//Set x and y coordinates of Point


void Point::setPoint(float a, float b)
{
x = a;
y = b;
}

//Output Point (with overloaded stream insertion operator)


ostream &operator<<(ostream &output, const Point &p)
{
output << '[' << p.x << ", " << p.y << ']';
return output; //enables concatenated calls
}
//CIRCLE.H
//Definition of class Circle
#ifndef CIRCLE_H
#define CIRCLE_H
#include <iostream>
#include <iomanip>
#include "Point.h"

class Circle : public Point { //Circle inherits from Point


friend ostream &operator<<(ostream &, const Circle
&);
public:
//default constructor
Circle(float r = 0.0, float x = 0.0, float y = 0.0);

void setRadius(float); //set radius


float getRadius() const; //return radius
float area() const; //calculate area
protected:
float radius;
};
#endif /*CIRCLE_H*/
//CIRCLE.CPP
//Member function definitions for class Circle
#include "Circle.h"
//Constructor for Circle calls constructor for Point
//with a member initializer then initializes radius.
Circle::Circle(float r, float a, float b)
: Point(a,b) // call base-class constructor
{
radius = r;
}
//Set radius of Circle
void Circle::setRadius(float r){radius = r;}
//Get radius of Circle
float Circle::getRadius() const {return radius;}
//Calculate area of Circle
float Circle::area() const
{ return 3.14159 * radius * radius;}
//Output a Circle in the form:
ostream &operator<<(ostream &output, const Circle & c)
{
output << "Center = [" << c.x << ", " << c.y
<< "]; Radius = " << setiosflags(ios::showpoint)
<< setprecision(2) << c.radius;
return output; //enables concatenated calls
}
Point *pointPtr, p(3.5, 5.3);
Circle *circlePtr, c(2.7, 1.2, 8.9);

cout << "Point p: " << p << "\n Circle c: " << c << endl;

//Treat a Circle as a Circle (with some casting)


pointPtr = &c; //assign a address of Circle to pointPtr
circlePtr = (Circle *) pointPtr; //cast base to derived
cout << "\n Area of c (via circlePtr): "
<< circlePtr->area() << endl;

//DANGEROUS: Treat a Point as a Circle


pointPtr = &p; //assign address of Point to pointPtr
circlePtr = (Circle *)pointPtr; //cast base to derived
cout << "\n Radius of object circlePtr points to: "
<< circlePtr->getRadius() << endl;
Point p: [3.5, 5.3]
Circle c: Center = [1.2, 8.9]; Radius =
2.7

Area of c (via circlePtr): 23.

Radius of object circlePtr points to:


5.3e+036
Herencia múltiple (MI en inglés)
Problema del diamante
Posibles errores
Herencia virtual
class Base {
 public:
   ...
 protected:
   int data_;
};

class Der1 : public virtual Base {
 public:             ^^^^^^^—this is the key
   ...
};
class Der2 : public virtual Base {
 public:             ^^^^^^^—this is the key
   ...
};
Herencia virtual…continuación
 class Join : public Der1, public Der2 {
 public:
   void method()
   {
      data_ = 1;  ← good: this is now unambiguous
   }
 };
 
 int main()
 {
   Join* j = new Join();
   Base* b = j;   ← good: this is now unambiguous
 }
Jerarquía de clases
Algunas disciplinas para usar MI

 Usar herencia sólo para remover


sentencias if/switch.
 Hacer uso de preferencia de clases base
abstractas al derivar de ellas.
 Considerar otras posibles mejores
alternativas; patrón “puente”,
generalización anidada.
Explicación detallada
 Suponga los siguientes conceptos.

 Vehículos  Combustible
 Terrestres.  Gasolina.
 Aéreos.  Eólico.
 Acuáticos.  Nuclear.
 Espaciales.  Mecánico.
Patrón puente

analysis Business Process Model

Vehiculo Motor

- _motor: Motor *

Espacial Terrestre Aereo Acuatico


Gasolina Eolico Nuclear Mecanico
Generalización anidada
 Considerando el tipo de vehículo como
jerarquía primaria, tenemos:
analysis Business Process Model

Vehiculo

Espacial Terrestre Aereo Acuatico

VehiculoEspacialAGasolina VehiculoEspacialEolico VehiculoEspacialNuclear VehiculoEspacialMecanico


Herencia múltiple

analysis Business Process Model

VehiculoEspacial VehiculoTerrestre VehiculoAereo VehiculoAcuatico VehiculoAGasolina VehiculoEolico

VehiculoEspacialAGasolina VehiculoEspacialEolico VehiculoEspacialNuclear VehiculoEspacialMecanico


Fuentes
 “Como programar en C++”, H.M. Deitel/ P.J. Deitel, Segunda
edición.
 “How to program C++” , H.M. Deitel/P.J. Deitel, sixth edition.
 http://www.parashift.com/c++-faq-lite/smalltalk.html
 http://www.cplusplus.com/doc/tutorial/inheritance/
 1http://www.parashift.com/c++-faq-lite/private-inheritance.html

 http://www.parashift.com/c++-faq-lite/multiple-
inheritance.html#faq-25.8
 https://knowledge.elementk.com
Evidencia 1
 1 2.10 (Account Inheritance Hierarchy) Create an
inheritance hierarchy that a bank might use to represent
customers’ bank accounts. All customers at this bank can
deposit (i.e., credit) money into their accounts and withdraw
(i.e., debit) money from their accounts. More specific types
of account salso exist. Savings accounts, for instance, earn
interest on the money they hold. Checking accounts, on the
other hand, charge a fee per transaction (i.e., credit or
debit). Create an inheritance hierarchy containing base
class Account and derived classes SavingsAccount and
CheckingAccount that inherit from class Account. Base
class Account should include one data member of type
double to represent the account balance.
 The class should provide a constructor that receives an initial
balance and uses it to initialize the data member. The constructor
should validate the initial balance to ensure that it is greater than or
equal to 0. 0. If not, the balance should be set to 0. 0 and the
constructor should display an error message, indicating that the
initial balance was invalid. The class should provide three member
functions. Member function credit should add an amount to the
current balance. Member function debit should withdraw money
from the Account and ensure that the debit amount does not exceed
the Account’s balance. If it does, the balance should be left
unchanged and the function should print the message "Debit
amount exceeded account balance. "
 Member function getBalance should return the current
balance. Derived class SavingsAccount should inherit
the functionality of an Account, but also include a data
member of type double indicating the interest rate
(percentage) assigned to the Account. SavingsAccount’s
constructor should receive the initial balance, as well as
an initial value for the SavingsAccount’s interest rate.
SavingsAccount should provide a public member
function CalculateInterest that returns a double indicating
the amount of interest earned by an account. Member
function CalculateInterest should determine this amount
by multiplying the interest rate by the account balance.
 [Note: SavingsAccount should inherit member functions credit and
debit as is without redefining them.] Derived class CheckingAccount
should inherit from base class Account and include an additional
data member of type double that represents the fee charged per
transaction. CheckingAccount’s constructor should receive the initial
balance, as well as a parameter indicating a fee amount. Class
CheckingAccount should redefine member functions credit and debit
so that they subtract the fee from the account balance whenever
either transaction is performed successfully. CheckingAccount’s
versions of these functions should invoke the base class Account
version to perform the updates to an account balance.
 CheckingAccount’s debit function should charge a fee
only if money is actually withdrawn (i.e., the debit
amount does not exceed the account balance). [Hint:
Define Account’s debit function so that it returns a bool
indicating whether money was withdrawn. Then use the
return value to determine whether a fee should be
charged.] After defining the classes in this hierarchy,
write a program that creates objects of each class and
tests their member functions. Add interest to the
SavingsAccount object by first invoking its
CalculateInterest function, then passing the returned
interest amount to the object’s credit function.

You might also like