PROGRAMACIÓN ORIENTADA A OBJETOS

------------------------------------------------------------

Capítulo I

Capítulo I.  Autor (Feliciano Ramirez)

CLASES: 

Una clase es una plantilla de Objeto que sirve para modelar (dar características de propiedad y comportamiento) los Objetos que se crearan de ella.

 OBJETO:

Un objeto es un tipo definido por el programador o mas técnicamente una instancia de la clase. Los objetos son tipos de datos derivados de las clases definidas.

 INSTANCIA DE CLASE:

Es el nombre que se le da a un Objeto al reverenciarlo de una clase o al hacer comparaciones con otros objetos.

 PROPIEDADES:

Este el nombre que reciben las variables miembros de los objetos.

 FUNCIONES MIEMBRO:

Las funciones miembro son las funciones que dan comportamiento a un objeto.

 POLIMORFISMO:

Es la capacidad que tienen los objetos para comportarse como un objeto de una clase diferente (Hija e incluso Padre de esta).

 HERENCIA:

Es la capacidad de una clase para heredar propiedades y funciones miembros de su clase padre.

 Aunque existen muchos conceptos más a tomar en cuenta por el momento solo describimos breve mente los más importantes.

 Empezamos con esto de la POO (Programación Orientada a Objetos).

Antes de la POO se programaba bajo el paradigma estructurado donde la función era la base para la buena programación.

 Uno de los lenguajes que es mas conocido por impulsar la programación estructurada es Pascal  pues se dice que antes se programaba en forma secuencial sin uso de funciones o subrutinas y se valían de la sentencia goto: para saltar de un bloque de código a otro.

Pero las funciones acabaron con esto aunque aun así el uso de funciones no favorece mucho el mantenimiento de código (eso dicen los aficionados a la POO).

Eso debido a que se hace uso independiente entre tipos de datos y funciones.

 Por eso un día unos investigadores trabajando en simulación de fenómenos naturales (creo) se dieron cuenta que no era nada fácil simularlos con estructuras de datos y funciones que las manejen por separado.

Para resolver esto diseñaron el primer lenguaje con orientación a objetos Simula.

 Bueno si esto es cierto o no lo dejamos para los filósofos..

Ahora cuando empezaron a ver que esta forma de englobar datos y funciones o comportamiento en una solo estructura se empezó a popularizar este paradigma y surgieron otros lenguajes entre ellos SmallkTalk .(no se si se escriba así pero se entiende).

Bueno si hago mención a este lenguaje es porque el creador del C++ se baso en C y el mencionado para crear un lenguaje que seria ocupado dentro de su Institución  (la creadora del C).

En un principio lo llamo C con Clases y no era más que un sistema de preprocesador que traducía el código C con clases a C.

Pero mas adelante el C con clases se fue puliendo más hasta llegar a ser el tan criticado y amado C++.

 Ahora bien cual es la diferencia entre Estructurado y POO pues veamos un poco de código para explicarlo mejor:

 Bloque Ejemplo 001:

 /*Código en C*/

 #include <stdio.h>

 /*Estructura que guarda los datos de una persona*/

Struct Datos

{

Char  nombre[30];

Char  direccion[30];

Char  telefono[30];

};

/*Funcion para pedir datos del teclado*/

Void leerDatos( Datos persona)

{

Printf(“Escribe tu Nombre: “);

Scanf(“%s”,persona.nombre);

Printf(“\nEscribe tu direccion: ”);

Scanf(“%s”,persona.direccion);

Printf(“\nEscribe tu telefono: “);

Scanf(“%s”,persona.telefono);

}

/*Funcion que muestra los datos por pantalla*/

Void mostrarDatos( Datos persona)

{

Printf (“Tu nombre es: %s\n”,persona.nombre);

Printf(“Tu direccion es: %s\n”, persona.direccion);

Printf(“Tu telefono es: %s\n”, persona.telefono);

}

/*Ahora utilizaremos nuestras funciones para un programa básico*/

Void main(void)

{

Datos persona; /*creamos una estructura de datos local a la función main*/

leerDatos(persona);

mostrar(persona);

getchar();

};

 La salida por pantalla seria :

 Escribe tu Nombre:  Felix

