• No se han encontrado resultados

Programación Orientada a Objetos

N/A
N/A
Protected

Academic year: 2021

Share "Programación Orientada a Objetos"

Copied!
8
0
0

Texto completo

(1)

Escuela Superior de Ingenieros de San Sebastián

Escuela Superior de Ingenieros de San Sebastián --TecnTecnunun 1

Programación

Programación

Orientada a Objetos

Orientada a Objetos

Informática II

Informática II

Fundamentos de Programación

Fundamentos de Programación

Concepto de POO

Concepto de POO

• Un Objeto es una encapsulación de un conjunto de datos y de los métodos para manipular éstos.

• Las características fundamentales de la Programación Orientada a Objetos (POO) son: – Abstracción : Es la representación de las características esenciales de algo sin

incluir los antecedentes o detalles irrelevantes. La clasees una abstracción porque en ella se definen las propiedades y los atributos genéricos de un conjunto de objetos. Las clases tratan de representar el mundo real.

Encapsulaciónu ocultamiento de información: Las variables y las funciones miembro de una clase pueden ser declaradas como public, private o protected. De esta forma se puede controlar el acceso a los miembros de la clase y evitar un uso inadecuado.

Herencia: Es el mecanismo para compartir automáticamente métodos métodos y atributos entre clases y subclases. Una clase puede derivar de otra, y en este caso hereda todas las variables y funciones miembro. Así, puede añadir nuevas

funciones y datos miembros.

Polimorfismo: Esta característica permite implementar múltiples formas de un mismo método, dependiendo cada una de ellas de la clase sobre la que se realice la implementación.

Un ejemplo de la POO

es “Windows”, donde cada ventana, botón, menú, etc.

es un objeto. Cada uno tiene sus propias características (datos) y sus propios

métodos (funciones) para manipularlos.

(2)

Escuela Superior de Ingenieros de San Sebastián

Escuela Superior de Ingenieros de San Sebastián --TecnTecnunun 3

Concepto de “clase” en C++

Concepto de “clase” en C++

¾

Una Clase

es un tipo de datos

definido por el usuario.

¾

Básicamente, es una agrupación de datos (

variables

) y de funciones

(

métodos

) que operan sobre esos datos.

¾

La definición de una clase consta de dos partes:

¾ La primera está formada por el nombre de la clase precedido por la palabra reservada class.

¾ La segunda parte es el cuerpo de la clase, encerrado entre llaves y seguido por (;):

