sábado, 9 de enero de 2016

Plantillas de clases


Es posible comprender qué es una pilla (una estructura de datos en la que insertamos elementos en un orden y los recuperamos en el orden último en salir, primero en entrar) independientemente del tipo de elementos que se coloquen en ella. Pero cuando en realidad se trata de crear la instancia de una pila, debemos especificar un tipo de dato. Esto crea una maravillosa oportunidad para la reutilización del software. Necesitamos los medios para describir la noción de una pila de manera genérica y crear las instancias a partir de las clases, que son versiones específicas de esta clase genérica. En C++, esta capacidad la proporcionan las plantillas de clases.







Polimorfismo

Se denomina polimorfismo a la capacidad que tienen los objetos ded una clase de responder al mismo mensaje o evento en función de los parámetros utilizados durante su innovación. Un objeto polimórfico es una entidad que puede contener valores de diferentes tipos durante la ejecución del programa.
Nos permite escribir programas que procesen objetos de clases que formen parte de la misma jerarquía de clases, como si todos fueran objetos de la clase base de la jerarquía.

El polimorfismo trabaja con los manejos de las referencias de clases base, pero no con los de nombres.





Niveles de herencia

Dependiendo del número de clases y de cómo se relacionan la herencia puede ser simple, múltiple y de niveles múltiples
Herencia Simple
Cuando sólo se tiene una clase base de la cual se hereda la clase derivada, la herencia simple no excluye la posibilidad de que una misma clase se pueda derivar más una clase derivada.
Herencia múltiple
En el tipo de herencia múltiple se usan dos o más clases base para derivar una clase. Es decir, la clase derivada comparte los atributos y métodos de más de una clase.
Herencia de niveles múltiples

La herencia de niveles múltiples se presenta cuando una clase derivada se usa como base para definir otra clase derivada.

Herencia: Clases base y clases derivadas

A menudo  un objeto de una clase en realidad también “es un” objeto de otra clase. Ciertamente un rectángulo es un cuadrilátero. Así, se puede decir que la clase Rectángulo hereda de la clase Cuadrilátero. En este contexto, a la clase cuadrilátero se le llama clase base y a la clase Rectángulo se le llama clase derivada. Un rectángulo es un tipo de cuadrilátero, pero es incorrecto decir que un cuadrilátero es un rectángulo.
Por lo general, la herencia produce clases derivadas con más características que sus clases base, de modo que los términos superclases y subclases pueden ser confusos; evitaremos estos términos . Los objetos de clases  derivadas pueden considerarse  como objetos de sus propias clases base; esto implica que existen más objetos asociados con las clases base y menos objetos asociados con las clases derivadas, así que es razonable llamar las clases base “superclases” y a las clases derivadas “subclases”.

La herencia forma estructuras jerárquicas en forma de árboles. Una clase base existe en una relación jerarquíca con sus clase derivadas. Una clase ciertamente puede existir por sí misma, pero cuando se utiliza la clase con el mecanismo de herencia que la clase se convierte en una clase base que suministra los atributos y el comportamiento para otras clases, o en una clase derivada que hereda los atributos y comportamientos.




Con la clase herencia pública, los miembros públicos y protegidos de la clase base se heredan como miembros públicos y privados,  respectivamente. Recuerde que los miembros privados de una clase baso no están accesibles desde las clases derivadas de dicha clase. Observe que las funciones amigas no se heredan.
Es posible tratar a los objetos de clases base y a los objetos de clase derivadas de manera similar; es similitud se expresa en los atributos y en el comportamiento de la clase. Los objetos de cualquier clase derivada mediante herencia pública de una clase base común pueden tratarse  como objetos de la clase base. 




Sobrecarga de los operadores de inserción y de extracción de flujo.

C++ es capaz de introducir y desplegar los tipos de datos integrados a través de los operadores de inserción << y de extracción>> de flujo. Estos operadores están sobrecargados (en la biblioteca de clases provista con los compiladores de C++) para procesar cada tipo de dato integrado, incluso cadenas, apuntadores y char* de estilo C. Los operadores de inserción y de extracción de flujo también pueden sobrecargarse para introducir y desplegar tipos de dato definidos por el usuario.


