Sie sind auf Seite 1von 11

Clases y Objetos

Este capitulo introduce a las clases en C++. La clase es la fundacin de C++ para el soporte de la programacin orientada a objetos, y se encuentra en el ncleo de muchas de sus ms avanzadas caractersticas. La clase es la unidad bsica de C++ de la encapsulacin y esta provee el mecanismo por el cual los objetos son creados.

Fundamentos de Clases
Vamos a comenzar definiendo los trminos de clase y objeto. Una clase define un nuevo tipo de dato que especifica la forma de un objeto. Una clase incluye los datos y el cdigo que operar sobre esos datos. Adems, una clase enlaza datos y cdigo. C++ usa una especificacin de una clase para construir objetos. Los objetos son instancias de una clase. Adems, una clase es esencialmente una serie de planes que especifican cmo construir un objeto. Es importante tener claro esto: Una clase es una abstraccin lgica. No es hasta que un objeto de esa clase sea creado que la representacin fsica de la clase existe en la memoria. Cuando se define una clase, se declaran los datos que sta contiene y el cdigo que opera en esos datos. Aunque clases m uy simples pueden contener slo cdigo o slo datos, la mayora de las clases contienen ambos. En conjunto, los datos se almacenan en las variables y el cdigo en las funciones. Colectivamente, las funciones y variables que constituyen una clase son llamados 'miembros' de la clase. Una variable declarada dentro de una clase es llamada 'variable miembro', y una funcin declarada en una clase es llamada 'funcin miembro'. En ocasiones el trmino 'variable de instancia' es usado en lugar de variable miembro. Una clase es creada con la palabra clave class. La declaracin de una clase es similar sintcticamente a una estructura ( y tienen muchsimo que ver ). Aqu tenemos un ejemplo. La siguente clase define un tipo llamado CRender, el cual es usado para implementar operaciones de renderizado en este caso. // Esto define la clase CRender class CRender { char buffer[256]; public: void m_Renderizar(); };

Veamos ms de cerca esta declaracin de la clase. Todos los miembros de CRender son declarados dentro de la declaracin 'class'. La variables miembro de CRender es buffer. La funcin miembro es m_Renderizar. NOTA: Por defecto los miembros de una clase son privados. Una clase puede contener tanto miembros privados como pblicos. Por defecto, todos los elementos definidos en una clase son privados. Por ejemplo la variable buffer es privada. Esto significa que slo pueden acceder a ella otros miembros de la clase CRender, cosa que no podr hacer ninguna otra parte del programa. Es una forma de lograr la encapsulacin: se puede controlar el acceso a ciertos elementos de datos mantenindolos privados. Aunque no hay ninguna en este ejemplo, se pueden definir funciones privadas, las cuales pueden ser llamadas solamente por otros miembros de la clase. Para hacer pblica una parte de la clase ( accesible a otras partes del programa ), se debe declarar con la palabra clave public. Todas las variables o funciones definidas despus de la declaracin pblica son accesibles por todas las dems funciones en el programa. En nuestra clase CRender, la funcin m_Renderizar() es pblica. Tpicamente, su programa acceder a los miembros privados de una clase a travs de sus funciones pblicas. Note que la palabra clave public es seguida con : . Mantenga en mente que un objeto forma una relacin entre cdigo y datos. Una funcin