class nombre_clase {

//cuerpo de la clase };

¾

El cuerpo de la clase

consta de:

• Especificadores de acceso: public, protected y private. • Atributos: datos miembro de la clase (variables).

• Métodos: definiciones de funciones miembro de la clase. ¾ Por omisión, los datos miembro de la clase son private.

¾ Tanto las variables como los métodos pueden ser declarados public,protected yprivate, controlando de esta forma el acceso y evitando un uso inadecuado ->Encapsulación. ¾ Por lo general, las definiciones de las clases se hacen en ficheros de cabecera (*.h), los

cuales suelen llevar el nombre de la clase, en el caso de que sólo haya una en él.

Miembros de una clase

Miembros de una clase

• Los miembros de una clase pueden ser variables de cualquier tipo y funciones.

• En C++ a las variables se las denomina datos miembroy a las funciones, funciones miembrode la clase.

Datos miembro de una clase:

–Para declarar un dato miembro se procede de la misma forma que para declarar cualquier variable. Por ejemplo:

class Complejo {

public: //especificador de acceso

float real; //Declaración correcta

float imaginario = 0; //MAL, no se puede inicializar };

–Los datos miembro nopueden ser inicializados durante la declaración.

–Si no se pone un especificador de acceso (como es nuestro ejemplo public), por defecto los datos miembro serán private.

–En una clase cada dato miembro debe tener un nombre único.

–También podemos declarar como datos miembro de una clase, objetosde otra clase, siendo necesario que ésta haya sido previamente definida.

class Datos {

Complejo c1; //Declaración de un objeto de la clase Complejo

};

–Para Acceder a un dato miembro (siempre y cuando sea declarado como público) de una clase desde un objeto, se utilizará el operador Punto (.). Por ejemplo: c1.real = 5.4;

(3)

Escuela Superior de Ingenieros de San Sebastián

Escuela Superior de Ingenieros de San Sebastián --TecnTecnunun 5

Miembros de una clase (

Miembros de una clase (

cont

cont

.)

.)

Funciones miembro de una clase:

– Las funciones miembro de una clase definen las operaciones que se pueden realizar con sus datos miembro.

– Las funciones miembro también pueden ser públicas o privadas, lo cual se hace con los respectivos especificadores. Al igual que los datos miembro, si no se especifica serán privadas (private) por defecto. – Para declarar una función miembro de una clase se procede de la misma forma que para declarar una

función cualquiera. Por ejemplo en el fichero complejo.h:

class Complejo {

private:

float real,imaginario;

public: //funcione miembro públicas

void Asignar (float x, float y); };

– El cuerpo de una clase sólo contiene los prototipos de las funciones miembro (las declaraciones). La definición de la función se hace en los ficheros fuente (*.cpp).

– Para definir la función miembro en el fichero fuente se utiliza el nombre de la clase seguido por el

operador de resolución de ámbito(::). Por ejemplo, en el fichero complejo.cpp:

void Complejo::Asignar(float x, float y) {

real = x; imaginario = y; //acceso a los datos miembro //... Más código

}

Miembros de una clase (

Miembros de una clase (

cont

cont

.)

.)

– Las funciones miembro que tengan poco código, o las que se desee, también pueden ser definidas en el cuerpo de la clase. Por ejemplo:

En complejo.h: class Complejo { private: float real,imaginario; public:

void Asignar(float x, float y);

void Print(void){

cout << real << " + " << imaginario << "i" << endl; }

};

En complejo.cpp:

void Complejo::Asignar(float x, float y) {

real = x; imaginario = y; }

– En nuestro ejemplo, la función Print()ha sido definida en el cuerpo de la clase, con lo cual ya no hay necesidad de hacerlo en el fichero fuente.

– Dentro del cuerpo de la clase no hay necesidad de anteponer el nombre de la clase con el operador (::), como se hace generalmente en el fichero fuente, puesto que el nombre de la clase es conocido.

– Para Acceder a una función miembro (siempre y cuando sea declarada como pública) de una clase desde un objeto, se utilizará el operador Punto (.). Por ejemplo: c1.Asignar( 5.4, 1.2);

(4)

Escuela Superior de Ingenieros de San Sebastián

Escuela Superior de Ingenieros de San Sebastián --TecnTecnunun 7

Miembros de una clase (

Miembros de una clase (

cont

cont

.)

.)

Control de acceso a los miembros de la clase:

– El concepto de clase incluye la idea de ocultación de datos, que, básicamente, consiste en que no se puedan acceder a los datos miembro directamente, sino que hay que hacerlo a través de las funciones miembro públicas de la clase.

– Para controlar el acceso a los miembros (datos y funciones) de una clase, C++ provee de 3 especificadores:

public: un miembro declarado público es accesible en cualquier parte del programa donde el

objetode la clase en cuestión es accesible.

private: un miembro declarado privado puede ser accedido solamente por las funciones miembro de su propia clase o por funciones amigas (friend) de su clase. En cambio no puede ser accedido

por funciones globales o por las funciones propias de una clase derivada (herencia).

protected:un miembro declarado protegido se comporta exactamente igual que uno privado para las funciones globales, pero actúa como un miembro públicopara las funciones miembro de una clase derivada. //fichero complejo.h class Complejo { protected: float real,imaginario; public:

void Asignar(float x, float y);

void Print(void){

cout <<real<<" + "<<imaginario<<"i"<< endl; }

};

#include “complejo.h”

void main() {

Complejo c1; //creación de un objeto c1.real = 4.5; //error, real es protected c1.Asignar(4.5,5.5); //Correcto

c1.Print(); //Bien, Print en public

} //fichero complejo.cpp

#include “complejo.h”

void Complejo::Asignar(float x,float y) {

real = x; imaginario = y; }

Objetos de una clase

Objetos de una clase

• Un Objeto es un ejemplar concreto de una clase. Las clases son como tipos de variables, mientras que los objetos son como variables concretas de un tipo determinado.

• Los objetosconstan de una estructura interna (los datos) y de una interfaz que permite manipular tal estructura (las funciones).

• Cómo se construye un objeto de una clase? Igual que cualquier otro objeto o variable de un tipo predefinido, es decir, anteponiendo el nombre de la clase al nombre del objeto:

Complejo miComplejo;

• Un objeto no se inicializa como las variables: Complejo miComplejo=5; //Error

• Hay que recordar que un objeto tiene una copia de todos los datos miembro de una clase, entonces cómo puedo inicializar esos datos miembro al momento de la creación del objeto?

• Para solucionar este problema, C++ permite inicializar el objeto de una determinada clase en el momento de su declaración mediante un constructor definido por el usuario.

• También existe otra forma de inicializar un objeto al momento de su declaración: Complejo c1={1.5,-3.5}; Esta forma es muy restrictiva y poco utilizada ya que exige que las variables miembro de la clase sean declaradas como públicas, que la clase no tenga constructores y que no sea derivada.

• También se puede inicializar un objeto utilizando el operador de asignación (=), utilizando para ello otro objeto que ya haya sido inicializado. Ejemplo: comp1 = comp2;

(5)

Escuela Superior de Ingenieros de San Sebastián

Escuela Superior de Ingenieros de San Sebastián --TecnTecnunun 9

Constructor

Constructor

• En C++, una forma de asegurar que los objetos siempre contengan valores válidos y que puedan ser inicializados al momento de la declaración es escribiendo un constructor. • Un constructores una función miembro especialde una clase que es llamada de forma

automática siempre que se declara un objeto de esa clase. Su función es crear e inicializar un objeto de su clase.

• Dado que un constructor es una función miembro, admite argumentosal igual que éstas. • El constructor se puede distinguir claramente, con respecto a las demás funciones miembro

de la clase, porque tiene el mismo nombreque el de la clase.

• Un constructor no retorna ningún valor ni se hereda. Si el usuario no ha creado uno, el compilador crea uno por omisión, sin argumentos.

• Pueden existir varios constructores, siempre y cuando difieran en los argumentos. • Se puede crear un objeto de cualquiera de las formas siguientes:

– Declarando un objeto local o temporal: Complejo c1;

– Invocando al operador new: Complejo *c1 = new Complejo; Complejo *c1 = new Complejo(3,4);

De esta forma, se debe llamar al operador deleteal finalizar;

– Llamando explícitamente al constructor: Complejo c1(4.5 , 5.0);

• Cuando se utiliza el operador newpara crear el objeto, el acceso a las variables y funciones miembro de la clase se hace a través del operador (->), siempre y cuando sean públicas. Por ejemplo:

c1->real = 4.5; c1->Print();

Constructor (

Constructor (

cont

cont

..)

..)

Ejemplo:

Ejemplo:

//fichero complejo.h

#include "iostream.h"

class Complejo {

protected:

float real,imaginario;

public:

void Asignar(float x, float y);

void Print(void){

cout <<real<<" + "<<imaginario<<"i\n"; }

public:

Complejo(){ //constructor 1

real=imaginario=0.0; }

Complejo(float x, float y);//constr. 2 };

#include <iostream.h> #include "complejo.h"

void main() {

Complejo c1; //creación de un objeto c1.Asignar(4.5,5.5); //Correcto c1.Print();

//objeto c2

Complejo c2; //usa el const. defecto c2.Print();

//objeto c3

Complejo c3(1.5,-1.5);//usa el const. 2 c3.Print();

//objeto 4

//Complejo *c4 = new Complejo; Complejo *c4 = new Complejo(2,5); c4->Print();

delete c4; }

// fichero complejo.cpp #include "complejo.h"

Complejo::Complejo(float x, float y) {

real = x; imaginario = y; }

void Complejo::Asignar(float x, float y) {

real = x; imaginario = y; }

(6)

Escuela Superior de Ingenieros de San Sebastián

Escuela Superior de Ingenieros de San Sebastián --TecnTecnunun 11

Destructor

Destructor

• De la misma forma que existe una función para construir cada unos de los objetos que declaramos, también existe una función para destruir cada objeto construido, liberando así la memoria que ocupa. Esta función recibe el nombre de destructor.

• Un objeto es destruido automáticamente al salir del ámbito en el que ha sido definido. Sin embargo, si se ha creado con el operador new, se debe utilizar el operador deletepara destruirlo.

• El destructores una función miembro especial de una clase que se utiliza para eliminar un objeto de esa clase.

• El destructorse distingue fácilmente del resto de funciones porque tiene el mismo nombre que la clase precedido del operador tilde ~.

• El destructorno es heredado, no tiene argumentos ni puede retornar ningún valor.

• No hace falta llamar al destructor, ya que éste es invocado de forma automática cuando se destruye el objeto por los medios mencionados anteriormente.

• Si hiciera falta, el destructor también puede ser invocado de forma explícita: Objeto.nombre_clase::~nombre_clase; //llamada al destructor

Objeto->nombre_clase::~nombre_clase; //cuando el objeto ha sido creado con new

class Complejo //complejo.h { public: float real,imaginario; public: Complejo(); //constructor ~Complejo(); //destructor }; Complejo::Complejo() //complejo.cpp { //codigo necesario para inicial.

real = imaginario = 0; }

Complejo::~Complejo()

{ //codigo necesario para liberar mem. cout << "Se ha llamado al destruc\n"; }

Ejemplo Completo

Ejemplo Completo

// fichero complejo.cpp

#include "complejo.h"

void Complejo::Asignar(float x, float y) {

real = x; imag = y; }

Complejo::Complejo(float x, float y) {

real = x; imag = y; }

Complejo::~Complejo() {

cout << "Se ha llamado al destructor\n"; }

Complejo Complejo::Suma(Complejo c) {

Complejo tmp; //se crean 3 Compl. temp. tmp.real = this->real + c.real;

tmp.imag = this->imag + c.imag;

return tmp; }

void Complejo::Resta(Complejo c1,Complejo c2) {

this->real = c1.real - c2.real;

this->imag = c1.imag - c2.imag; } #include <iostream.h> #include "complejo.h" void main() { Complejo c1(4.5,-1.5); Complejo c2; c2.Asignar(1.5,1.0); Complejo Sum; Sum = c1.Suma(c2);

c1.Print(); cout<<" + "; c2.Print(); cout << " = ";

Sum.Print(); cout << endl; //Resta

Complejo Resta; Resta.Resta(c1,c2);

c1.Print(); cout<<" - "; c2.Print(); cout << " = ";

Resta.Print(); cout << endl; } //fichero complejo.h #include "iostream.h" class Complejo { protected: float real,imag; public: //constructores Complejo() { real = imag = 0.0;} Complejo(float x, float y); ~Complejo(); //destructor

public:

void Asignar(float x, float y);

void Print(void){

cout <<"["<<real<<","<<imag<<"i]"; }

Complejo Suma(Complejo c);

void Resta(Complejo,Complejo); };