Ejemplo de sobrecarga de inserción y extracción de flujo.






Fundamentos de la sobrecarga de operadores
La programación en C++ es sensible a los tipos y a los procesos que se enfocan en ellos. Los programadores pueden utilizar tipos integrados y pueden definir nuevos tipos. Los tipos integrados pueden utilizarse con la rica colección de operadores de C++. Los operadores proporcionan a los programadores una notación concisa para expresar manipulaciones a objetos de tipos integrados.
Los programadores también pueden utilizar operadores con tipos definidos por el usuario. Aunque C++ no permite la creación de nuevos operadores, sí permite que la mayoría de los operadores existentes se  sobrecarguen para que cuando se utilicen con objetos clase, los operadores tengan un significado apropiado para los nuevos tipos.
La sobrecarga de operadores contribuye a la extensibilidad de C++, uno de los atributos más atractivos del lenguaje.
Utilice la sobre de operadores,  cuando ésta haga que los programas sean más claros que si utilizara llamadas explícitas a funciones para realizar las mismas operaciones.
Aunque la sobrecarga de operadores puede sonar como una capacidad exótica, la mayoría de los programadores con frecuencia utilizan implícitamente operadores sobrecargados. Los operadores se sobrecargan escribiendo una definición de  función (con un encabezado y un cuerpo) como normalmente lo haría, con la excepción de que el nombre de la función ahora se convierte en la palabra reservada operator, seguida por el símbolo del operador que se está sobrecargado. Por ejemplo, el nombre de la función operator+  se utilizaría para sobrecargar el operador suma (+).
Para utilizar un operador sobre clases de objetos, ese operador debe sobrecargarse (existen dos excepciones) El operador de asignación (=) puede utilizarse con todas las clases, sin una sobrecarga explícita. El comportamiento predeterminad del operador de asignación predeterminada de miembros es peligrosa para las clases. Pronto veremos que dicha asignación predeterminada de miembros es peligrosa para las clases con miembros apuntadores; explícitamente sobrecargaremos el operador de asignación para dichas clases. El operador de dirección (&) también puede utilizarse con objetos de cualquier clase sin tener que sobrecargarlos; éste simplemente devuelve la dirección del objeto en memoria. El operador de dirección también puede sobrecargarse.
La sobrecarga es más adecuada para clases matemáticas. Éstas con frecuencia requieren de un conjunto completo de operadores sobrecargados, para garantizar la consistencia con la forma en que se manejan realmente esas clases matemáticas.
El propósito de la sobrecarga de operadores es proporcionar las mismas expresiones concisas para tipos definidos por el usuario, que C++ proporciona en su rica colección de operadores para tipos integraos, Sin embargo, la soobrecarga de operadores no es automática; el programador debe escribir funciones para la sobrecarga de operedadores, de tal modo que realicen operaciones deseadas. Algunas veces, estas funciones se realizan mejor  con funciones miembro; en ocasiones, son mejores como funciones friend y en otras, pueden hacerse con funciones no miembro y no friend.

Es posible abusar en extremo de la sobrecarga, como el caso del operador +, para realizar operaciones de tipo sustracción, o como en el caso del operador /, para realizar operaciones de tipo multiplicación. Tales usos de la sobrecarga hacen que un programa se extremadamente difícil de entender.
Al menos un argumento de una función operador debe ser un objeto de clase o una referencia a un objeto de clase. Esto evita que los programadores modifiquen la forma en que los operadores funcionan con tipos integrados.
Sobrecargar un operador de asignación y un operador de suma para permitir instrucciones como:                              objeto2 = objeto2 + objeto 1; no implica que el operador += también se sobrecargue para permitir funciones como: objeto 2 += objeto1; Tal comportamiento puede lograrse sobrecargando explícitamente el operador += para esa clase.

Ejemplo de sobrecarga de operadores






Funciones y Clases Amigas