miembro tiene acceso a los elementos privados de su clase. Esto significa que m_Renderizar tiene acceso a buffer en nuestro ejemplo. Para aadir una funcin miembro a la clase, debe especificar su prototipo en la definicin de la misma. Una vez que se ha definido una clase, se puede crear un objeto de ese tipo usando el nombre de la clase. El nombre de la clase se convierte en un especificador del nuevo tipo. Por ejemplo la siguiente declaracin crea 2 objetos llamados render1 y render2 del tipo CRender. CRender render1, render2; Cuando un objeto de la clase es creado, ste tendr su propia copia de las variables miembros que contiene la clase. Esto significa que render1 y render2 tendrn su propia e independiente copia de buffer. Los datos asociados con render1 son distintos y separados de los datos asociados con render2. Recordemos: En C++, una clase es un nuevo tipo de dato que puede ser usado para crear objetos. Especficamente, una clase crea una consistencia lgica que define una relacin entre sus miembros. Cuando se declara una variable de una clase, se est creando un objeto. Un objeto tiene existencia fsica, y es una instancia especfica de una clase. ( Esto es, un objeto ocupa espacio de memoria, pero una definicin de tipo no ). Adems, cada objeto de una clase tiene su propia copia de los datos definidos dentro de esa clase. Dentro de la declaracin de CRender, el prototipo de una funcin es especificado. Ya que las funciones miembros son prototipadas dentro de la definicin de la clase, no necesitan ser prototipadas en otro lugar cualquiera. Para implementar una funcin que es un miembro de una clase, debe indicarle al compilador a cual clase pertenece la funcin calificando el nombre de la funcin con el nombre de la clase. Por ejemplo, esta es una manera de codificar la funcin m_Renderizar(). void CRender::m_Renderizar() { } strcpy(buffer, "C++ en wikibooks"); return;

Resolucin de mbito
El :: es llamado el operador de resolucin de mbito. Esencialmente le dice al compilador que esta versin de m_Renderizar pertenece a la clase CRender. Dicho de otra forma, ::declara que m_Renderizar se encuentra en el mbito de CRender. Varias clases diferentes pueden usar los mismos nombres de funcin. El compilador sabe cul funcin pertenece a cul clase y esto es posible por el operador de resolucin de mbito y el nombre de la clase.

Acceso a la funciones
Las funciones miembros de una clase slo pueden ser llamadas relativas a un objeto especfico. Para llamar a una funcin miembro desde alguna parte del programa que se encuentre fuera de la clase, se debe usar el nombre del objeto y el operador de direcionamiento '.' ( punto ). Por ejemplo, lo siguiente llama a m_Renderizar() en el objeto objeto1. CRender objeto1, objeto2; objeto1.m_Renderizar();

La invocacin de objeto1.m_Renderizar() causa a m_Renderizar() operar en los datos de la copia de objeto1. Mantenga en mente que objeto1 y objeto2 son 2 objetos separados. Esto significa, por ejemplo, que inicializar objeto1 no causa que objeto2 sea inicializado, La nica relacin que objeto1 tiene con objeto2 es que es un objeto del mismo tipo. Cuando una funcin miembro llama a otra funcin miembro de la misma clase, puede hacerlo directamente, sin usar un objeto y el operador '.' En este caso, el compilador ya conoce en cul objeto se est operando. Solamente cuando una funcin miembro es llamada por cdigo que se encuentra fuera de la clase es cuando debe utilizarse el nombre del objeto y el operador '.' Por la misma razn, una funcin miembro puede referirse directamente a una variable miembro, pero cdigo fuera de la clase debe referenciarse a la variable a travs de un objeto y el operador '.' El programa siguiente muestra aqu todas las piezas juntas y detalles perdidos, e ilustra la clase CRender.

Ejemplo
// Programa OPP01.CPP #include <iostream> // Esto define la clase CRender class CRender { public: char buffer[256]; void m_Renderizar(const char *cadena); };