El puntero implícito this: C++ proporciona este puntero para que una función miembro conozca la identidad del objeto particular que la está llamando, de esa forma acceder a los datos de dicho objeto, ya que todos los objetos comparten las funciones miembro mas no los datos, lo cuales cada uno tiene su propia copia.

(7)

Escuela Superior de Ingenieros de San Sebastián

Escuela Superior de Ingenieros de San Sebastián --TecnTecnunun 13

Miembros

Miembros

static

static

de una clase

de una clase

• Cada objeto tiene una copia de los datos miembro de la clase. Qué pasa cuando necesito que todos los objetos tengan un dato miembro en común?

• Un dato miembro de una clase declarado como staticimplica que sólo existirá una copia de ese dato miembro para todos los objetos y existe aunque no existan objetos de esa clase, con lo cual se concluye que es un dato asociado con la clase y no con el objeto.

• Un dato miembro static:

Puede ser declarado static, private o public.

Tiene que ser inicializado a nivel global (ámbito de fichero, no de clase).

Cuando sea accedido a través de una función miembro, dicha función también tiene que ser declarada static.

Y por último, existe aunque no haya ningún objeto de la clase declarado. #include <iostream.h>

class CPersona {

private:

static int num;

char *nombre;

int edad;

public:

CPersona(char *name="No Dato",int ed=0){ nombre = name; edad = ed;

num++; }

~CPersona(){ num--; }

static int Num(){ return num;}

char *GetName(){ return nombre; } };