Una función friend (amiga) de una clase se define fuera del alcance de la clase, pero tiene derechos de acceso a los miembros privados de la clase. Una función o una clase completa puede declararse como función friend de otra clase.
Al utilizar funciones amigas podemos aumentar el rendimiento. Los objetos de la clase iteradora se utilizan para seleccionar sucesivamente elementos o realizar una operación con elementos de un objeto de una clase contenedora. Los objetos de la clase contenedora son capaces de almacenar elementos. Con frecuencia, el uso de amigas es apropiado cuando las funciones miembro no pueden utilizarse para ciertas operaciones.
Para declarar una función como amiga de una clase, anteceda la palabra reservada friend al prototipo de la función en la definición de la clase. Para declarar la ClaseDos como amiga de la ClaseUno, coloque una declaración de la  forma: friend class ClaseDos; en la definición de ClaseUno.
Aunque los prototipos para las funciones amigas aparecen en la definición de la clase, las amigas no son funciones miembro. Los conceptos private, protected, y public de acceso a miembros no son relevantes para las declaraciones de amistad, de modo que este tipo de declaraciones pueden colocarse en cualquier parte de la definición de la clase.
Inmediatamente después del encabezado del clase coloque las declaraciones  de amistad, y no las anteceda con algún especificador de acceso a miembros.
La amistad se gana, no se toma, es decir, para que la clase B sea una amiga de la clase A, la clase A debe declarar de manera explícita que la clase B en una amiga. Además, la amistad no es mi simétrica ni transitiva, si la clase A es amiga de la clase B, y la clase B es amiga de la clase C, no se puede inferir que la clase B es amiga de la clase A, que la clase es amiga de la clase B o que la clase A es amiga de la clase C.









Invocación de constructores y destructores

Los constructores y los destructores son llamados automáticamente. El orden en el que ocurren estas llamadas a función depende del orden en el que la ejecución introduce y rebasa el alcance en el que estos objetos se crean. Por lo general, las llamadas a un destructor se hacen en orden inverso de las llamadas a un constructor. Sin embargo, las clases de almacenamiento de los objetos pueden alterar el orden en el que se llama a los destructores.
Los constructores son llamados por objetos definidos con alcance global, antes de que cualquier otra función (incluso main) en este archivo comience su ejecución (aunque el orden de la ejecución de constructores de objetos globales entre archivos no está garantizado). Los destructores correspondientes son llamados cuando termina el main o cuando se llama a la función exit. Los destructores no son llamados por objetos globales, si el programa termina con una llamada a una función exit o abort.
Se llama al constructor de un objeto local automático cuando la ejecución alcanza el punto en donde se definen los objetos. Los destructores correspondientes se llaman cuando los objetos e salen de alcance (es decir cuando se abandona el bloque en el que se definieron). Los constructores y los destructores de objetos automáticos se llaman cada vez que los objetos entran o salen de alcance. Los destructores de objetos automáticos no se llaman si el programa termina con una llamada a las funciones exit o abort.

Se llama al constructor para un objeto local estático solamente una vez cuando la ejecución alcanza por primera vez el punto donde el objeto está definido. Los destructores correspondientes se llaman cuando termina main cuando se llama a la función exit. No se llama a los destructores para objetos estáticos, si el programa termina con una llamada a una función abort.

Ejemplo de constructores por omisión






Ejemplo de constructor con parámetros













Destructores

Un destructor es otro tipo de función miembro especial de una clase. El nombre del destructor de una clase es un carácter (~) seguido por el nombre de la clase. Esta convención es intuitivamente atractiva, ya que el operador tilde es el operador de complemento a niel de bits y en cierto sentido, el destructor es el complemento del constructor.

Al destructor de una clase se le llama cuando se destruye un objeto. Esto ocurre cuando por ejemplo un objeto automático se destruye si la ejecución del programa rebasa el alcance en el que ese objeto fue creado. El destructor mismo no destruye realmente al objeto, éste realiza la limpieza final antes de que el sistema se lo pida a la memoria del objeto, para que  ésta pueda reutilizarse para almacenar nuevos objetos. Un destructor no recibe parámetros y no devuelve valor alguno. Una clase solamente puede tener un destructor, la sobrecarga de destructores no está permitida.