Escribe tu direccion: Acapulco

Escribe tu telefono:  123456789

 Tu nombre es:   Felix

Tu direccion es: Acapulco

Tu telefono es:   123456789

 Observaciones:

 Para que las funciones puedan manipular los datos de nuestra estructura persona debemos pasársela como parámetro o declarar nuestra estructura globalmente esto evitaría que se la pasáramos como parámetro pero no es muy recomendable manejar variables a nivel global por tanto lo dejamos como en el ejemplo.

 //codigo en C++ y POO.

 #include <iostream>

Using namespace std;

 //creamos  nuestra clase Datos.

 Class Datos

{

Private:

Char nombre[30];

Char direccion[30];

Char telefono[30];

Public:

Void leerDatos( );

Void mostrarDatos( );

};

// ahora definimos las funciones miembro de la clase Datos

 Void Datos::leerDatos( )

{

Cout << “Escribe tu nombre: “;

Cin   >> nombre;

Cout << “Escribe tu direccion: “;

Cin   >> direccion;

Cout << “Escribe tu telefono: “;

Cin   >> telefono;

}

 Void Datos::mostrarDatos( )

{

Cout << “Tu nombre es: “    << nombre << endl;

Cout << “Tu direccion es: “ <<  direccion << ende;

Cout << “Tu telefono es: “   << telefono << ende;

}

 //ahora utilizaremos nuestra clase para crear un objeto en nuestro programa principal.

 Int main( )

{

Datos persona;

Persona.leerDatos( );

Persona.mostrarDatos( );

Cin.get();

Retunr 0;

}

 La salida por pantalla seria :

 Escribe tu Nombre:  Felix

Escribe tu direccion: Acapulco

Escribe tu telefono:  123456789

 Tu nombre es:   Felix

Tu direccion es: Acapulco

Tu telefono es:   123456789

 Fin del Bloque Ejemplo 001;

 Observaciones:

Como vemos la salida es la misma ese es el propósito y no se trata de comparar a C con C++ si no de ver las diferencias entre estructurado y POO .

Pues bien en el manejo de objetos ya no es necesario lidiar entre declarar la estructura como local o global para que nuestras funciones las trabajes pues como ambos datos y comportamiento están contenidos en la clase .los datos son visibles a las funciones directamente .por tanto no tenemos que declarar parámetros en las funciones miembros (solo en este caso y cundo nuestra función trabaje con datos contenidos en la clase).

Bueno esto es lo que se ve superficialmente en realidad si existe tal parámetro pero es implícito y el compilador lo reconoce al usar la función precedida por el nombre del objeto a modificar o trabajar :

Objet.funcion( );

 Esta es la forma de hacerlo explícitamente en realidad el compilador hace algo como.

 Funcion(Objeto* this);

 Para saber a que estructura de datos nos referimos.

 Pero claro de esto se encargo el compilador y nosotros nos limitamos a dar comportamiento a nuestros objetos.  Objeto.hacer( );

 En estas líneas hice referencia a una palabra this la cual es una palabra reservada de C++ de la cual hablaremos mas adelante.

 Bueno una vez visto estos Ejemplos donde se muestra una de las principales diferencias entre la programación Estructurada y la POO . Nos meteremos más a detalle en el estudio de la POO.

 Una clase es muy similar a una estructura del C , se declara con la palabra reservada class  y se declaran sus variables miembro dentro del cuerpo de la clase.

 Esto se hace de forma muy similar a como lo hacemos en las estructuras pero una diferencia es que en las estructuras las variables miembro son publicas esto significa que se puede acceder a ellas desde afuera de la estructuras, claro precedida por la variable estructura:

  tipoestructur.variable_miembro = Valor // esto es valido.

 En las clases es diferente pues por defecto una variable miembro de una clase es privada por lo cual no podemos acceder directamente a ella.

 Tipoclase.variable_miembro = Valor //esto por defecto es un error.

 Sin embargo podemos declarar un bloque dentro de la clase como public:

Esto nos permitiría acceder a las variables desde afuera de la clase.

 Otra características de las clase es que puede contener funciones dentro de ella alas cuales se les da el nombre de funciones miembro.

 ¿¿Que nos aporta el tener funciones dentro de la clase??

Pues lo que nos aporta es poder acceder a las variables miembro de la clase directamente si la necesidad de pasarlas como parámetros.(Esto lo vimos en el ejemplo 001.)

 Las funciones miembro a la inversa de las variables miembro ,son publicas por defecto y se puede acceder directamente a  ellas desde fuera de la clase :

 tipoObjeto.funcionMiembro( ); //forma valida.

 Igualmente como se hace con las variables miembro se puede cambiar la forma de ver a las funciones usando la palabra reservada  private:.

Esto evitaría que nuestra función fuese vista desde fuera de la clase.

¿y que ventaja tiene esto?

 Pues estas funciones privadas se utilizan por la propia clase para implementar a sus funciones publicas.

 OK estructuremos todo esto :

 Visibilidad:

Este es el  nombre que se le da a la forma en como las funciones y variables miembro serán declaradas dentro de la clase.

 Hay tres tipos de visibilidad:

 Public: una variable o función pública podrá ser accedida desde fuera de la clase.

 Private: una variable o función privada no podrá ser accedida desde fuera de la clase.

 Protected: una variable o función protegida podrá ser accedida solo por las clases hijas (derivada) de nuestra clase.  (Esto de hija lo veremos en la Herencia).

 Nota: como pueden ver solo hable de la forma de acceder a  los miembro de una clase desde fuera. Esto es porque desde dentro de ella todas los miembro son visibles entre ellos tengan la visibilidad que tengan.

 Bloque Ejemplo 002:

 Agregar que al declara una clase sus funciones miembro se declaran dentro de ella pero se implementan fuera precedidas por el nombre de su clase y el operador de visibilidad “::”.

 //Se declara una clase Ejemplo

Class Ejemplo

{

Private:  //iniciamos el bloque privado .

Int    numero1; //esta variable solo podrá ser accedida por las funciones miembro.

Int   numero2; // esta variable solo podrá ser accedida por las funciones miembro.

Int  funMayor(int num1, int num2); // esta función solo será utilizada por las funciones miembro.

Public://inicia el bloque publico.

Int mayor; //esta variable podrá ser accedida desde fuera de la clase.

Void leeNumeros( ); // esta función podrá ser utilizada desde fuera de la clase.

Void muestraMayor( );sta función podrá ser utilizada desde fuera de la clase.

};

Nota: la visibilidad protected: es utilizada solo en el manejo de clases y herencia por tano dejaremos su utilización para más adelante.

 //un pequeño programa para utilizar nuestra clase.

 Int main()

{

Ejemplo miObjeto;

miObjeto.leerNumero( );

miOjeto.muestraMayor( );

cout << “el numero mayor es: “ << miObjeto.mayor << endl;

system(“pause”);

return 0;

}

 //implementacion de las funciones miembro de la clase Ejemplo.

 Int Ejemplo::funMayor(int num1, int num2)

{

Return (num1 > num2 ? num1: num2);

}

Void Ejemplo::leeNumeros( )

{

Cout << “Escribe dos numeros enteros y el program ate mostrara el mayor de ellos: “ << endl:

Cin >> numero1;

Cin >> numero2;

Mayor = funMayor(nuemro1, numero2);

}

 Void Ejemplo::muestraMayor( )

{

Cout << “El numero mayor es: “ << funMayor(numero1, numero2) << endl;

}

  Fin Bloque Ejemplo 002;

 Como podemos ver este pequeño ejemplo nos muestra las formas como se utilizan las diferentes visibilidades de nuestros miembros de la clase Ejemplo.

 Una mala forma de hacerlo seria:

 Int main()