/* implementar m_Renderizar() para la c;*/ void CRender::m_Renderizar(const char *cadena){ strcpy(buffer, cadena);//copia la cadena return; }

int main (int argc, char **argv){ // crear 2 objetos CRender CRender render1, render2; render1.m_Renderizar("Inicializando el objeto render1"); render2.m_Renderizar("Inicializando el objeto render2"); cout << "buffer en render1: "; cout << render1.buffer << endl; cout << "buffer en render2: "; cout << render2.buffer << endl; return (0); } Este programa imprime: buffer en render1: Inicializando el objeto render1 buffer en render2: Inicializando el objeto render2

// tenemos acceso a buffer ya que es publico.

Miembros de una clase ( mtodos y atributos )


En el lenguaje coloquial de la programacin orientada al objeto es comn escuchar trminos tales como: mtodos, atributos, herencia, polimorfismo, etc. En esta seccin nos encargaremos de hablar de los dos primeros. Mtodos: En comparacin con la programacin tradicional, un mtodo es lo mismo que una funcin cualquiera, salvo que como los mtodos se declaran para pertenecer a una clase especfica, se dice que todos los mtodos de dicha clase son miembros de la misma. Por lo dems, la declaracin y definicin de los mtodos es exactamente igual que declarar y definir cualquier otra funcin. Atributos: En comparacin con la programacin tradicional, un atributo es lo mismo que una variable cualquiera, salvo que como los atributos se declaran para pertenecer a una clase especfica, se dice que todos los atributos de dicha clase son miembros de la misma. Por lo dems, la declaracin de los atributos es exactamente igual que declarar cualquier otra variable. Miembros: A partir de este momento usaremos la palabra miembro para referirnos al hecho de que un mtodo o un atributo pertenece a tal o cual clase. Por Ejemplo, en el programa OOP01.CPP ( visto anteriormente ) la Clase CRender posee dos miembros, buffer que es un atributo; y m_Renderizar que es un mtodo. class CRender { public: char buffer[256]; // atributo void m_Renderizar(const char *cadena); // mtodo };

Visibilidad de los miembros de una clase


Por visibilidad se entiende al acto de acceder a los miembros de una clase. En este sentido, los miembros de una clase pueden ser: pblicos, privados y protegidos. Un miembro pblico significa que el acceso al mismo puede darse dentro del interior de la clase, dentro de una subclase, y desde un objeto instanciado de cualquiera de estas. Por ejemplo, los miembros de la clase CRender son accesibles dentro de la misma y podrn accederse desde cualquier otra clase que se derive de CRender, as como desde cualquier objeto instanciado de estas. Un miembro privado significa que el acceso al mismo puede darse solamente dentro del interior de la clase que lo posee. Normalmente, el programador creador de una clase declara a los atributos de la clase como privados y a los mtodos como pblicos, esto con la idea de que el usuario de la clase no pueda tener acceso a los atributos sino es a traves de los mtodos definidos para el caso. Un miembro protegido se comporta de manera parecida a un miembro privado, salvo que estos son accesibles dentro de la clase que lo posee y desde las clases derivadas, pero no desde los objetos instanciados a raiz de dichas clases.

Nota: por defecto, los miembros de una clase son privados.

En la clase Pareja que se ver en seguida, se declaran dos atributos y cuatro mtodos para la manipulacin de dichos atributos. Observe que los atributos son privados( por defecto ), mientras que los mtodos se declaran pblicos. class Pareja { // atributos double a, b; public: // mtodos double getA(); double getB(); void setA(double n); void setB(double n); }; // implementacin de los mtodos de la clase Pareja // double Pareja::getA() { return a; } double Pareja::getB() { return b; } void Pareja::setA(double n) { a = n; } void Pareja::setB(double n) { b = n; }

Subclases
Una subclase es una clase que se deriva de otra. La clase que sirve de base suele conocerse como parent (padre), y a la subclase se le llama child (hija). En C++ cada clase que es creada se convierte en candidata para servir de base de donde se deriven otras. Por ejemplo, la clase Pareja es candidata para convertirse en la base para las subclases Suma,Resta, Multiplica, Divide, y otras posibles subclases en donde se utilice un par de valores numricos. Para poner un ejemplo, pensemos en que deseamos crear la clase Suma, misma que ser utilizada para obtener la suma de dos nmeros. Puesto que la clase Pareja posee dos atributos nmericos puede ser usada como base para la clase que estamos proyectando. As, el siguiente ejemplo se constituye en un caso de clases derivadas. Nota: Observe que la sintaxis para crear una subclase es: class hija : [public | private] padre { ... }; Donde padre es la clase base e hija es la subclase.

class Suma : public Pareja { // atributos de Suma double resultado; public: // mtodos de Suma double calcular(); }; // implementacin de Suma // double Suma::calcular() { return getA() + getB(); }

Probando las clases Pareja y Suma


// programa OOP02.CPP // Este programa pone a prueba el uso de las clase Suma, // misma que es una subclase de la clase Pareja anteriormente). #include <iostream.h> int main() { Suma s; s.setA(80); s.setB(100); cout << s.getA() << " + " << s.getB() << " = " << s.calcular() << endl; cin.get(); return 0; }

ambas

definidas

Herencia
La herencia es uno de los mecanismos ms tiles de la programacin orientada al objeto, ya que por medio de la misma se puede llevar a cabo la reutilizacin de cdigo. Es decir, puesto que toda clase definida se convierte en candidata para ser usada como base de donde se deriven otras, esto da como resultado que las clases derivadas hereden todos los miembros de la clase base. Por ejemplo, la clase Suma vista en la seccin anterior, hereda todos los miembros de la clase Pareja puesto que Suma es una extensin de Pareja. En ese sentido, podemos decir que existen dos tipos de herencia, por extensin y por agregacin o composicin. En el caso de las clases Pareja y Suma, se dice que Suma es una extensin de Pareja. Vista grficamente, la herencia por extensin se puede representar as:

Herencia por extensin

Herencia
Al tipo de diagrama mostrado arriba (Herencia por extensin) se le conoce como UML y es utilizado para mostrar de forma grafica la relacin existente entre una clase hija con la clase padre. En el caso del ejemplo, se muestra que la clase Suma es una extensin de la clase Pareja y, en consecuencia, Suma posee a los miembros { a, b, getA(), getB(),setA(), setB() } heredados de la clase Pareja. Observe como la clase Suma posee otros dos miembros no heredados, { resultado, y calcular() }, y es precisamente a este tipo de situacin por lo que se dice que Suma es una extensin de Pareja, ya que Suma, adems de poseer a todos los miembros de Pareja, se extiende para poseer otros dos miembros.

Agregacion o composicin
La composicin se da en los casos en donde una clase posee un objeto que es una instancia de otra clase. Por ejemplo, la clase Suma podra escribirse de la siguiente forma:

class Suma { // atributo privado double resultado; public: // mtodo pblico double calcular(); // atributo pblico Pareja p; }; // implementacin del metodo calcular de la clase Suma. double Suma::calcular() { return p.getA() + p.getB(); } Luego, si usted presta atencin, notar que el miembro p de la clase Suma es un objeto o instancia de la clase Pareja, en consecuencia, la clase Suma puede acceder a los miembros de la clase Pareja a travs de la variable p. Tambin se debe observar que la implementacin del mtodo calcular() es diferente que el mismo de la clase Suma original. Si usted desea poner a prueba a la nueva clase Suma, compile y ejecute el siguiente programa.

// programa herencia_por_composicion.CPP #include <iostream> using namespace std; class Pareja { // atributos double a, b; public: // mtodos double getA(); double getB(); void setA(double n); void setB(double n); }; // implementacin de los mtodos de la clase Pareja double Pareja::getA() { return a; } double Pareja::getB() { return b; } void Pareja::setA(double n) { a = n; } void Pareja::setB(double n) { b = n; } class Suma

{ // atributo privado double resultado; public: // mtodo pblico double calcular(); // atributo pblico Pareja p; }; // implementacin del metodo calcular de la clase Suma. double Suma::calcular() { return p.getA() + p.getB(); } int main() { Suma s; s.p.setA(80); s.p.setB(100); cout << s.p.getA() << " + " << s.p.getB() << " = " << s.calcular() << endl; cin.get(); return 0; } ////SALIDA//// 80 + 100 = 180

Constructores
Un constructor es un mtodo que pertenece a una clase y el cual (en C++) debe tener el mismo nombre de la clase a la que pertenece. A diferencia de los otros mtodos de la clase, un constructor deber ser del tipo void, es decir, el mismo no regresar valor alguno. Una clase puede tener ms de un mtodo constructor. Cada clase debe tener al menos un constructor, tanto as que si el programador creador de una clase no define un mtodo constructor para la misma, el sistema, o sea el compilador, crear de manera automtica un constructor nulo. El objetivo principal del constructor es establecer las condiciones necesarias dentro de la memoria y crear una copia del objeto mismo dentro de la memoria. Los constructores suelen usarse para la inicializacin de los atributos de los objetos instanciados. Por ejemplo, con las instrucciones: Suma s; s.setA(80); s.setB(100); del programa OOP02.CPP, se declara el objeto s de la clase Suma y luego se inicializan los atributos del objeto por medio de los mtodos setA() y setB(). En este caso, es necesario hacer uso de dichos mtodos debido al hecho de que no se ha definido un constructor para la clase Suma. Ahora bien, para evitar este tipo de situaciones podemos definir un mtodo constructor para Suma y que este se encargue de inicializar los atributos. Veamos.

Notas: ya que Suma es una extensin de Pareja, se ha definido el mtodo constructor de Pareja y ste a la vez es invocado por el constructor de Suma. Otro punto de inters es el hecho de la definicin de un constructor base para Pareja, ya que de acuerdo con las reglas de programacin en C++ toda clase en donde se defina un constructor parametrizado deber definir un constructor base; esta regla se aplica en los casos en donde la clase proyectada servir de base para otras. // programa OOP04.CPP // Ejemplo: clases Pareja y Suma, ambas con constructor #include <iostream> using namespace std; //-----------------------class Pareja { // atributos double a, b; public: // constructor de base ( null ) Pareja() {} // constructror parametrizado Pareja(double x, double y) : a(x), b(y) {} // mtodos double getA(); double getB(); void setA(double n); void setB(double n); }; // implementacin de los mtodos de la clase Pareja // double Pareja::getA() { return a; } double Pareja::getB() { return b; } void Pareja::setA(double n) { a = n; } void Pareja::setB(double n) { b = n; } //-----------------------class Suma : public Pareja { // atributos de Suma double resultado; public: // constructor Suma(double a, double b) : Pareja(a, b) {} // mtodos de Suma

double calcular(); }; // implementacin de Suma // double Suma::calcular() { return getA() + getB(); }

//-----------------------int main() { Suma s(80, 100); cout << s.getA() << " + " << s.getB() << " = " << s.calcular() << endl; cin.get(); return 0; }

Destructores
Un destructor es un mtodo que pertenece a una clase y el cual (en C++) debe tener el mismo nombre de la clase a la que pertenece. A diferencia de los otros mtodos de la clase, un destructor deber ser del tipo void, es decir, el mismo no regresar valor alguno. Para diferenciar a un mtodo destructor de un mtodo constructor, al nombre del destructor se le debe anteponer el caracter ~ (Alt + 126). El objetivo principal del destructor es el de retirar de la memoria al objeto, o sea, el destructor hace todo lo contrario que el constructor. Los destructores suelen usarse para liberar memoria que haya sido solicitada por el objeto a travez de las ordenes malloc(), new, etc. En tales casos se deber incluir dentro del mtodo destructor la orden free, delete, etc., segn sea el caso. // clase Pareja con constructor y destructor class Pareja { // atributos double a, b; public: // constructor de base ( nulo ) Pareja() {} // constructor parametrizado Pareja(double x, double y) : a(x), b(y) {} // destructor ~Pareja() {} // mtodos double getA(); double getB(); void setA(double n); void setB(double n); };

Das könnte Ihnen auch gefallen