Inicialización de los objetos de una clase


Cuando se crea un objeto de una clase, sus miembros pueden inicializarse mediante una función constructor de dicha clase. Un constructor es una función miembro especial que tiene el mismo nombre que la clase y no devuelve ningún tipo de dato. El programador proporciona el constructor, el cual se invoca cada vez que se crea un objeto de dicha clase (se crea la instancia). Los constructores pueden sobrecargarse para producir distintas maneras de inicializar a los objetos de una clase. Los datos miembro pueden inicializarse dentro del constructor de una clase, o sus valores pueden establecerse posteriormente después de la creación del objeto. Se debe proporcionar un  constructor para asegurarse que cada  objeto se inicialice de manera apropiada con valores significativos. En especial los datos miembro apuntadores deben inicializarse con un valor legítimo del apuntador.

Funciones de acceso y funciones de utilidad

No todas las funciones miembro necesitan ser públicas para servir como parte de la interfaz de una clase. Algunas funciones miembro permanecen como privadas y sirven como funciones de utilidad para otras funciones de la clase.

Las funciones miembro tienen a caer en ciertas categorías diferentes: funciones que leen y devuelven el valor de datos miembros privados : funciones que establecen el valor de los datos; funciones que implementan los servicios de la clase; y funciones que realizan distintas tareas mecánicas para la clases, tales como la inicialización de los objetos de una clase, la conversión entre clases y tipos predefinidos o entre clases u otras clases, y la manipulación de memoria para los objetos de la clase.

Operador unario de resolución de alcance

C++ proporciona el operador unario de resolución de alcance (::) para proporcionar acceso a una variable global cuando ésta ha sido oculta para una variable local con el mismo nombre, en un alcance local. Sin embargo, el operador unario de resolución de alcance no puede utilizarse para acceder a una variable local del mismo nombre en un bloque externo. Tal y como en C, se puede acceder directamente a una variable global sin el operador unario de resolución de alcance, si el nombre de la variable global no es el mismo que el de la variable local en alcance.



 Estructuras uniones y la palabra reservada class

Los programadores en  C++ se concentran en crear sus propios tipos definidos por el programador llamados clases. A las clases también se les denomina tipos definidos por el programador. Cada clase contiene datos, así como un conjunto de funciones que manipulan estos datos. A los datos que componen una clase se les llama datos miembro. A las funciones que componen una clase se les llama funciones  miembro o métodos. Así como una instancia de un tipo de dato predefinido tal como int se le llama variable, a una instancia de un tipo de dato definido por el usuario (es decir a instancia de una clase) se le llama objeto. El foco de atención en C++ se centra en las clases, en lugar de las funciones. Las clases en C++ son la evolución  natural de la idea de C con respecto a struct, recordando que struct es una colección de variables (datos) relacionadas mientras que una clase contiene tanto variables (datos miembro) como las funciones que manipulan dichos daros (funciones miembro).
Las clases permiten al programador modelar objetos que tienen atributos (representados como datos miembro) y compartimientos u operaciones (representado como funciones miembro). En C++, los tipos que contienen datos miembro y funciones miembro se definen mediante la palabra reservada class.
Algunas veces, en otros lenguajes de programación orientada a objetos, las funciones miembro se es denomina métodos y se invocan en respuesta a los mensajes que se envían al objeto. Un mensaje corresponde a una llamada a una función miembro enviada de un objeto a otro, o enviada desde una función hacia un objeto. Una vez que se define un clase, el nombre de la clase se vuelve un nombre tipo , lo cual puede utilizarse para declarar objetos de dicha clase. El cuerpo de la definición de la clase está delimitado con las llaves izquierda y derecha  { y }. La definición de la clase termina con un punto y coma. 
Las etiquetas public y private se llaman especificadores de acceso a miembros. Cualquier fato o función miembro declarada después del especificados public (y antes del siguiente especificador de acceso a miembro) es accesible desde cualquier parte del programa en la que el objeto se encuentre al alcance. Cualquier dato o función miembro que se declara después del especificador de acceso a miembros private (y hasta el siguiente especificador de acceso a miembros ) sólo es accesible a funciones miembro de la clase. Los especificadores de acceso a miembros terminan siempre con dos puntos (:), y pueden aparecer varias veces y en cualquier orden dentro de la definición de la clase.

