Paradigmas de programación Año 2005 PROGRAMACION ORIENTADA A OBJETOS EN C++ 1- INTRODUCCIÓN El lenguaje C++ representa el resultado de los esfuerzos realizados para proporcionar las ventajas de la programación Orientada a Objetos a un lenguaje clásico, muy extendido en la programación de sistemas. Se trata de una extensión del lenguaje C que presenta claras influencias del lenguaje Simula, que a su vez puede considerarse como el precursor de los lenguajes POO. El lenguaje C++ fue diseñado por Bjarne Stroustrup, cuyo objetivo era construir un C mejorado. El resultado es un lenguaje compilativo, extensión estricta del C, al que incorpora nuevas características, aunque no todas están relacionadas con la programación orientada a objetos. Los programas escritos en C son totalmente compatibles con los programas C++, aunque lo contrario no es cierto. Algunos autores dicen, que siendo C y luego C++ lenguajes muy cerca del hardware (orientados a la eficiencia), solo incorporan la POO en lo que no los degrade. Sin embargo, si lo comparamos con un lenguaje puro, digamos Smalltalk (esta comparación la hace Ravi Sethi en “Lenguajes de Programación”) vemos que no hay nada que falte a C++ . Es verdad que es híbrido, en C++ podemos programar en el estilo estructurado también, pero es esto un pecado? En C++ un programa consta de objetos. Los objetos son como los tipos abstractos de datos: • Son un tipo de datos definido por el programador junto con un conjunto de operaciones que se pueden realizar sobre ellos. • Son abstractos para diferenciarlos de los tipos de datos básicos definidos, por ejemplo int, char y double. Un objeto es una unidad que contiene datos y las funciones que operan sobre esos datos. A los elementos de un objeto se los conoce como miembros: las funciones que operan sobre los objetos se denominan métodos (o funciones miembro) y los datos se denominan miembros datos. Los objetos soportan una serie de características específicas de los mismos: • Se agrupan en tipos denominados clases. • Contienen datos internos que definen su estado actual. • Soportan ocultación de datos. • Pueden heredar propiedades de otros objetos. • Pueden comunicarse con otros objetos enviando o pasando mensajes. • Tienen métodos que definen su comportamiento. OBJETO DIAGRAMA DE UN OBJETO Miembros datos K Miembros Función (métodos) Kkjhfkk Interior Lenguaje C++ - Página 1 I N T E R F A Z Exterior Paradigmas de programación Año 2005 Los objetos pueden ser activados mediante la recepción de mensajes. Un mensaje es una petición de un objeto a otro para que éste se comporte de una determinada manera, ejecutando uno de sus métodos, es decir los objetos de un programa se comunican entre sí mediante el paso o envío de mensajes. La notación utilizada para los mensajes es: nombre_ del _objeto.Función _miembro o método En POO los objetos son miembros de una clase. Una clase es un tipo definido por el usuario, está formada por los métodos y los datos que definen las características comunes a todos los objetos de una clase. 2- CLASES El lenguaje C++ entiende por clase un tipo de dato definido por el programador que contiene toda la información necesaria para construir un objeto de dicho tipo y el conjunto de operaciones que permiten manejarlo (métodos). Las clases de C++ le permiten disfrutar de los beneficios de la modularidad, de la misma manera que en lenguajes tales como Ada o Modula-2. La construcción de las clases se hace de tal manera que se asegura el encapsulamiento de los objetos. Las clases en C++ soportan los conceptos: • Encapsulamiento de datos • Tipos abstractos de datos. El encapsulamiento de datos se produce cuando la representación interna de un objeto junto con sus operaciones, se encierran en la misma estructura (la clase). La clase define un tipo abstracto de dato. Una clase contiene elementos dato llamado miembros dato, y funciones que manipulan esos datos llamados miembros función o funciones miembro. Una clase se puede definir con una estructura (struct), una unión (union) o una clase (class). En el tipo class todos los miembros son por defecto privados. Las estructuras y uniones son clases en las que todos sus miembros son por defecto public, a no ser que se especifique lo contrario utilizando los especificadores de acceso. La sintaxis de una clase es: class nombre_clase { miembro_1; miembro_2; ...... función_miembro_1( ); función_miembro_2( ); }; //Lista de miembros //funciones miembro Lenguaje C++ - Página 2 Paradigmas de programación Año 2005 3- OBJETOS O INSTANCIAS DE UNA CLASE Los objetos o instancias de una clase se definen así: nombre_clase instancia_1 //instancia_1 es una instancia de la clase tipo nombre_clase 4- COMPONENTES La definición de una clase consta de dos partes: una declaración y una implementación. La declaración lista los miembros de la clase. La implementación o cuerpo define las funciones de la clase. Declaración de una clase class Contador { long cuenta; public: void LeerValor(long); long ObtenerValor( ); Implementación de una clase void Contador ::LeerValor(long valor) { cuenta=valor; } long Contador :: ObtenerValor( ) { return cuenta; } :: operador de resolución de ámbito, identifica la clase a la que pertenece la función. 5- CONTROL DE ACCESO A UNA CLASE: VISIBILIDAD Una de las características fundamentales de una clase es ocultar tanta información como sea posible. Por consiguiente, es necesario imponer ciertas restricciones en el modo en que se puede manipular una clase y de cómo se puede utilizar los datos y el código dentro de una clase. Una clase puede contener partes públicas y partes privadas. Por defecto, todos los miembros definidos en la clase son privados. Para hacer las partes de una clase públicas (esto es, accesible desde cualquier parte de su programa) deben declararse después de la palabra reservada public. Todas las variables o funciones definidas después de public son accesibles a las restantes funciones del programa. Especialmente, el resto de su programa accede a un objeto a través de sus funciones y datos públicos. Dado que una característica clave de la POO es la ocultación de datos, debe tener presente que aunque puede tener variables públicas, desde un punto de vista Lenguaje C++ - Página 3 Paradigmas de programación Año 2005 conceptual debe tratar de limitar o eliminar su uso. En su lugar, debe hacer todos los datos privados y controlar el acceso a ellos, a través de funciones públicas. El mecanismo para hacer privados datos o funciones es anteponerle la palabra reservada private. Por defecto, una clase es privada, aunque es conveniente especificar la visibilidad expresamente, por legibilidad y por compatibilidad con versiones posteriores que pueden recomendar su uso obligatorio. Existen tres clases de usuarios de una clase: 1- La propia clase 2- Usuarios genéricos 3- Clases derivadas Cada usuario tiene diferentes privilegios o niveles de acceso. Cada nivel de privilegio de acceso se asocia con una palabra reservada: 1- private 2- public 3- protected • • • Por defecto todo lo declarado dentro de una clase es privado (private), y sólo se puede acceder a ella con las funciones miembros declaradas en el interior de la clase. Los miembros que se declaran en la región pública (public) se puede acceder a través de cualquier objeto de la clase de igual modo que se accede a los miembros de una estructura en C. Los miembros que se declaran en la región protegida (protected) sólo se pueden acceder por funciones miembros declaradas dentro de la clase, por funciones miembro de clases derivadas de esta clase. VISIBILIDAD DE UNA CLASE CLASE No accesible desde una clase externa Accesible desde una clase externa Privada Datos y/o funciones Pública Datos y/o funciones Lenguaje C++ - Página 4 class artículo { float precio; //privado por defecto char nombre[20]; //privado por defecto public: void indicar(void); //público ….. }; Paradigmas de programación Año 2005 6- FUNCIONES MIEMBRO ESPECIALES CONSTRUCTORES Un constructor es una función especial que sirve para construir o inicializar objetos. Se caracteriza por: • • • • • • Tener el mismo nombre de la clase que inicializa. No devuelve valores Puede admitir parámetros como cualquier otra función. Pueden existir más de un constructor, e incluso no existir. Si no se define ningún constructor de una clase, el compilador generará un constructor por defecto. Las funciones constructoras se llaman cuando se define el objeto. 7- HERENCIA Y POLIMORFISMO - HERENCIA Y JERARQUIA DE CLASES La herencia se manifiesta con la creación de un tipo definido por el usuario (clase), que puede heredar las características de otra clase ya existente o derivar las suyas a otra nueva clase. Cuando se hereda, las clases derivadas reciben las características (estructuras de datos y funciones) de la clase original, a las que se pueden añadir nuevas características o modificar las características heredadas. La derivación de las clases consigue la reutilización efectiva del código de la clase base para sus necesidades. C++ utiliza un sistema de herencia jerárquica. Es decir se hereda una clase de otra, creando nuevas clases a partir de clases ya existentes. Solo se pueden heredar clases, no funciones ordinarias ni variables. Una clase utilizada para derivar nuevas clases se denomina clase base (padre, superclase o ascendiente). Una clase creada de otra clase se denomina clase derivada o subclase. La terminología supone una clase base o clase padre, y una clase derivada o clase hija. Esta relación supone un orden de jerarquía simple. A su vez, una clase derivada puede ser utilizada como una clase base para derivar más clases. Por consiguiente se puede construir jerarquías de clases, en las que cada clase sirve como padre o raíz de una nueva clase. La siguiente figura representa un diagrama de jerarquía de clases. Lenguaje C++ - Página 5 Paradigmas de programación Año 2005 JERARQUIA DE CLASES clase base Figura Clases derivadas Figura_círculo Figura_rectángulo Figura_rectángulo_sólido - TIPOS DE HERENCIA En C++ existen dos tipos de herencia: simple y múltiple. • • La herencia simple es aquella en la que cada clase derivada hereda de una única clase. Cada clase tiene un solo ascendiente, y puede tener muchos descendientes. La herencia múltiple es aquella en la cual una clase derivada tiene más de una clase base. clase base Clase derivada Clase derivada - TIPOS DE DERIVACION Los especificadores de acceso a la clase base definen los posibles tipos de derivación: public, private y protected. El tipo de acceso a la clase base especifica cómo recibirá la clase derivada a los miembros de clase base. Si no se especifica un acceso a la clase base, C++ supone que su tipo de herencia es privado. Los accesos a la clase base pueden ser: Lenguaje C++ - Página 6 Paradigmas de programación Año 2005 • • • public: Los miembros públicos de la clase base son miembros públicos de la clase derivada. Los miembros protegidos de la clase base son miembros protegidos de la clase derivada. Los miembros privados de la case base permanecen privados a la clase derivada. private: Todos los miembros públicos y protegidos de la clase base son miembros privados de la clase derivada. Los miembros privados de la clase base permanecen privados a la clase derivada. protected: todos los miembros públicos y protegidos de la clase base son miembros protegidos de la clase derivada. Los miembros privados de la clase base permanecen privados a la clase derivada. Ejemplo de una clase Class Persona { private: char nombre[30]; int edad; public: Persona ( ); àConstructor char verNombre ( ); void modificarNombre (char); int verEdad ( ); void modiEdad (int); ~Persona ( ); à Destructor } char Persona::verNombre( ) { return nombre; }; void modificarNombre(char nuevonombre) { nombre=nuevonombre; }; int verEdad( ) { return edad; }; void modiEdad( int nuevaedad) { edad=nuevaedad }; Lenguaje C++ - Página 7