#include <iostream.h>

int CPersona::num = 0; //inicializac. global

void main() {

CPersona p1("Carla",5);

cout<<"Num.Objetos:"<<CPersona::Num()<<endl; CPersona p2("Juan",31);

cout<<"Num.Objetos:"<<CPersona::Num()<<endl; CPersona *p3 = new CPersona("Ana",25); cout<<"Num.Objetos:"<<CPersona::Num()<<endl; delete p3; //eliminar 1 objeto

cout<<"Num.Objetos:"<<p1.Num()<<endl; cout<<"Nombre:"<<p1.GetName()<<endl; }

Array’s

Array’s

de objetos

de objetos

• Al igual que con los tipos estándar, también es posible crear array’sde objetos: – Forma estática, utilizando los corchetes: Nombre_clase Nombre_array[num_objetos];

– Forma dinámica, usando new: Nombre_clase *Nom_Puntero = newNombre_clase[num];

Recordar de llamar a delete cuando ya no necesitemos el array.

• Para crear un puntero a objeto se utiliza new. Para acceder a los miembros se usa el operador (->).

#include <iostream.h>

#include <string.h> //para strlen

class CAlumno { private: char *nombre; int edad; long telefono; public:

CAlumno(){;} //const. por defecto CAlumno(char *buf, int ed, int tel); ~CAlumno();

void Print();

void Asignar(char *buf,int ed,int tel); };