A continuación se muestra una ejemplificación de lo ya mencionado así como su explicación.




La definición de la clase contiene prototipo para las siguientes cuatro funciones miembro después del especificador de acceso a miembros  public: Hora, estableceHora, imprimeMilitar  e imprimeEstándar . Éstas son las funciones miembro public de la clase (también conocidas como servicios públicos, comportamientos públicos o interfaz de la clase). Estas funciones serpan utilizadas por los clientes .Los datos meimbro de la clase permite el envío de los servicios que la clase propociona a sus clientes, a través de sus funciones miembro. Estos servicios permiten al código cliente interactuar con un objeto de dicha clase.
La función miembro que tiene el mismo nombre  que la clase se le denomina función constructor de la clase. Un constructor es una función miembro especial que inicializa los datos miembro de un objeto de la clas. A un constructor de la clase se le invoca cuando el programa crea un objeto de dicha clase. Es común tener varios contructores para un clase; esto se lleva a cabo a través de la sobrecarga de funciones. Así mismo no es posible especificar ningún tipo de retorno para el constructor.
Los tres miembros enteros aparecen después del especificador de acceso a miembros  private. Esto indica que los datso miembro de la de la clase son accesibles sólo para las funciones miembro de la clase. Por lo tanto, solamente se puede acceder a los datos miembro de la clase Hora mediante las cuatro funciones, cuyos prototipos aparecen en la definicipon de la clase,Por lo general, los datos miembro se listan en la parte privada de la clase, y las funciones miembro se listan en la poción publica. Es posible tener funciones miembro private  y dato public.
Una vez que se deifne la clase, es posible utilizarla como un tipo dentro delas declaraciones de objetos, arreglos y apuntadores, de la siguiente manera:
Hora  atardecer,                                     //objeto de tipo Hora
                arregloDeHoras  [ 5 ]           //arreglo de objetos de tipo Hora
                *apuntadorAHora,               //apuntador a un objeto de tipo Hora
                &hora Cenar =atardecer    //referencia a un objeto de tipo Hora
El nombre de la clase se convierte en un especificador de tipo. Puede haber tantos objetos de una clase, como variables de tipo int. El programador puede crear nuevos de clases, como sea necesario. Ésta es una de las razones por las que C++ es un lenguaje extensible.

Por lo general, las funciones miembro son más pequeñas que las que se encuentran en programas no orientados a objetos, debido a que los datos almacenados en los datos miembro se validan por medio del constructor, o por medio de las funciones miembro que almacenan los nuevos datos. Debido a que los datos ya se encuentran en el objeto las llamadas las funciones miembro a menudo se hacen sin argumentos, o al menos tienen menos argumentos que las típicas llamadas a funciones en lenguaje 







Constructor

Método de la clase que nos permite inicializar los atributos de la misma característica:
·         Tiene el mismo nombre de la clase
·         Se escriben generalmente en la sección pública de la clase
·         Asegura que los objetos al crearse se inicialice con valores válidos
·         No se hereda
·         No tiene valor de retorno
·         Se manda llamar automáticamente cuando se crea el objeto de la clase.

Tipos de constructor

·         Constructor por omisión: Aquel que no tiene  parámetros
·         Constructos con parámetros: Aquel que tiene una lista de parámetros.
Niveles de Seguridad

Privada (private): Generalmente se utiliza para definir los atributos de la clase y en casos muy especiales algunos métodos de la clase. Los métodos definidos en esta sección sólo pueden acceder miembros de la misma clase, esto garantiza la protección de los atributos y los métodos.
Protegida (protected): En esta sección se definen los atributos y métodos que comparten una clase base a una clase derivada. Los miembros definidos en esta sección pueden ser accedidos solamente por miembros de la misma clase y sus clases derivada.