{

Ejemplo objeto;

Cout << “Escribe dos números enteros: “ << endl;

Cin >> objeto.numero1;

Cin >> objeto.numero2;

Cout << “El numero mayor es :” << funMayor(objeto.numero1, objeto.numero2) << endl;

Return 0;

}

 Como ven en este pequeño ejemplo no es correcta la forma de acceder a los variables miembros y a la función privada.

 Pues como mencione anteriormente no es posible acceder alas variables miembro privadas (private: ) ni a la funciones miembro privadas.

 Pues cuando hablamos de acceder no nos referimos a usar la variable o función de forma independiente sino como propiedad o comportamiento de un objeto existente.

Pues no podríamos hacer :

 leerNumero( );

mostrarMayor( );

 Aunque sean publicas, pues mientras no se declare un objeto de la clase que contiene tales funciones miembro, estas no existen en memoria.

 Tampoco podríamos hacer.

 Ejemplo.leerNumero( );

 O

Ejemplo::leerNumero( );

 Por la misma razón.

 Pues como mencioné al principio la clase solo existe para nosotros y el compilador pero para el microprocesador no existe , solo existen los objetos instancia de las clases.

Otro detalle es que podemos crear cuantos objetos queramos de una clase ,

Cada objeto contendría sus propias variables miembros y serian totalmente independientes salvo algunas excepciones que veremos mas adelante.

En el caso de las funciones miembro solo se crean una sola vez; solo el primer objeto de una clase carga las funciones miembro en memoria y todos los demás trabajan con las mismas funciones.

 Un ejemplo de esto seria:

 Bloque ejemplo 003:

 Class Datos

{

Private:

Int valor1;

Int valor2;

Int valor3;

Public :

Void fun1 ( );

Void fun2( );

Ahora si crearemos dos objetos de esta clase se haría internamente algo como esto:

 Bloque objeto1:                     Bloque funciones:                     Bloque objeto2:

Datos objeto1;                        común a infancias de:               Datos  objeto2;  

Valor1                                    clase Datos:                               valor1

Valor2                                     fun1                                          valor2

Valor3                                     fun2                                          valor3

Fin bloque.                            Fin Bloque funciones.               Fin Bloque objeto2.

 Como vemos en estos bloque existen dos objetos de la clase Datos y aunque cada uno tiene su propio bloque de datos ambos comparten el mismo bloque de funciones esto ahorra memoria.

 Fin Bloque Ejemplo 003.

 Como mencione a este asunto existen algunas excepciones que son las variables de clase y las funciones de clase.

 Estos tipos se declaran dentro de la clase como static (estáticas) que en realidad son compartidas.

 Estos tipos de miembros, variables y funciones static se crean automáticamente al cargar el programa, ósea existen sin necesidad de que exista un objeto de la clase que contiene miembros static.

 Estos tipos de datos son comunes a todos los objetos creados de una clase como sucede con las funciones miembro a diferencia de que podemos acceder a ellas de una forma que no podemos hacerlo con las funciones miembro comunes.

Bloque Ejemplo 004:

 Class Datos

{

Public:

Static int valor1;

Int valor2;

Static void fun1( );

Void fun2( );

}

 //ahora los datos static de la clase se inicializan a nivel de archive.

Int Datos::valor1 = 0; // esto es necesario para las variables static:

Se definen las funciones………………………..

 Y utilizaríamos nuetra clase :

 Int main( )

{

Cin >> Datos::valor1;

Cout << Datos::fun1 ();

Datos objeto1;

Cin>> objeto1.valor2;

Cout << objeto1.fun2( );

 Como vez para los miembros static no es necesario crear un objeto para usarlos pero se tiene que utilizar el nombre de la clase y el operador de visibilidad “::”.

Y en cambio para los miembros normales tenemos que crear un objeto para poder usarlos.

Otro detalle es que las variables miembros static solo podrán ser manejadas dentro de la clase por funciones static  .

 Variables miembro static con funciones miembro static.

Si que remos usar una variable staic en una funcion automatica(que es como se les llama alas funciones y variables comunes) es con el operador de visibilidad

Clase :: varstatic;

 La forma de inicializar las variables statics se realiza fuera de la clase porque C++ no permite la inicialización dentro de la declaración de la clase por tanto con las constantes de clase se hará algo muy similar , se iniciaran fuera de la clase.

---------------------------------------------------------

Espera mas complementos en este link.