CAlumno::CAlumno(char *buf,int ed,int tel) {

nombre = new char[strlen(buf)+1]; strcpy(nombre,buf); edad = ed; telefono = tel; } CAlumno::~CAlumno() {

if (nombre!=NULL) delete nombre; }

void CAlumno::Asignar(char *buf,int ed,int tel){

nombre = new char[strlen(buf)+1]; strcpy(nombre,buf);

edad = ed; telefono = tel; }

void CAlumno::Print(){

cout << "\nNombre: " << nombre; cout << "\nEdad: " << edad;

cout << "\nTelefono: " << telefono;

}

void main(){

CAlumno al[3]; //array de 3 objetos al[0].Asignar("Juan",22,943215677); al[1].Asignar("Pedro",20,943215673); al[2].Asignar("Ana",21,943215271); for (int i=0;i<3;i++) al[i].Print();

int num=2; // dinamicamente

CAlumno *alumnos = new CAlumno[num]; alumnos[0].Asignar("Carla",5,943567221);

alumnos[1].Asignar("Mikel",15,943567222);

for (i=0;i<num;i++) alumnos[i].Print();

delete [] alumnos;

CAlumno *pAlum = new

CAlumno("Joseba",21,943765432); pAlum->Print();

delete pAlum; }

(8)

Escuela Superior de Ingenieros de San Sebastián

Escuela Superior de Ingenieros de San Sebastián --TecnTecnunun 15

Funciones “amigas”

Funciones “amigas”

• Los miembros de una clase declarados como privados solamente pueden ser accedidos mediante las funciones miembro de la clase, garantizando así la integridad de los datos. • Una función declarada friend(amiga) de una clase puede acceder a los miembros privados y

protegidos de la clase C++.

• Para declarar una función amiga, basta con escribir la palabra clave frienddelante del nombre de la función. En la definición de ésta no hace falta anteponer el nombre de la clase. Véase el siguiente ejemplo: class Complejo { private: float real; float imag; public: Complejo(){;}

Complejo(float x, float y){ real=x; imag=y;

}

void Print();

friend void LeerDatos(double &r, double &i, Complejo c);

};

void LeerDatos(double &r, double &i, Complejo c)

{

r=c.real; i=c.imag; }

void Complejo::Print()

{

cout << "Real: " << real ;

cout << " Imag: " << imag <<endl; }

void main()

{

Complejo c1(1.5,4.5); double r,i;

LeerDatos(r,i,c1); //accede a datos de c1 cout << "R:"<<r<<" Imag:"<<i;

Referencias

Documento similar