Pública (public): En esta sección se definen los miembros y atributos que estarán disponibles para todas las clases sean o no derivadas.

Características de la programación.

Abstracción: Determina lo más relevante que identifica a un concepto a un objeto.
Atributo: Características genéricas o relevantes del objeto.
Método: Las acciones que modifican o actualizan el estatus del objeto
Encapsulamiento: Proteger todos los atributos y métodos dentro de una clase
Herencia: Estructura jerárquica donde se puede determinar (a través de una clase padre o clase base) heredar métodos y atributos a una clase hija o derivada.
Polimorfismo: Método que puede tener múltiples resultados, múltiples formas y dependerá del objeto que la invoque.
Clase: Estructura o patrón a través del cual se van a construir objetos, lo constituyen dos elementos, los métodos y los atributos.
Objeto: Identidad que tiene características propias.

El papel de clases y objetos en análisis y diseño.

Lo primero el diseñador tiene que identificar las clases y objetos del problema y trabajar juntos para lograr los comportamientos deseados. El interés del principal desarrollo debes estar en la vista externa.

Se han desarrollado distintas metodologías para el diseño y programación logrando fiabilidad, rendimiento, adaptabilidad, compresibilidad.
El diseño de software orientada a objetos elabora el software como un modelo muy próximo a la forma en que pensamos e interactuamos en el mundo real.

 Relaciones entre clases y objetos

No se debe confundir clases y objetos de la misma clase: una auto rojo y un auto azul no son objetos de clases diferentes sino objetos de  la misma clase con atributos diferentes. Son conceptos separaos pero en íntima relación.

Mientras que un objeto es una entidad concreta, existe en el tiempo y en el espacio una clase sólo representa una abstracción. Una clase es un conjunto de objetos que comparten una estructura común y un comportamiento común.
Conceptos Fundamentales de la programación orientada a objetos
La orientación de los objetos es una natural forma de pensar acerca del mundo real y descubrir programas de computadora. La programación orientada a objetos toma como modelo a los objetos reales para elaborar su contraparte en software. Toma ventaja en la relaciones entre clases en donde objetos de cierta clase, tales  como una clase de vehículos tienen atributos y operaciones similares.
La programación orientada a objetos encapsula datos (atributos) y funciones (operaciones) en paquetes llamados “objetos”. En C y otros lenguajes de programación por procedimientos, la  programación tiende ser orientada a  objetos.
 En C la unidad de programación es la función. En C++ la unidad de programación es a clase, que contienen funciones que implementan el comportamiento y datos  que implementan los atributos de la clase.
La orientación a objetos puede describirse como un  conjunto de disciplinas de ingeniería que desarrollan y modernizan software así como la facilidad de construir sistemas complejos a partir de  componentes.
La orientación a objetos trata de cumplir las necesidades de los usuarios finales así como productos software y estas tareas se realizan mediante la modificación del mundo real.
El soporte fundamental es el modelo objeto y los cinco elementos o propiedades de este modelo son: Abstracción, Encapsulamiento, Modularidad, Jerarquía, Polimorfismo.
Abstracción: Es la propiedad que permite representar las características esenciales de un objeto sin preocuparse de la restantes, se centra en la vista externa.
Encapsulamiento: O encapsulación permite asegurar que el contenido de la información de un objeto esté oculta al mundo exterior.
Modularidad: Permite subdividir una aplicación en partes más pequeñas llamadas “módulos” cada una de las cuales  deben ser tan independientes como sean posibles pero que al final tienen conexiones.
Jerarquía: Permite una ordenación de las abstracciones.

Polimorfismo: Indica literalmente la posibilidad de que una entidad tome muchas formas.

Bienvenidos

El blog en el que te encuentras, espero sea de tu ayuda, aquí encontrarás algunos temas con respecto a la programación orientada a objetos, así como algunos ejemplos de programas que te serán útiles para tus cursos. ¡Éxito!