Programacin Orientada a Objetos OOP Definicin La Programacin
Programación Orientada a Objetos (OOP)
Definición La Programación Orientada a Objetos (Object Oriented Programming) es una técnica de programación que establece una unión muy estrecha entre algoritmos y datos. Algoritmos + Datos = Objetos
Características Las características principales de los objetos son: Encapsulación: combinación en una sola estructura los datos, procedimientos y funciones que los manipulan para formar un nuevo tipo - el objeto. Herencia: Definición de un objeto y luego uso del mismo para construir una jerarquía de objetos descendientes, con cada descendiente heredando acceso a todo el código y datos del ancestro. Polimorfismo: Dada una acción un nombre que es compartido hacia arriba y abajo en una jerarquía de objetos, con cada objeto en la jerarquía implementando la acción de una manera apropiada a sí mismo.
Mensajes y métodos • En la programación orientada a objetos, la acción se indica mediante la transmisión de un mensaje a un agente (un objeto) responsable de la acción. • El mensaje tiene codificada la petición de una acción y se acompaña de cualquier información adicional (argumentos) necesaria para llevar a cabo la petición. • El receptor es el agente al cual se envía el mensaje. • Si el receptor acepta el mensaje, acepta la responsabilidad de llevar a cabo la acción indicada. • En respuesta a un mensaje, el receptor ejecutará algún método para satisfacer la petición.
Diferencia entre mensajes y procedimientos La distinción entre el paso de mensajes y la llamada a procedimiento es que, en el paso de mensaje, hay un receptor designado, y la interpretación – es decir, la selección del método que se ejecutará como respuesta al mensaje – puede diferir con receptores diferentes. Por lo general, el receptor específico para cualquier mensaje no se conoce sino hasta el tiempo de ejecución, por lo que la determinación del método que se debe invocar no puede hacerse sino hasta entonces.
Clases y ejemplares • Todos los objetos son ejemplares de una clase. • El método invocado por un objeto en respuesta a un mensaje queda determinado por la clase del receptor. • Todos los objetos de una clase dada usan el mismo método en respuesta a mensajes similares.
Herencia • Las clases se pueden organizar en una estructura de herencia jerárquica. • Una subclase heredará atributos de una superclase que esté más arriba en el árbol. • Una superclase abstracta es una clase (como mamífero) que se usa sólo para crear subclases y para la cual no hay ejemplares directos.
Ejemplo de herencia Objeto material Animal Planta Mamífero Perro Flor Humano Comerciante Ornitorrinco Artista Dentista Beth Ken Florista Relámpago Flo Pepe flores de la abuela
La clase Point La clase punto sirve para representar un punto en el plano x-y. class Point{ int X, Y; public: Point(int x 1, int y 1){X = x 1; Y = y 1; }; int Get. X(){return X; }; int Get. Y(){return Y; }; };
Ejemplo Herencia Redefinición de la clase Point (archivo Point. h de encabezado) class Location { protected: // permite a clases derivadas acceder datos privados int X; int Y; public: //estas funciones pueden accederse desde fuera Location(int Init. X, int Init. Y); int Get. X(); int Get. Y(); }; class Point : public Location{//derivada de Location // derivación pública indica que X y Y son protegidos // dentro de Point protected: Boolean Visible; // las clases derivadas de Point // necesitarán acceso public: Point(int Init. X, int Init. Y); // constructor void Show(); void Hide(); Boolean Is. Visible(); void Move. To(int New. X, int New. Y); };
Acceso en clases Acceso en clase base Modificador de acceso Acceso heredado en base public private public no accesible protected public private no accesible protected private
Archivo de implementación de las clases Location y Point (archivo Point 2. cpp) #include "point. h" #include <graphics. h> // funciones miembro de la clase // Location: : Location(int Init. X, int Init. Y) { X = Init. X; invoca constructor de Y = Init. Y; Location }; int Location: : Get. X(void) { return X; }; int Location: : Get. Y(void) { return Y; }; // funciones miembro de la clase Point: Estas //suponen que el programa principal inicia las gráficas Point: : Point(int Init. X, int Init. Y) : Location(Init. X, Init. Y) { Visible = false; // la hace invisible por default };
Archivo de implementación (cont. ) void Point: : Show(void) { Visible = true; putpixel(X, Y, getcolor()); // usa el color default }; void Point: : Hide(void) { Visible = false; // usa color de fondo para borrar putpixel(X, Y, getbkcolor()); }; Boolean Point: : Is. Visible(void) { return Visible; }; void Point: : Move. To(int New. X, int New. Y) { Hide(); // hace el punto invisible X = New. X; // cambia X y Y a una nueva posición Y = New. Y; Show(); // muestra el punto en la nueva posición };
Programa de ejemplo #include <graphics. h> // Biblioteca gráfica #include <conio. h> // para getch() #include "point. h" // declaraciones de Point y Location int main() { // inicia el sistema gráfico int graphdriver = DETECT, graphmode; initgraph(&graphdriver, &graphmode, ". . \bgi"); // Mueve un punto a través de la pantalla Point APoint(100, 50); // Inicia X, Y a 100, 50 APoint. Show(); // APoint semuestra getch(); // espera una tecla APoint. Move. To(300, 150); // APoint se mueve a 300, 150 getch(); // espera una tecla APoint. Hide(); // APoint se oculta getch(); // espera una tecla closegraph(); // Restaura pantalla original return 0; }
Diagrama UML de Location y Point Location #X : int #Y : int +Get. X(): int +Get. Y(): int Point #Visible: Boolean +Show() +Hide() +Is. Visible(): Boolean +Move. To(New. X, New. Y)
La clase Circle // CIRCLE. CPP A Circle class derived from Point #include <graphics. h> #include "point. h" #include <conio. h> // graphics library declarations // Location and Point class declarations // for getch() function // link with point 2. obj and graphics. lib class Circle : Point { int Radius; // derived privately from class Point // and ultimately from class Location // private by default public: Circle(int Init. X, int Init. Y, int Init. Radius); void Show(void); void Hide(void); void Expand(int Expand. By); void Move. To(int New. X, int New. Y); void Contract(int Contract. By); };
La clase Circle (cont. ) Circle: : Circle(int Init. X, int Init. Y, int Init. Radius) : Point(Init. X, Init. Y) { Radius = Init. Radius; }; void Circle: : Show(void) { Visible = true; circle(X, Y, Radius); } void Circle: : Hide(void) { unsigned int Temp. Color; Temp. Color = getcolor(); setcolor(getbkcolor()); Visible = false; circle(X, Y, Radius); setcolor(Temp. Color); }; // draw the circle // to save current color // set to current color // set drawing color to background // draw in background color to erase // set color back to current color
La clase Circle (cont. ) void Circle: : Expand(int Expand. By) { Hide(); // Radius += Expand. By; // if (Radius < 0) // Radius = 0; Show(); // }; erase old circle expand radius avoid negative radius draw new circle void Circle: : Contract(int Contract. By) { Expand(-Contract. By); // redraws with (Radius - Contract. By) }; void Circle: : Move. To(int New. X, int New. Y) { Hide(); // erase old circle X = New. X; // set new location Y = New. Y; Show(); // draw in new location };
Ejemplo de programa main() // test the functions { // initialize the graphics system int graphdriver = DETECT, graphmode; initgraph(&graphdriver, &graphmode, ". . \bgi"); Circle My. Circle(100, 200, 50); My. Circle. Show(); getch(); My. Circle. Move. To(200, 250); getch(); My. Circle. Expand(50); getch(); My. Circle. Contract(75); getch(); closegraph(); return 0; } // // // declare a circle object show it wait for keypress move the circle (tests hide and show also) // make it bigger // make it smaller
Diagrama UML de Circle Location #X : int #Y : int +Get. X(): int +Get. Y(): int Point #Visible: Boolean +Show() +Hide() +Is. Visible(): Boolean +Move. To(New. X, New. Y) Circle -Radius: int +Show(void); +Hide(void); +Expand(int Expand. By); +Move. To(int New. X, int New. Y); +Contract(int Contract. By);
Tarea Derive la clase Rectangle a partir de la clase Point. Defina width y height como miembros dato. Escriba los métodos constructor, Show, Hide, Move. To, Expand. W, Expand. H, Contract. W, Contract. H. Defina un jerarquía de clases Empleado, Empleado. Por. Hora, Emplado. De. Base. Defina que atributos (miembros dato) necesita mantener para cada uno. Defina métodos (funciones miembro) para Iniciar cada tipo de empleado, obtener el sueldo de cada uno, Obtener el nombre, Imprimir todos los datos.
Herencia Múltiple Lacation Point GMessage Circle MCircle
La clase MCircle class GMessage : public Location { // Despliega mensaje en la pantalla gráfica char *msg; // mensaje a desplegar int Font; // fuente BGI int Field; // escala del texto public: // Inicializar GMessage(int msg. X, int msg. Y, int Msg. Font, int Field. Size, char *text); void Show(void); // mostrar mensaje }; class MCircle : Circle, GMessage {// hereda de dos clases public: MCircle(int mcirc. X, int mcirc. Y, int mcirc. Radius, int Font, char *msg); void Show(void); // mostrar circulo con mensaje };
Métodos para GMessage: : GMessage(int msg. X, int msg. Y, int Msg. Font, int Field. Size, char *text) : Location(msg. X, msg. Y) // coordenadas X Y para centrar mensaje { Font = Msg. Font; // font estándar Field = Field. Size; // ancho del área msg = text; // apunta al mensaje }; void GMessage: : Show(void) { int size = Field/(8*strlen(msg)); //8 pixels por char. settextjustify(CENTER_TEXT, CENTER_TEXT); //centrado settextstyle(Font, HORIZ_DIR, size); //magnificar outtextxy(X, Y, msg); // despliega texto }
Programa principal void MCircle: : Show(void){ Circle: : Show(); GMessage: : Show(); } main() //draws some circles with text { int graphdriver = DETECT, graphmode; initgraph(&graphdriver, &graphmode, ". . \bgi"); MCircle Small(250, 100, 25, SANS_SERIF_FONT, "You"); Small. Show(); MCircle Medium(250, 100, TRIPLEX_FONT, "World"); Medium. Show(); MCircle Large(250, 225, GOTHIC_FONT, "Universe"); Large. Show(); getch(); closegraph(); return 0; }
Enlace de métodos • La búsqueda para encontrar un método que pueda invocarse en respuesta a un mensaje dado empieza con la clase del receptor. • Si no se encuentra un método apropiado, se lleva la búsqueda a la superclase de dicha clase. • La búsqueda continúa hacia arriba de la cadena de la superclase hasta que se encuentra un método o se agota la cadena de la superclase. • En el primer caso el método se ejecuta; en el último caso, se emite un mensaje de error.
Funciones virtuales Los métodos vistos anteriormente tienen la característica de ligado estático o temprano. Este consiste en que el compilador determina el método al momento de compilación. Con el ligado temprano el usuario no puede agregar nuevas clases de figuras a la aplicación revisada anteriormente. Se necesitaría re-escribir código y recompilar cada que se agregaran nuevas formas con su propio método Show. El ligado tardío o dinámico permite resolver este problema mediante el uso de funciones virtuales. En términos prácticos, esto consiste en decidir cual función show ejecutar al momento de correr el programa hasta saber que tipo de objeto la está llamando.
El método Move. To Este método está definido en cada clase a partir de la clase Point. Los métodos Hide y Show dentro de Move. To no son los mismos cuando se llama Circle: : Move. To que cuando se llama Point: : Move. To. Si se heredara Move. To a partir de Point, se llamaría a Hide y Show incorrectos cuando se deseara mover un objeto Circle. La solución es declarar las funciones Hide y Show como virtuales.
Declaración de funciones virtuales Las funciones Hide y Show virtuales serían declaradas como sigue: virtual void show(); virtual void hide(); Un ejemplo de llamada: Circle ACircle; Point* APoint_pointer=&ACircle; //puntero a Circle asignado //a la clase base, Point APoint_pointer->Show(); //llamara a Circle: : Show()
Cambios en Point Solo hay que agregar la palabra virtual en los lugares adecuados (VPOINT. H). class Point : public Location {// derivada de Location protected: Boolean Visible; public: Point(int Init. X, int Init. Y); virtual void Show(); virtual void Hide(); Boolean Is. Visible(); void Move. To(int New. X, int New. Y); }; Se elimina Move. To de la clase Circle y derivar Circle públicamente a partir de Point para acceder a Move. To (VCIRC. CPP).
Una aplicación gráfica referencia a Point Se desea una aplicación para manipular las figuras desarrolladas anteriormente. Para desplazar las figuras se utilizará la función Drag Cualquier objeto tipo Point o alguno de sus descendientes puede ser Any. Fig Drag será definido en Point Get. Delta regresa el incremento en x y de la posición. (teclado, , pouse, joystick, etc) void Drag(Point& Any. Fig, int Drag. By){ int Delta. X, Delta. Y; int Figure. X, Figure. Y; Any. Fig. Show(); // dibuja la figura // posicion inicial Figure. X = Any. Fig. Get. X(); Figure. Y = Any. Fig. Get. Y(); // lazo de arrastre while (Get. Delta(Delta. X, Delta. Y)) { // Aplica delta a figure en X, Y Figure. X += (Delta. X * Drag. By); Figure. Y += (Delta. Y * Drag. By); // mueve Any. Fig. Move. To(Figure. X, Figure. Y); }; }
Ejemplo FIGDEMO. CPP Revisar FIGURES. H FIGURES. CPP y FIGDEMO. CPP
Computación como simulación El computador es un manejador de datos que sigue un patrón de instrucciones, se desplaza por la memoria, obtiene de diversas posiciones, los transforma de alguna manera y devuelve los resultados a otras posiciones. Si observamos los valores de los segmentos, podemos determinar el estado de la máquina o los resultados producidos por el cómputo. Aunque el modelo puede ser un cuadro más o menos exacto de lo que pasa dentro de un computador, nos ayuda muy poco para entender como resolver problemas por medio de él.
Computación como simulación (cont. ) En el marco orientado a objetos, nunca mencionamos direcciones de memoria, variables, asignaciones o algún otro de los términos convencionales de programación. En su lugar, hablamos de objetos, mensajes y responsabilidad por alguna acción. En lugar de un procesador triturador de bits. . que saquea estructuras de datos, nosotros tenemos un universo de objetos con buen comportamiento que cortésmente se solicitan entre sí cumplir sus diversos deseos, Dan Ingalls. Ver a la computación como si creara un “universo” se asemeja en mucho a un estilo de simulación de computación llamado “simulación determinada por eventos discretos”.
Manejo de la complejidad Puesto que la construcción de software es en forma inherente una actividad de sistemas, esto es, un ejercicio de interrelaciones complejas, el esfuerzo de comunicación es grande y pronto domina la disminución de tiempo de trabajo individual originado por la división. Añadir más hombres alarga, no acorta, el plan de trabajo.
Mecanismos de abstracción Módulos 1. Uno debe proporcionar al usuario toda la información necesaria para usar correctamente el módulo, y nada más. 2. Uno debe proporcionar al implantador toda la información necesaria para completarlo, y nada más. Los módulos por si mismos ofrecen un método efectivo para la ocultación de información, pero no nos permite realizar la creación de ejemplares (instantiation), la cual es la capacidad para hacer copias múltiples de las áreas de datos.
Mecanismos de abstracción (cont) Tipos de datos abstractos 1. Exportar una definición de tipo 2. Proporcionar un conjunto de operaciones que puedan usarse para manipular los ejemplares de tipo. 3. Proteger los datos asociados con el tipo de tal manera que pueda operar con ellos solo mediante las operaciones provistas. 4. Crear múltiples ejemplares del tipo. Objetos: mensajes, herencia y polimorfismo En el paso de mensajes está implícita la idea de que un mensaje puede variar de acuerdo con los diferentes objetos. El comportamiento y la respuesta que el mensaje provoca dependerá del objeto que lo recibe.
Tarea #1 Dibuje la jerarquía de dispositivos electrónicos que conozca (pasivos, activos, de dos patas de 3 patas, lineales, no lineales, etc. ) De un ejemplo de una jerarquía de la vida diaria similar a la vista en clase. Dibuje una jerarquía de figuras geométricas (cuadrado, triángulo, pentágono, trapecio, etc. ) Dibuje una jerarquía de vehículos para pasajeros (bicicleta, motocicleta, automóvil, etc. ).
Tarjetas CRC Las tarjetas CRC (Class-Responsability-Collaboration) Son utilizadas para representar clases en el proceso de diseño. sirven para determinar que clases se necesitan y como interactúan 15 cm Nombre de Clase 10 cm Responsabilidades Colaboradores
Ejemplo Vista Dibuja el modelo Transforma coordenadas Controlador Modelo Controlador Interpreta entrada de usuario Distribuye control Modelo Mantiene información del problema Envía notificación de cambios Vista Modelo
Reglas para los nombres • Use nombres pronunciables. Como regla práctica, si no se puede leer el nombre en voz alta, no es un buen nombre. • Use mayúsculas o subrayado para marcar el principio de una nueva palabra dentro del nombre. • Examine con cuidado las abreviaturas. • No use dígitos dentro de un nombre, se pueden confundir con letras (l y 1, O y 0, etc. ) • Nombre las variables y funciones que manejen valores booleanos de tal forma que describan claramente la interpretación de un valor falso o verdadero.
Categorías de las clases Clases de manejadores de datos, de datos o de estado. Son clases cuya responsabilidad principal es mantener información de datos o de estado de un genero o de otro. Pozos de datos o fuentes de datos. Clases que generan datos o que aceptan datos y los procesan. Clase de vista u observadoras. Presentan la información en un dispositivo de salida. Clases auxiliares o de ayuda. Guardan poca o ninguna información, pero asisten en la ejecución de tareas complejas.
Diseño por escenarios Iniciar con las clases más obvias y necesarias Se simulan escenarios jugando al “que tal si”. Cada diseñador es responsable de una o más clases Se levantan las clases activas El control se pasa moviendo una tarjeta a otra Las tarjetas relacionadas se agrupan Se identifica cada acción y se hace responsable a algún objeto Se añade la responsabilidad a ese objeto Se prueban más escenarios
Case de ejemplo: Cajero automático Se desea desarrollar software para un cajero automático La primera clase es Lector. De. Tarjetas que muestra el mensaje de bienvenida y lee la banda magnética. Cuando se introduce el NIP, se lo pasa a Verificador. De. Nip pasa el número de cuenta a Manejador. De. Cuenta para confirmar cuenta y NIP. Si los números coinciden, Verificador. De. Nip regresa verdadero, sino regresa falso. Si todo está correcto Lector. De. Tarjetas pasa el control a Selector. De. Actividad.
Colaboradores Lector. De. Tarjetas Muestre mensaje de bienvenida, espere tarjeta Pida a Verificador. De. Nip que compruebe validez Llame al Selector. De. Actividad Devuelva tarjeta al usuario Verificador. De. Nip Selector. De. Actividad Colaboradores Manejador. De. Cuenta Verificar validez de cuenta; devuelva número NIP Verifique información de retiro/depósito Colaboradores Verificador. De. Nip Reciba número NIP de Manejador. De. Cuenta Colaboradores Selector. De. Actividad Presente ventana de solicitud de NIP Muestre menú de actividades Reciba número NIP del usuario Espere selección de usuario Compare números NIP; devuelva el resultado Llame al manejador de transacción apropiado Manejador. Depósito s Manejador. De. Retiros
Colaboradores Manejador. De. Retiros Pregunte al usuario la cantidad a retirar Manejador. De. Cuenta Distribuidor. De. Efectiv o Verifique la cantidad con Manejador. De. Cuenta Diga al Distribuidor. De. Efectivo que descargue Colaboradores Caja. Electrónica Dar efectivo Dar sobre de depósito con indicación de hora Recuperar sobre de depósito Manejador. De. Retiros Manejador. De. Dispositi vos
Manejadores de datos Cualquier valor al que se tenga acceso o que pueda ser modificado ampliamente, o que vaya a existir por un periodo significativo, debe ser manejado. Es decir, una y solo una clase debe tener la responsabilidad de las acciones tomadas para consultar o alterar los valores. Todas las demás clases que necesiten tener los valores deben hacer solicitudes al manejador para tales acciones, más que lograr el acceso de datos por si mismas. El acceso a datos debe quedar tan restringido como sea posible. Si una clase no necesita en absoluto el acceso a cierta parte de la información para llevar a cabo sus tareas, no debe buscar y tener tal acceso. Una clase debe tener acceso a todos los valores de datos que necesite para llevar a cabo sus responsabilidades, y solo a ellos.
Ejemplo discusión inapropiada entre manejadores Manejador. De. Retiros Manejador. De. Cuenta ¿Cuál es el saldo actual? El saldo actual es $1, 756. 09 (Hmmm. Si resto $200 a esa cantidad todavía obtengo un valor positivo. De acuerdo) Por favor ajusta el saldo a $1, 556. 09 discusión apropiada entre manejadores Manejador. De. Retiros Manejador. De. Cuenta ¿Puede retirar el cliente $200? (Hmmm. Si resto $200 a ese saldo todavía obtengo un valor positivo) Si De acuerdo. Por favor registra el retiro
Tarea #2 Describa las responsabilidades de una organización que comprenda al menos seis tipos de individuos. Ejemplos de una organización son un escuela (estudiantes, profesores, director, conserje), un negocio (secretaria, gerente, trabajadores) y un club (presidente, vicepresidente, miembros). Para cada clase de individuo, describa las responsabilidades y los colaboradores. Considere un juego común. Describa un sistema de software que interactúe con el usuario para jugarlo, (dados, solitario, damas, turista, etc. ) Para cada uno de los pares siguientes, diga si la relación es es-un o tiene-un. Casa – techo Conserje – empleado Ratón digital – dispositivo de entrada Menú – ventana Conjunto – colección
Herencia Tipos de relaciones: es-un tiene-un Herencia Composición Transporte Avión Vehículo Puerta Camión Motor Automóvil Capota Llanta
- Slides: 50