SlideShare una empresa de Scribd logo
1 de 212
Descargar para leer sin conexión
Fundamentos de la Programación Orientada a
Objetos
Una Aplicación a las Estructuras de Datos en
JavaTM
Ricardo Ruiz Rodrı́guez
Universidad Tecnológica de la Mixteca
Instituto de Computación
A Thelma
Ruiz Rodríguez, Ricardo
Fundamentos de la programación orientada a objetos: una aplicación a las estructuras de
datos en Java - 1º ed. - El Cid Editor, 2014.
pdf
ISBN digital – pdf 978-1-4135-2433-8
Fecha de catalogación: 18/02/2014
© Ricardo Ruiz Rodríguez
© El Cid Editor
ISBN versión digital pdf: 978-1-4135-2433-8
Índice general
Índice de figuras ix
Índice de ejemplos xiii
Prefacio xvii
1. Orientación a Objetos 1
1.1. Orı́genes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1
1.2. Paradigma . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2
1.2.1. Una perspectiva diferente . . . . . . . . . . . . . . . . 4
1.2.2. Objetos . . . . . . . . . . . . . . . . . . . . . . . . . . 5
1.2.3. Objetos y clases . . . . . . . . . . . . . . . . . . . . . . 6
1.3. Orientación a objetos y modularidad . . . . . . . . . . . . . . 8
1.3.1. Cohesión y Acoplamiento . . . . . . . . . . . . . . . . 9
1.4. Caracterı́sticas fundamentales de la POO . . . . . . . . . . . . 9
1.5. Consideraciones finales . . . . . . . . . . . . . . . . . . . . . . 12
1.6. Ejercicios . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13
2. Programación Orientada a Objetos 15
2.1. Mensajes y métodos . . . . . . . . . . . . . . . . . . . . . . . 16
2.1.1. Métodos sin argumentos . . . . . . . . . . . . . . . . . 16
2.1.2. Métodos con argumentos . . . . . . . . . . . . . . . . . 17
2.1.3. Métodos y atributos . . . . . . . . . . . . . . . . . . . 19
2.1.4. Métodos y constructores . . . . . . . . . . . . . . . . . 21
2.1.5. Sobrecarga . . . . . . . . . . . . . . . . . . . . . . . . . 23
2.2. Herencia . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 25
2.2.1. Abstracción . . . . . . . . . . . . . . . . . . . . . . . . 25
2.2.2. Implementación . . . . . . . . . . . . . . . . . . . . . . 28
v
ÍNDICE GENERAL
2.3. Consideraciones finales . . . . . . . . . . . . . . . . . . . . . . 33
2.3.1. Respecto al envı́o de mensajes . . . . . . . . . . . . . . 33
2.3.2. Respecto a la sobrecarga de operadores . . . . . . . . . 33
2.3.3. Respecto al paradigma . . . . . . . . . . . . . . . . . . 33
2.4. Ejercicios . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 35
3. Estructuras de datos 39
3.1. Panorama general . . . . . . . . . . . . . . . . . . . . . . . . . 39
3.2. Tipos de datos y referencias . . . . . . . . . . . . . . . . . . . 40
3.3. Tipos de datos abstractos (ADT) . . . . . . . . . . . . . . . . 41
3.3.1. Especificación del ADT Racional . . . . . . . . . . . . 43
3.3.2. Implementación del ADT Racional . . . . . . . . . . . 44
3.4. Abstracción de estructuras de datos . . . . . . . . . . . . . . . 47
3.4.1. Clases autorreferidas . . . . . . . . . . . . . . . . . . . 48
3.4.2. Implementación . . . . . . . . . . . . . . . . . . . . . . 50
3.5. Consideraciones finales . . . . . . . . . . . . . . . . . . . . . . 50
3.6. Ejercicios . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 52
4. Pilas 55
4.1. Definición . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 55
4.1.1. Operaciones primitivas . . . . . . . . . . . . . . . . . . 56
4.2. Implementación . . . . . . . . . . . . . . . . . . . . . . . . . . 57
4.2.1. Pila primitiva . . . . . . . . . . . . . . . . . . . . . . . 57
4.2.2. Pila genérica . . . . . . . . . . . . . . . . . . . . . . . 63
4.3. Aplicaciones . . . . . . . . . . . . . . . . . . . . . . . . . . . . 66
4.3.1. Análisis básico de expresiones . . . . . . . . . . . . . . 66
4.3.2. Notación interfija, postfija y prefija . . . . . . . . . . . 69
4.3.3. Evaluación de expresiones . . . . . . . . . . . . . . . . 71
4.4. Consideraciones finales . . . . . . . . . . . . . . . . . . . . . . 72
4.5. Ejercicios . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 74
5. Colas de espera 79
5.1. Definición . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 79
5.1.1. Operaciones primitivas . . . . . . . . . . . . . . . . . . 80
5.1.2. Representación . . . . . . . . . . . . . . . . . . . . . . 81
5.2. Implementación . . . . . . . . . . . . . . . . . . . . . . . . . . 82
5.3. Colas de prioridad . . . . . . . . . . . . . . . . . . . . . . . . 86
5.3.1. Cola de prioridad ascendente . . . . . . . . . . . . . . . 88
vi
6.3.1. Implementacion de una pila utilizando herencia . . . . 110
6.3.2. Implementacion de una pila utilizando composición . . 115
ÍNDICE GENERAL
5.3.2. Cola de prioridad descendente . . . . . . . . . . . . . . 94
5.4. Consideraciones finales . . . . . . . . . . . . . . . . . . . . . . 95
5.5. Ejercicios . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 97
6. Listas enlazadas 103
6.1. Definición . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 103
103
6.1.1. Operaciones primitivas . . . . . . . . . . . . . . . . . . 104
6.1.2. Representación . . . . . . . . . . . . . . . . . . . . . . 105
6.2. Implementación . . . . . . . . . . . . . . . . . . . . . . . . . . 106
6.3. Herencia vs. composición . . . . . . . . . . . . . . . . . . . . . 110
6.4. Listas circulares . . . . . . . . . . . . . . . . . . . . . . . . . . 117
6.4.1. El problema de Josephus . . . . . . . . . . . . . . . . . 119
6.5. Listas doblemente enlazadas . . . . . . . . . . . . . . . . . . . 119
6.5.1. Definición, primitivas y representación . . . . . . . . . 120
6.6. Consideraciones finales . . . . . . . . . . . . . . . . . . . . . . 122
6.7. Ejercicios . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 123
7. Árboles binarios 129
7.1. Definición . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 129
7.1.1. Representación y conceptos . . . . . . . . . . . . . . . 129
7.1.2. Operaciones primitivas . . . . . . . . . . . . . . . . . . 131
7.2. Árbol binario de búsqueda (ABB) . . . . . . . . . . . . . . . . 134
7.2.1. Operaciones primitivas . . . . . . . . . . . . . . . . . . 135
7.2.2. Representación . . . . . . . . . . . . . . . . . . . . . . 136
7.2.3. Implementación . . . . . . . . . . . . . . . . . . . . . . 137
7.2.4. Eliminación . . . . . . . . . . . . . . . . . . . . . . . . 145
7.3. Árboles binarios balanceados (AVL) . . . . . . . . . . . . . . . 147
7.3.1. Definición y conceptos . . . . . . . . . . . . . . . . . . 147
7.3.2. Rotación simple . . . . . . . . . . . . . . . . . . . . . . 148
7.3.3. Rotación doble . . . . . . . . . . . . . . . . . . . . . . 150
7.4. Consideraciones finales . . . . . . . . . . . . . . . . . . . . . . 153
7.5. Ejercicios . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 154
A. Java 159
A.1. Orı́genes y caracterı́sticas . . . . . . . . . . . . . . . . . . . . . 160
A.2. Estructura general de una clase . . . . . . . . . . . . . . . . . 160
vii
ÍNDICE GENERAL
A.3. Bienvenid@ a Java . . . . . . . . . . . . . . . . . . . . . . . . 162
A.4. Compilación . . . . . . . . . . . . . . . . . . . . . . . . . . . . 164
A.5. Ejemplos selectos . . . . . . . . . . . . . . . . . . . . . . . . . 165
A.5.1. Lectura de datos . . . . . . . . . . . . . . . . . . . . . 165
A.5.2. Estructuras de control . . . . . . . . . . . . . . . . . . 167
A.5.3. Arreglos . . . . . . . . . . . . . . . . . . . . . . . . . . 170
A.5.4. Argumentos en la lı́nea de comandos . . . . . . . . . . 171
A.5.5. Excepciones . . . . . . . . . . . . . . . . . . . . . . . . 172
A.5.6. Genéricos . . . . . . . . . . . . . . . . . . . . . . . . . 174
A.6. Ejercicios . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 176
Bibliografı́a 179
Índice Analı́tico 181
Agradecimientos 187
Acerca del Autor 189
viii
Índice de figuras
1.1. Ilusión óptica del conejo-pato creada por Joseph Jastrow . . . 3
1.2. Jerarquı́a de clases . . . . . . . . . . . . . . . . . . . . . . . . 7
2.1. Salida del Ejemplo 2.2 . . . . . . . . . . . . . . . . . . . . . . 17
2.2. Salida del Ejemplo 2.4 . . . . . . . . . . . . . . . . . . . . . . 19
2.3. Salida del Ejemplo 2.6 . . . . . . . . . . . . . . . . . . . . . . 21
2.4. Salida del Ejemplo 2.8 . . . . . . . . . . . . . . . . . . . . . . 23
2.5. Salida del Ejemplo 2.10 . . . . . . . . . . . . . . . . . . . . . . 24
2.6. Diagrama de clases UML para la relación de herencia entre
Cientifico y Persona . . . . . . . . . . . . . . . . . . . . . . . 26
2.7. Salida del Ejemplo 2.13 . . . . . . . . . . . . . . . . . . . . . . 31
3.1. Salida de una ejecución del Ejemplo 3.2 al intentar crear un
número racional cuyo denominador sea cero . . . . . . . . . . 44
3.2. Salida de la ejecución del Ejemplo 3.2 . . . . . . . . . . . . . . 46
3.3. Representación de un objeto de la clase Nodo (Ejemplo 3.3) . 49
3.4. Secuencia de nodos generados por una clase autorreferida . . . 50
3.5. Representación de un objeto autorreferido . . . . . . . . . . . 54
4.1. Crecimiento y decrecimiento de una pila . . . . . . . . . . . . 56
4.2. Abstracción de una pila como una secuencia de nodos . . . . . 57
4.3. Inserción de elementos en la pila primitiva . . . . . . . . . . . 61
4.4. Eliminación de elementos de la pila primitiva . . . . . . . . . . 62
4.5. Diagrama de clases UML para la pila genérica . . . . . . . . . 73
5.1. Inserción y eliminación de elementos en una cola de espera . . 80
5.2. Abstracción de una cola de espera como una secuencia de nodos 81
5.3. Diagrama de clases UML para la cola de espera . . . . . . . . 81
5.4. Salida del Ejemplo 5.4 . . . . . . . . . . . . . . . . . . . . . . 87
ix
ÍNDICE DE FIGURAS
5.5. Diagrama de clases en UML para una cola de prioridad ascen-
dente con la redefinición del método elimina . . . . . . . . . . 88
5.6. Diagrama de clases en UML para una cola de prioridad ascen-
dente con la redefinición del método inserta . . . . . . . . . . 89
5.7. Salida del Ejemplo 5.6 . . . . . . . . . . . . . . . . . . . . . . 93
5.8. Diagrama de clases en UML para una cola de prioridad ascen-
dente con la redefinición del método elimina . . . . . . . . . . 94
5.9. Diagrama de clases en UML para una cola de prioridad ascen-
dente con la redefinición del método inserta . . . . . . . . . . 95
5.10. Abstracción y representación de Round robin . . . . . . . . . . 98
5.11. Abstracción de una estructura de datos compuesta . . . . . . . 102
6.1. Abstraccion de una lista enlazada como una secuencia de nodos105
6.2. Diagrama de clases UML para la lista enlazada . . . . . . . . 106
6.3. Salida del Ejemplo 5.4 . . . . . . . . . . . . . . . . . . . . . . 111
6.4. Diagrama de clases UML para la implementación de una pila
utilizando herencia y una lista lista enlazada . . . . . . . . . . 112
6.5. Salida del Ejemplo 6.4 . . . . . . . . . . . . . . . . . . . . . . 114
6.6. Diagrama de clases UML para la implementación de una pila
utilizando composición y una lista lista enlazada . . . . . . . . 115
6.7. Abstraccion de una lista enlazada circular como una secuencia
de nodos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 118
6.8. Abstracción de una lista doblemente enlazada . . . . . . . . . 121
6.9. Diagrama de clases UML para una lista doblemente enlazada . 121
6.10. Representación de Round robin por niveles de prioridad . . . . 128
7.1. Abstraccion de un árbol binario como una estructura de nodos 130
7.2. Diagrama de clases UML para un árbol binario de búsqueda . 137
7.3. Una posible salida para el Ejemplo 7.3 y el Ejemplo 7.5 . . . . 142
7.4. Diagrama de clases UML para un árbol binario de búsqueda
con eliminación . . . . . . . . . . . . . . . . . . . . . . . . . . 147
7.5. Caso 1: Rotación derecha [Wirth] . . . . . . . . . . . . . . . . 149
7.6. Ejemplo de aplicación de la rotación sencilla . . . . . . . . . . 150
7.7. Caso 3: Rotación doble izquierda derecha (adaptada de [Wirth])151
7.8. Ejemplo de aplicación de la rotación doble . . . . . . . . . . . 152
7.9. Representación de un ABB . . . . . . . . . . . . . . . . . . . . 154
7.10. Eliminación en un árbol AVL (adaptada de [Wirth]) . . . . . . 158
x
ÍNDICE DE FIGURAS
A.1. Salida del Ejemplo A.2 . . . . . . . . . . . . . . . . . . . . . . 163
A.2. Salida del Ejemplo A.4 . . . . . . . . . . . . . . . . . . . . . . 163
A.3. Salida del Ejemplo A.6 . . . . . . . . . . . . . . . . . . . . . . 167
A.4. Salida del Ejemplo A.7 . . . . . . . . . . . . . . . . . . . . . . 169
A.5. Salida de los Ejemplos A.8, A.9 y A.10 . . . . . . . . . . . . . 170
A.6. Salida del Ejemplo A.11 . . . . . . . . . . . . . . . . . . . . . 171
A.7. Salida del Ejemplo A.12 sin argumentos . . . . . . . . . . . . 172
A.8. Salida del Ejemplo A.12 con argumentos . . . . . . . . . . . . 172
A.9. Relación UML de la jerarquı́a de la clases Exception en Java . 173
xi
Índice de ejemplos
2.1. Definición de la clase Parvulo1 . . . . . . . . . . . . . . . . . . 16
2.2. Clase de prueba para la clase Parvulo1 . . . . . . . . . . . . . 16
2.3. Definición de la clase Parvulo2 . . . . . . . . . . . . . . . . . . 18
2.4. Clase de prueba para la clase Parvulo2 . . . . . . . . . . . . . 18
2.5. Definición de la clase Parvulo3 . . . . . . . . . . . . . . . . . . 19
2.6. Clase de prueba para la clase Parvulo3 . . . . . . . . . . . . . 20
2.7. Definición de la clase Parvulo4 . . . . . . . . . . . . . . . . . . 22
2.8. Clase de prueba para la clase Parvulo4 . . . . . . . . . . . . . 23
2.9. Definición de la clase Parvulo5 . . . . . . . . . . . . . . . . . . 24
2.10. Clase de prueba para la clase Parvulo5 . . . . . . . . . . . . . 24
2.11. Definición de la clase Persona . . . . . . . . . . . . . . . . . . 28
2.12. Definición de la clase Cientifico . . . . . . . . . . . . . . . . . 30
2.13. Clase de prueba para la herencia . . . . . . . . . . . . . . . . 32
3.1. Clase implementa la abstracción de un número racional . . . . 44
3.2. Clase de prueba para la clase Racional . . . . . . . . . . . . . 47
3.3. Clase autorreferida . . . . . . . . . . . . . . . . . . . . . . . . 49
4.1. Definición de la clase NodoPrimitivo . . . . . . . . . . . . . . 57
4.2. Definición de la clase PilaPrimitiva . . . . . . . . . . . . . . . 58
4.3. Definición de la clase ExcepcionEDVacia que se utiliza para la
implementación de todas las estructuras de datos . . . . . . . 60
4.4. Clase de prueba para la clase PilaPrimitiva . . . . . . . . . . . 61
4.5. Definición de la clase para un nodo genérico (NodoG) . . . . . 63
4.6. Definición de la clase Pila que permite almacenar objetos genéri-
cos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 64
4.7. Clase de prueba para la pila genérica . . . . . . . . . . . . . . 65
5.1. Nodo genérico utilizado en la cola de espera . . . . . . . . . . 82
5.2. Excepción utilizada en la cola de espera . . . . . . . . . . . . 83
xiii
ÍNDICE DE EJEMPLOS
5.3. Definición de la clase Cola que permite almacenar objetos
genéricos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 84
5.4. Clase de prueba para la cola de espera . . . . . . . . . . . . . 86
5.5. Clase que define una cola de prioridad ascendente sobre escri-
biendo el método inserta . . . . . . . . . . . . . . . . . . . . . 90
5.6. Clase de prueba para la cola de prioridad ascendente . . . . . 92
5.7. Clase que implementa la interfaz Comparable . . . . . . . . . . 99
6.1. Definición de la clase Lista que permite almacenar objetos
genéricos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 107
6.2. Clase de prueba para la clase Lista . . . . . . . . . . . . . . . 109
6.3. Definición de la clase PilaH que implementa una pila de obje-
tos genéricos utilizando herencia y una lista enlazada . . . . . 112
6.4. Clase de prueba para PilaH . . . . . . . . . . . . . . . . . . . 113
6.5. Definición de la clase PilaC que implementa una pila de obje-
tos genéricos utilizando composición y una lista enlazada . . . 116
6.6. Clase de prueba para PilaC . . . . . . . . . . . . . . . . . . . 117
7.1. Definición de la clase NodoABB que permite representar ob-
jetos (nodos) genéricos para un árbol binario de búsqueda . . 138
7.2. Definición de la clase ABBr que permite almacenar nodos (No-
doABB) en un árbol binario de búsqueda . . . . . . . . . . . . 139
7.3. Clase de prueba para el árbol binario de búsqueda (recursivo) 141
7.4. Definición de la clase ABB que permite almacenar nodos (No-
doABB) en un árbol binario de búsqueda . . . . . . . . . . . . 143
7.5. Clase de prueba para el árbol binario de búsqueda . . . . . . . 145
A.1. Estructura general de una clase en Java . . . . . . . . . . . . . 161
A.2. Primer programa en Java (versión 1.0) . . . . . . . . . . . . . 162
A.3. Primer programa en Java (versión 1.1) . . . . . . . . . . . . . 163
A.4. Primer programa en Java (versión 1.2) . . . . . . . . . . . . . 163
A.5. Primer programa en Java (versión 1.3) . . . . . . . . . . . . . 164
A.6. Lectura de datos desde la entrada estándar . . . . . . . . . . . 166
A.7. Uso de la estructura de selección if y de los operadores rela-
cionales . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 168
A.8. Estructura de repetición while . . . . . . . . . . . . . . . . . 169
A.9. Estructura de repetición do-while . . . . . . . . . . . . . . . 170
A.10.Estructura de repetición for . . . . . . . . . . . . . . . . . . . 170
A.11.Arreglo de enteros (int) . . . . . . . . . . . . . . . . . . . . . 171
A.12.Procesamiento de argumentos en la lı́nea de comandos . . . . 172
A.13.Definición de una excepción . . . . . . . . . . . . . . . . . . . 174
xiv
ÍNDICE DE EJEMPLOS
A.14.Uso de una colección ArrayList . . . . . . . . . . . . . . . . . 177
xv
Prefacio
Estimado lector, este libro tiene una orientación especı́fica. Está pensado
para un curso introductorio de programación orientada a objetos, en donde,
de manera preferente aunque de ninguna manera obligatoria, se haya tenido
un contacto previo con algún lenguaje de programación utilizando el enfo-
que estructurado; sin embargo, también es mi intención que el libro sea de
utilidad para aquellos lectores que se quieran iniciar en el mundo de la pro-
gramación y el paradigma orientado a objetos, sin ningún requisito previo de
programación.
El libro asume que el lector posee conocimientos básicos de algoritmos
y/o programación, ası́ como el funcionamiento de las estructuras de control
secuencial, de selección, y de repetición. Por otro lado, si bien es cierto que
para la comprensión del paradigma no es preciso dichos conocimientos (de
hecho podrı́an generar un vicio para un paradigma de programación orien-
tado a objetos más puro), sı́ lo son para la comprensión y el seguimiento
correspondiente de los programas de ejemplo.
Con todo, el libro proporciona un apéndice para apoyar al lector a través
de ejemplos selectos, tanto en la introducción del lenguaje de programación
utilizado, como en los conceptos fundamentales de la programación.
Al respecto, existe un debate acerca de si es mejor enseñar el paradig-
ma orientado a objetos sin antes tener un conocimiento de otro enfoque de
programación (como el estructurado por ejemplo), o si es mejor partir de la
programación estructurada para realizar una transición hacia la programa-
ción orientada a objetos. En mi opinión ambos enfoques tienen sus ventajas
y desventajas, y se podrı́a estar ante el sempiterno problema del huevo y la
gallina.
Java es un lenguaje de programación hı́brido, en el sentido de que no es
un lenguaje totalmente orientado a objetos como Smalltalk, y en ese sentido,
tiene estructuras de control y tipos de datos primitivos al estilo del lenguaje
xvii
PREFACIO
de programación C, el cual es el lenguaje por antonomasia para la progra-
macion estructurada y, dado que este libro utiliza a Java como lenguaje de
programación, aquellos lectores que conozcan el lenguaje C se sentirán fami-
liarizados rápidamente con Java, concentrándose entonces en la asimilación
del paradigma y en su aplicación.
Por otro lado, aquellos lectores que no conozcan el enfoque estructurado
estarı́an, al menos de primera instancia, sin la predisposición a cometer uno
de los vicios más comunes en la programación orientada a objetos, como lo es
el de utilizar Java por ejemplo, para escribir programas siguiendo un enfoque
estructurado. En éste sentido, resulta fundamental enfatizar desde ahora que
el uso de un lenguaje de programación orientado a objetos, no hace per se, ni
mucho menos garantiza, que los programas que se escriban en dicho lenguaje
sigan el modelo de programación orientado a objetos.
Como en muchas cosas, más que establecer qué es lo mejor y qué no
lo es, ya que se está ante una disyuntiva subjetiva, finalmente el beneficio
dependerá tanto de las intenciones del lector, como de su disposición hacia la
comprensión del paradigma orientado a objetos, ası́ como de que se entienda,
que la asimilación de un nuevo enfoque de programación no es excluyente de
otros, sino que la diversidad de enfoques de solución o formas de resolver un
problema, amplı́an el repertorio de conocimientos y capacidades intelectuales
en pro de ser progresiva y eventualmente, mejores programadores.
Para ilustrar y complementar de mejor manera tanto el diseño como los
conceptos relacionados con los objetos, el libro se apoya de diagramas de
clase UML para su correspondiente representación, por lo que serı́a también
de mucha utilidad tener bases de UML, sin embargo, tampoco son indispen-
sables.
La intención de este libro es también la de introducir al lector en algunas
de las estructuras de datos más convencionales, y al mismo tiempo, utilizarlas
para ilustrar los conceptos del paradigma orientado a objetos a través de su
implementación. En éste sentido, la estructura general del libro, es la que se
describe a continuación:
Capı́tulo 1 presenta los elementos fundamentales de la orientación a obje-
tos. La intención del capı́tulo es la de proporcionar al lector un pano-
rama general del paradigma orientado a objetos sin asociarlo necesa-
riamente con la programación, y mucho menos con algún lenguaje de
programación en particular.
xviii
Capı́tulo 2 describe las bases del paradigma orientado a objetos en el con-
texto de su aplicación a la programación, utilizando a Java como len-
guaje de programación.
La intención del capı́tulo es la de concretizar en un lenguaje de progra-
macion especı́fico, los conceptos más distintivos del paradigma orienta-
do a objetos, para que en los capı́tulos siguientes, se puedan aplicar al
desarrollo de las estructuras de datos, y mejorar ası́ tanto su compren-
sión, como la experiencia del lector de manera progresiva.
Capı́tulo 3 presenta un panorama general de las estructuras de datos, tipos
de datos y referencias en Java. Se aborda también un concepto central
tanto para el paradigma orientado a objetos, como para las estructuras
de datos: los tipos de datos abstractos (ADT). Ası́ mismo, se sientan
las bases para la implementación de estructuras de datos basadas en
clases de autorreferencia.
Capı́tulo 4 presenta la primera de las estructuras de datos estudiadas en
el libro. El capı́tulo comienza con la definición de las propiedades y
operaciones definidas para el ADT pila, para después presentar la im-
plementación de una pila utilizando un tipo de dato primitivo. Poste-
riormente, tomando como base dicha implementación, se generaliza el
concepto para mostrar la implementación de una pila cuyos elementos
son objetos genéricos. Finalmente, se refuerza la definición del ADT, y
se muestra la relación que existe entre la implementación y el diseño
con el correspondiente diagrama de clases en UML.
Capı́tulo 5 introduce al lector en el estudio de las estructuras de datos de-
nominadas colas de espera. Se realiza una presentación de la cola de
espera ası́ como de su correspondiente implementación, para posterior-
mente analizar una variante de dicha estructura de datos: las colas de
prioridad. Ası́ mismo, el capı́tulo también presenta los elementos princi-
pales para la implementación de objetos con caracterı́sticas de relación
de orden a través de la interfaz Comparable del API de Java. Dicha
caracterı́stica resultará fundamental para los capı́tulos posteriores.
Capı́tulo 6 presenta al lector la última de las estructuras de datos linea-
les estudiadas en el libro: las listas enlazadas. Ası́ mismo, toda vez
que se asume completado el estudio de las pilas, el capı́tulo muestra
la posibilidad de la implementación de dicha estructura de datos por
xix
PREFACIO
medio de una lista enlazada. Adicionalmente, se comentan las ventajas
y desventajas de los enfoques de implementación utilizados.
Capı́tulo 7 introduce al lector tanto a los conceptos de árboles binarios,
como al conocimiento de algunas de las estructuras de datos de árboles
mas comunes: árboles binarios, árboles binarios de búsqueda (ABB), y
árboles AVL.
Los árboles binarios son estructuras de datos no lineales, y sus aplica-
ciones y usos son tan diversos, que están únicamente limitados por la
imaginación de quien los utiliza. El capı́tulo inicia presentando los con-
ceptos relacionados con los árboles binarios en general, y con los ABB
y AVL en particular. Presenta además dos tipos de implementación
para un ABB: con recursividad y con ciclos, y se describen también los
diferentes recorridos que es posible realizar con árboles binarios.
Apéndice A presenta un compendio de referencia a la mano de Java para
el lector familiarizado con algún lenguaje de programación. Al mismo
tiempo, es un marco de referencia respecto a caracterı́sticas que no se
tienen en un enfoque estructurado, como lo son las excepciones y los
genéricos por ejemplo. El apéndice presenta además una selección de
ejemplos de transición respecto a la forma de hacer las cosas en Java,
sin entrar en detalles especı́ficos respecto a la definición y descripción
de las estructuras de control, representación y notación de arreglos, etc.
Insisto en que este libro tiene una naturaleza introductoria, pero no por
ello informal. Confı́o plenamente en que puede servir como inicio de un largo
camino en la asimilación progresiva de los conceptos asociados con el para-
digma orientado a objetos. Espero sinceramente haber podido alcanzar la
meta de transmitir los conceptos fundamentales de la orientación a objetos,
ası́ como su aplicación en las estructuras de datos, utilizando al lenguaje de
programación Java como medio.
Ricardo Ruiz Rodrı́guez
xx
I consider to paradigms as universally recognized scientific
achievements that, for a time, provide model problems and
solutions for a community of researchers.
Thomas Samuel Kuhn
Programming is one of the most difficult branches of applied
mathematics; the poorer mathematicians had better remain pure
mathematicians.
Edsger Wybe Dijkstra
xxi
Capı́tulo 1
Orientación a Objetos
Technology is anything that wasn’t around when you were born.
Alan Curtis Kay
Hong Kong press conference
1.1. Orı́genes
Las caracterı́sticas principales de lo que actualmente se denomina Pro-
gramación Orientada a Objetos (POO) surgen en 1960, y aunque algunos
autores difieren en sus orı́genes, los conceptos de la POO tienen su inicio en
Simula 67, un lenguaje diseñado en el centro de cómputo noruego en Oslo1
.
Posteriormente, en Agosto de 1981, se publica en la revista Byte la des-
cripción del lenguaje de programación Smalltalk2
, el cual refinó algunos de
los conceptos originados con el lenguaje Simula.
Lo anterior dio pie a que en la década de 1980, los lenguajes de progra-
mación Orientados a Objetos (OO) tuvieran un rápido auge y expansión,
por lo que la POO se fue convirtiendo en el estilo de programación dominan-
te a mediados de los años ochenta del siglo XX, continuando vigente hasta
nuestros dı́as.
La POO es una de las propuestas de solución para ayudar a resolver
la denominada, aunque no generalmente aceptada, “crisis del software”. En
este sentido, es importante decir que, si bien las técnicas OO facilitan la
1
Lenguaje para simulaciones creado por Ole-Johan Dahl y Kristen Nygaard.
2
Desarrollado en Xerox PARC (Palo Alto-California Research Center).
1
2 CAPÍTULO 1. ORIENTACIÓN A OBJETOS
creación de complejos sistemas de software por medio de mejores mecanismos
de abstracción, no son la panacea universal de solución.
Programar una computadora sigue siendo una de las tareas más difı́ci-
les jamás realizadas por un ser humano. Volverse experto en programación
requiere, no sólo de saber manejar herramientas y conocer técnicas de pro-
gramación, sino que es preciso contar también con:
Talento.
Creatividad.
Inteligencia.
Lógica.
Habilidad para construir y utilizar abstracciones.
Experiencia.
Por lo anterior, hacer un uso efectivo de los principios OO requiere de
una visión del mundo desde una perspectiva distinta, sobre todo si se parte
de la base de resolución de problemas a través de un enfoque estructurado.
Es importante señalar y tener presente desde este momento, que el uso de
un lenguaje de POO no hace, por sı́ mismo, que se programe OO, ya que se
podrı́a tener en el mejor de los casos, un programa o sistema implementado
con un enfoque estructurado, pero programado en un lenguaje orientado a
objetos.
La POO requiere de la comprensión del paradigma orientado a objetos.
La sección 1.2 discute el concepto de paradigma que se utilizará a lo largo
del texto.
1.2. Paradigma
El concepto de paradigma resulta fundamental en la comprensión del
paradigma orientado a objetos.
Antes de proporcionar la definición que se adoptará, describiré algunas
definiciones de paradigma que encontré:
paradigma m. Ejemplo o ejemplar: esa chica es el paradigma de la pacien-
cia.
1.2. PARADIGMA 3
Figura 1.1: Ilusión óptica del conejo-pato creada por Joseph Jastrow
paradigma ling. Cada uno de los esquemas formales a los que se ajustan las
palabras, según sus respectivas flexiones: paradigma de la conjugación
verbal.
paradigma ling. Conjunto de elementos de una misma clase gramatical que
pueden aparecer en un mismo contexto: paradigma de las preposiciones.
paradigma ejemplo o modelo. En todo el ámbito cientı́fico, religioso u otro
contexto epistemológico, el término paradigma puede indicar el concep-
to de esquema formal de organización, y ser utilizado como sinónimo
de marco teórico o conjunto de teorı́as.
Pero entonces, ¿qué entender por paradigma de programación?
La palabra paradigma irrumpió en el vocabulario moderno a través del
influyente libro “The Structure of Scientific Revolutions”del historiador de
la ciencia Thomas Samuel Kuhn[Kuhn].
Thomas Kuhn utilizó el término en la forma de la última definición: un
paradigma es un modelo para describir un conjunto de teorı́as, estándares y
métodos que en conjunto representan una forma de organizar el conocimiento,
esto es, una forma de ver el mundo.
En base a lo anterior se entederá como paradigma de programación
al modelo de programación utilizado, el cual está descrito y definido por un
conjunto de teorı́as, estándares y métodos que en conjunto, representan una
propuesta de solución por software hacia una problemática determinada.
4 CAPÍTULO 1. ORIENTACIÓN A OBJETOS
Kuhn utilizó la ilusión óptica de la Figura 1.1 para ilustrar el concepto
de paradigma. En dicha figura puede verse un conejo o un pato, dependiendo
de la perspectiva que se utilice.
El paradigma orientado a objetos cambió la perspectiva respecto del en-
foque estructurado, el cual era el paradigma dominante hasta entonces.
1.2.1. Una perspectiva diferente
El concepto sobre el que subyace la esencia de la orientación a objetos
es la abstracción. Por lo que, al pensar en este paradigma, deberá tener en
mente una perspectiva basada en los siguientes conceptos:
1. Entidades: agentes u objetos en interacción, donde cada objeto tiene
un rol.
2. Responsabilidades: cada objeto proporciona un conjunto de servicios
o lleva a cabo acciones que son utilizadas por otras entidades u objetos.
Las responsabilidades determinan el comportamiento del objeto.
3. Mensajes: en la POO la acción es iniciada por la transmisión de un
mensaje a un objeto responsable de dicha acción. En respuesta al men-
saje, el objeto receptor llevará a cabo un método para satisfacer la
solicitud que le fue realizada por dicho mensaje.
Los tres elementos anteriormente mencionados, constituyen los funda-
mentos primordiales de la orientación a objetos. A lo largo del texto se desa-
rrollarán de manera progresiva, y se ejemplificarán con programas.
Mensajes, procedimientos/funciones y métodos
Los mensajes son solicitudes especı́ficas de alguno de los servicios o res-
ponsabilidades asignadas a un objeto. Los mensajes tienen un receptor es-
pecı́fico, por lo que son enviados a un objeto en particular con una posible
lista de argumentos determinada.
Los mensajes son llevados a cabo por métodos, los cuales son algoritmos
asociado a un objeto (o a una clase de objetos), cuya ejecución se desencadena
tras la recepción de un mensaje. En este sentido, tanto los métodos como los
procedimientos o funciones son un conjunto de pasos bien definidos que llevan
a cabo una acción; sin embargo, los mensajes y los procedimientos o funciones
se distinguen esencialmente por dos aspectos:
1.2. PARADIGMA 5
1. En un mensaje, hay un receptor designado para dicho mensaje.
2. La interpretación o método utilizado para responder al mensaje es de-
terminado por el receptor, y puede variar en función del receptor.
1.2.2. Objetos
Los objetos son esencialmente abstracciones. Son entidades que tienen un
determinado estado, un comportamiento (determinado por sus responsabili-
dades), y una identidad.
El estado está representado por los datos o los valores que contienen los
atributos del objeto, los cuales son a su vez, otros objetos o variables
que representan las caracterı́sticas inherentes del objeto.
El comportamiento está determinado por las responsabilidades o servicios
del objeto, los cuales son definidos por los métodos, mismos que se
solicitan a través de mensajes a los que sabe responder dicho objeto.
La identidad es la propiedad que tiene un objeto que lo distingue de los
demás. La identidad está representada por un identificador.
Un objeto es una entidad que contiene en sı́ mismo, toda la información
necesaria, misma que permite definirlo, identificarlo, y accederlo3
frente a
otros objetos pertenecientes a otras clases, e incluso frente a objetos de su
misma clase.
Los objetos se valen de mecanismos de interacción llamados métodos,
que favorecen la comunicación entre ellos. Dicha comunicación favorece a su
vez el cambio de estado en los propios objetos. Esta caracterı́stica define a
los objetos como unidades indivisibles, en las que no se separa el estado del
comportamiento.
Orientación a objetos vs. enfoque estructurado
La orientación a objetos difiere del enfoque estructurado básicamente, en
que en la programación estructurada los datos y los procedimientos están
3
La forma de acceder a un objeto es a través de su interfaz. La interfaz de un objeto
es el conjunto de servicios públicos que ofrece el objeto, los cuales se solicitan a través de
mensajes o solicitudes realizadas a dicho objeto.
6 CAPÍTULO 1. ORIENTACIÓN A OBJETOS
separados y sin relación, ya que lo único que se busca en ésta última, es el
procesamiento de los datos de entrada para obtener los datos de salida.
La programación estructurada utiliza en primera instancia, un enfoque
basado en procedimientos o funciones, y en segunda instancia, las estructuras
de datos que dichos procedimientos o funciones manejan, cumpliendo ası́ la
Ecuación 1.1 planteada por Niklaus Wirth.
Algoritmos + Estructuras de Datos = Programas (1.1)
Por otro lado, un programa en un enfoque OO solicita estructuras de
datos (las cuales son otros objetos) para llevar a cabo un servicio.
La perspectiva OO también define programas compuestos por algoritmos
y estructuras de datos esencialmente (como los de la Ecuación 1.1), sin em-
bargo lo hace desde un enfoque diferente. En la orientación a objetos la des-
cripción del objeto se da en términos de responsabilidades y caracterı́sticas, y
al analizar un problema en dichos términos, se eleva el nivel de abstracción.
Lo anterior permite una mayor independencia entre los objetos, lo cual
es un factor crı́tico en la solución de problemas complejos. Cabe mencionar
por último, que al conjunto completo de responsabilidades asociadas con un
objeto es comúnmente referido como protocolo.
1.2.3. Objetos y clases
Todos los objetos son instancias de una clase (categorı́a). Esta relación
de un objeto con una clase, hace que los objetos tengan las siguientes carac-
terı́sticas:
El método invocado por un objeto en respuesta a un mensaje, es de-
terminado por la clase del objeto receptor.
Todos los objetos de una clase determinada, utilizan el mismo método
en respuesta a mensajes similares.
Las clases pueden ser organizadas en una estructura jerárquica de he-
rencia como la que se muestra en la Figura 1.2.
Una clase hija o subclase heredará todas las caracterı́sticas de la clase
de la que deriva (clase padre).
1.2. PARADIGMA 7
Figura 1.2: Jerarquı́a de clases
Una clase abstracta es una clase de la que no se derivan instancias
directamente, sino que es utilizada únicamente para crear subclases.
La búsqueda del método a invocar en respuesta a un mensaje deter-
minado, inicia en la clase del receptor. Si no se encuentra el método
apropiado, la búsqueda se realiza en la clase padre, y ası́ sucesivamente
hasta encontrar el método correspondiente.
Si se encuentran métodos con el mismo nombre dentro de la jerarquı́a
de clases, se dice que el método procesado sobre escribe (override) el
comportamiento heredado.
La Figura 1.2 presenta una posible jerarquı́a de clases para un Ser Vivo.
Mas que una clasificación o taxonomı́a completa, la figura muestra el concepto
de herencia a través de un árbol, el cual exhibe, que los elementos que se
derivan, comparten caracterı́sticas (atributos) y comportamientos (métodos)
semejantes.
Ası́ por ejemplo, es posible decir que Flipper es una instancia particular de
todos los posibles delfines que podrı́an existir. A su vez, un Delfı́n comparte
8 CAPÍTULO 1. ORIENTACIÓN A OBJETOS
caracterı́sticas comunes con una Ballena en cuanto a que ambos son Cetáceos,
pero difieren en otras4
.
Un Delfı́n es un Cetáceo, y un Cetáceo es un Mamı́fero. En muchas oca-
siones a éste tipo de relaciones se le denomina “es un”(is a), y es una carac-
terı́stica útil para identificar herencia, pero no es la única.
Existe otro tipo de relación y se denomina “tiene” (has-a). Estas relacio-
nes son las dos formas más importantes de abstracción en la orientación a
objetos:
1. La idea de división en partes (has-a): un automóvil tiene un motor,
tiene una transmisión, tiene un sistema eléctrico, etc.
2. La idea de división en especializaciones (is-a): un automóvil es un
medio de transporte, es un objeto de cuatro ruedas, es un objeto que
se dirige con un volante, etc.
Finalmente, la Figura 1.2 muestra que Flipper es un Delfı́n, que un Delfı́n
es un Cetáceo, y que éste a su vez es un Mamı́fero; que un Mamı́fero per-
tenece al Reino Animal, y que el Reino Animal es parte de los seres vivos
representados por la super clase o clase base Ser Vivo.
1.3. Orientación a objetos y modularidad
La modularidad no está exclusivamente relacionada con los procedimien-
tos o funciones de la programación estructurada, sino con el grado en el que
los componentes de un sistema pueden ser separados y reutilizados.
En base a lo anterior, tanto los métodos como los objetos son en sı́ mismos
módulos de una aplicación determinada, y en consecuencia, las clases de las
que se derivan constituyen los módulos del sistema, por lo que de aquı́ en
adelante se hará referencia a la modularidad de manera indistinta tanto para
clases, como para los métodos de las clases.
La modularidad ayuda también a hacer el código más comprensible, y ésto
a su vez hace que en consecuencia el código sea más fácil de mantener. Sin
embargo, sin las debidas consideraciones, la modularidad tiene también sus
consecuencias negativas, las cuales están en función directa de dos conceptos
4
Si un delfı́n y una ballena coincidieran en todo (caracterı́sticas y comportamiento)
serı́an de la misma clase.
1.4. CARACTERÍSTICAS FUNDAMENTALES DE LA POO 9
fundamentales en el desarrollo de software en general, y en el paradigma
orientado a objetos en particular:
1. Cohesión.
2. Acoplamiento.
1.3.1. Cohesión y Acoplamiento
La cohesión está relacionada con la integridad interna de un módulo. Es
el grado o nivel de relación o integridad entre los elementos que componen
un módulo.
El nivel de cohesión determina, qué tan fuerte están relacionados cada
unos de los elementos de funcionalidad expresados en el código fuente de un
módulo.
Por otro lado, el acoplamiento describe qué tan fuerte un módulo está re-
lacionado con otros, es decir, es el grado en que un módulo depende de cada
uno de los otros módulos que componen un sistema.
El acoplamiento también puede ser referido o entendido como dependen-
cia, lo cual ayuda a recordar que lo que se desea es mantener un bajo nivel
de dependencia entre los módulos, es decir un bajo acoplamiento.
En general, se desea que los módulos de un programa o sistema tengan,
un alto nivel de cohesión y un bajo nivel de acoplamiento, y el paradigma
orientado a objetos persigue y enfatiza dichos objetivos.
1.4. Caracterı́sticas fundamentales de la POO
Por último, pero no por ello menos importante, es importante mencionar
que Alan Curtis Kay, quien es considerado por muchos como el padre de la
POO, definió un conjunto de caracterı́sticas fundamentales para el paradig-
ma.
En base a lo propuesto por Kay, en la Programación Orientada a Objetos:
1. Todo es un objeto.
2. El procesamiento es llevado a cabo por objetos:
10 CAPÍTULO 1. ORIENTACIÓN A OBJETOS
Los objetos se comunican unos con otros solicitando que se lleven
a cabo determinadas acciones.
Los objetos se comunican enviando y recibiendo mensajes.
Un mensaje es la solicitud de una acción, la cual incluye los argu-
mentos que son necesarios para completar la tarea.
3. Cada objeto tiene su propia memoria, misma que está compuesta de
otros objetos.
4. Cada objeto es una instancia de una clase. Una clase representa un
grupo de objetos similares.
5. La clase es el repositorio del comportamiento asociado con un objeto.
Todos los objetos que son instancias de la misma clase, llevan a
cabo las mismas acciones.
6. Las clases están organizadas en una estructura jerárquica de árbol de-
nominada jerarquı́a de herencia.
La memoria y el comportamiento asociados con las instancias de
una clase, están automáticamente disponibles para cualquier clase
asociada con la descendencia dentro de la estructura jerárquica de
árbol.
Complementando la visión de Alan Kay, se presenta a continuación un
compendio de conceptos que definen también y refuerzan, las caracterı́sticas
principales de la POO:
La abstracción denota las caracterı́sticas esenciales de un objeto.
El proceso de abstracción permite seleccionar las caracterı́sticas rele-
vantes dentro de un conjunto, e identificar comportamientos comunes
para definir nuevos tipos de entidades.
La abstracción es la consideración aislada de las cualidades esenciales
de un objeto en su pura esencia o noción.
La modularidad es la propiedad que permite subdividir una aplicación en
partes más pequeñas (llamadas módulos), cada una de las cuales debe
1.4. CARACTERÍSTICAS FUNDAMENTALES DE LA POO 11
ser tan independiente como sea posible de la aplicación en sı́, y de las
partes restantes.
La modularidad es el grado en el que los componentes de un sistema
pueden ser separados y reutilizados.
El encapsulamiento tiene que ver con reunir todos los elementos que pue-
den considerarse pertenecientes a una misma entidad, al mismo nivel
de abstracción. Esto permite aumentar la cohesión de los módulos o
componentes del sistema.
El principio de ocultación de información (information hiding) se re-
fiere a que cada objeto está aislado del exterior, es un módulo indepen-
diente, y cada tipo de objeto presenta una interfaz a otros objetos, la
cual especifica cómo es que pueden interactuar con él.
El aislamiento protege a las propiedades de un objeto contra su mo-
dificación por quien no tenga derecho a acceder a ellas; solamente los
propios métodos internos del objeto pueden acceder a su estado. Ésto
asegura que otros objetos no puedan cambiar el estado interno de un
objeto de manera accidental o intencionada, eliminando efectos secun-
darios e interacciones inesperadas.
El polimorfismo está relacionado con el aspecto de que comportamientos
diferentes asociados a objetos distintos, pueden compartir el mismo
nombre.
El polimorfismo es la capacidad que tienen los objetos de naturaleza
heterogénea, de responder de manera diferente a un mismo mensaje, en
función de las caracterı́sticas y responsabilidades del objeto que recibe
dicho mensaje.
La herencia organiza y facilita el polimorfismo y el encapsulamiento, per-
mitiendo a los objetos ser definidos y creados como tipos especializados
de objetos preexistentes.
Las clases no están aisladas, sino que se relacionan entre sı́ formando
una jerarquı́a de clasificación.
Los objetos heredan las propiedades y el comportamiento de todas las
clases a las que pertenecen. Ası́, los objetos pueden compartir y exten-
der su comportamiento sin tener que volver a implementarlo.
12 CAPÍTULO 1. ORIENTACIÓN A OBJETOS
Cuando un objeto hereda de más de una clase se dice que hay herencia
múltiple.
Es importante tener todos estos conceptos presentes, estudiarlos, anali-
zarlos y comprenderlos, la memorización no es recomendable, ya que es bien
sabido que el memorizar conceptos no implica su comprensión, pero si un
concepto es comprendido, es posible explicarlo y deducir en consecuencia su
definición.
Mi deseo es que el lector reflexione sobre este aspecto y que, con un
poco de paciencia, sume a su repertorio de conocimientos el conjunto de
conceptos descritos hasta aquı́, los cuales se pondrán en práctica eventual y
progresivamente, en los capı́tulos siguientes.
1.5. Consideraciones finales
Este capı́tulo discutió los elementos fundamentales de la orientación a
objetos. La intención del capı́tulo es la de proporcionar al lector un panorama
general del paradigma orientado a objetos, sin asociarlo necesariamente con
la programación, y mucho menos con algún lenguaje de programación en
particular.
Un lenguaje de programación es sólo un medio para el paradigma, no el
paradigma en sı́. Por otro lado, el ejercicio de la programación es la forma
de aplicar los conceptos asociados al paradigma.
Los capı́tulos siguientes irán detallando al lector los conceptos presentados
hasta ahora, pero desde la perspectiva de la programación y su aplicación
en un lenguaje de programación. Sin embargo, es importante aclarar que
el objetivo del libro no es enseñar un lenguaje de programación, sino el de
utilizar al lenguaje como un medio para hacer tangibles los conceptos de
orientación a objetos.
El Apéndice A introduce algunos aspectos del lenguaje de programación
Java que podrı́an ser de utilidad para el lector, pero de ninguna manera
pretende cubrir los elementos completos de dicho lenguaje, sino solamente
presentar un panorama general.
1.6. EJERCICIOS 13
1.6. Ejercicios
1. Investigue más acerca de la historia y desarrollo de la programación
orientada a objetos.
2. Xerox es actualmente una compañı́a que desarrolla equipo de foto copia-
do e impresión entre otras cosas. Investigue cuál era el sistema operativo
que utilizaban, que por cierto, ya incluı́a una GUI (Interfaz Gráfica de
Usuario), pionera de las GUI que actualmente se utilizan.
3. Investigue la historia y la ideologı́a del lenguaje de programación Small-
talk. Aproveche para conocer el nombre de su(s) creador(es).
4. Investigue la historia y la ideologı́a del lenguaje de programación Eiffel.
Aproveche para conocer el nombre de su(s) creador(es).
5. Investigue la historia del lenguaje de programación C++. Aproveche
para conocer el nombre de su(s) creador(es).
6. Investigue el papel del Dr. Alan Curtis Kay en la concepción y desa-
rrollo de la programación orientada a objetos.
7. Investigue qué otros paradigmas de programación existen.
8. Investigue qué lenguajes de programación actuales soportan el paradig-
ma orientado a objetos, cuáles lo soportan de manera nativa y cuáles
como una extensión.
14 CAPÍTULO 1. ORIENTACIÓN A OBJETOS
Capı́tulo 2
Programación Orientada a
Objetos
Object-oriented programming is an exceptionally bad idea which
could only have originated in California.
Edsger Wybe Dijkstra (attributed to)
I don’t know how many of you have ever met Dijkstra, but you
probably know that arrogance in computer science is measured in
nano-Dijkstras.
Alan Curtis Kay
Este capı́tulo presenta las bases del paradigma orientado a objetos en
el contexto de su aplicación a la programación utilizando un lenguaje de
programación.
La intención principal del capı́tulo, es concretizar en un lenguaje de pro-
gramación los conceptos más distintivos del paradigma orientado a objetos,
para que en los capı́tulos subsecuentes, se puedan aplicar al desarrollo de las
estructuras de datos, y mejorar ası́ tanto la comprensión de los conceptos,
como la experiencia del lector.
Antes de continuar con este capı́tulo, no estarı́a de más que el lector
revisara el Apéndice A, a excepción de que se esté ampliamente familiarizado
con el lenguaje de programación Java.
15
16 CAPÍTULO 2. PROGRAMACIÓN ORIENTADA A OBJETOS
2.1. Mensajes y métodos
Una de las principales inquietudes que expresan los estudiantes acerca
del paradigma orientado a objetos, está relacionada con los mensajes y los
métodos. En este sentido, se iniciará con un ejemplo sumamente sencillo, el
cual irá evolucionando progresivamente con la finalidad de ilustrar dichos
conceptos.
2.1.1. Métodos sin argumentos
El Ejemplo 2.1 muestra la definición de la clase Parvulo1, la cual no
contiene atributos, pero sı́ un método cuyo identificador o nombre es mensaje.
1 /∗ Ejemplo de envio de mensaje e invocacion de metodos ( Version 1.0) .
2 @autor Ricardo Ruiz Rodriguez
3 ∗/
4 public class Parvulo1 {
5 public void mensaje ( ) {
6 System . out . p r i n t l n ( ”Dentro del metodo mensaje ( ) ” ) ;
7 }
8 }
Ejemplo 2.1: Definición de la clase Parvulo1
El método mensaje tiene como única responsabilidad la impresión en la
salida estándar de una cadena1
.
En base a lo anterior, la clase Parvulo1 es una plantilla capaz de generar
objetos con una única responsabilidad o servicio, y no puede ser instanciada
ni ejecutada por sı́ misma. Para poder instanciar objetos de la clase Parvulo1
y poder visualizar su funcionamiento, se requiere de una clase de prueba
que permita generar una instancia de ella.
1 /∗ Clase de prueba para Parvulo1 . Se crea e l o b j e t o ” parvulo ” instanciado
2 de l a c l a s e Parvulo1 y se l e envia e l mensaje ”mensaje” .
3 @autor Ricardo Ruiz Rodriguez
4 ∗/
5 public class PruebaParvulo1{
6 public static void main ( String [ ] args ) {
7 Parvulo1 parvulo = new Parvulo1 () ;
8
9 parvulo . mensaje () ;
10 }
11 }
Ejemplo 2.2: Clase de prueba para la clase Parvulo1
1
Los detalles generales del funcionamiento de println son presentados en la Sección A.3.
2.1. MENSAJES Y MÉTODOS 17
Figura 2.1: Salida del Ejemplo 2.2
La clase de prueba para el Ejemplo 2.1 es la clase PruebaParvulo1 que se
presenta en el Ejemplo 2.2.
La clase PruebaParvulo1 tiene la estructura de la mayorı́a de las clases
de prueba que se utilizarán en el texto, y está basada en la definición del
método main.
En la lı́nea 7 se define el objeto parvulo cuya clase (tipo) es Parvulo1;
ası́ mismo, observe que se genera una instancia por medio de la cláusula new,
el cual, entre otras cosas, construye el objeto. Si la clase Parvulo1 tuviera
un constructor explı́cito, serı́a precisamente aquı́ en donde se invocarı́a. Más
adelante en esta misma sección, se profundizará un poco más al respecto.
Una vez que el objeto existe (ha sido instanciado), es posible interactuar
con él por medio de mensajes para solicitarle acciones que correspondan con
las responsabilidades o servicios definidos para dicho objeto que, para el caso
del objeto parvulo, es sólo una.
La solicitud del único servicio que puede proporcionar el objeto parvulo se
realiza a través del mensaje mensaje, el cual es enviado (invocado) al objeto
en la lı́nea 9:
parvulo.mensaje();
La expresión anterior se interpreta como: “se envı́a el mensaje mensaje al
objeto parvulo”. El envı́o de mensajes no es otra cosa más que la invocación
explı́cita de un método a través de su identificador, es utilizar el método
correspondiente para realizar una acción, misma que está relacionada con el
comportamiento o las responsabilidades del objeto en cuestión.
La salida del Ejemplo 2.2 se muestra en la Figura 2.1. Asegúrese de com-
prender lo hasta aquı́ descrito antes de continuar.
2.1.2. Métodos con argumentos
En esta sección se presenta una versión ligeramente distinta del Ejemplo
2.1, en el cual se presentó el envı́o de mensajes sin argumentos. Tómese el
tiempo necesario para comparar el Ejemplo 2.3 de esta sección con el Ejemplo
2.1, y compruebe que son esencialmente iguales.
El argumento nombre en el método mensaje constituye la diferencia de los
18 CAPÍTULO 2. PROGRAMACIÓN ORIENTADA A OBJETOS
ejemplos anteriormente mencionados. En el Ejemplo 2.3 el método mensaje
(lı́nea 5) define ahora la capacidad de recibir el argumento nombre, el cual
se define como un objeto de la clase String. El método mensaje imprime en
la salida estándar un cadena conformada por un texto predefinido (lı́nea 6)
y la cadena referida por nombre.
1 /∗ Ejemplo de envio de mensaje e invocacion de metodos ( Version 1.1) .
2 @autor Ricardo Ruiz Rodriguez
3 ∗/
4 public class Parvulo2 {
5 public void mensaje ( String nombre ) {
6 System . out . p r i n t l n ( ”Mi nombre es ” + nombre ) ;
7 }
8 }
Ejemplo 2.3: Definición de la clase Parvulo2
Por otro lado, el Ejemplo 2.4 muestra la clase de prueba para el Ejemplo
2.3, la cual es también similar a la del Ejemplo 2.2 excepto en la forma en
que se envı́a el mensaje al objeto parvulo (lı́nea 10 del Ejemplo 2.4). Observe
que el mensaje enviado tiene ahora una cadena como argumento, la cual es
referida por el objeto nombre del método mensaje (lı́nea 5 del Ejemplo 2.3)
en el momento en que se le envı́a el mensaje mensaje al objeto parvulo.
1 /∗ Clase de prueba para Parvulo2 . Se crea e l o b j e t o ” parvulo ”
2 instanciado de l a c l a s e Parvulo2 y se l e envia e l mensaje
3 ”mensaje” con un argumento .
4 @autor Ricardo Ruiz Rodriguez
5 ∗/
6 public class PruebaParvulo2{
7 public static void main ( String [ ] args ) {
8 Parvulo2 parvulo = new Parvulo2 () ;
9
10 parvulo . mensaje ( ” Ricardo ” ) ;
11 }
12 }
Ejemplo 2.4: Clase de prueba para la clase Parvulo2
Asegúrese de realizar una labor analı́tica al comparar lı́nea a lı́nea, tanto
las clases Parvulo1 y Parvulo2, como las clases PruebaParvulo1 y Prueba-
Parvulo2, ası́ como de comprender sus diferencias en base a lo que se ha
descrito hasta ahora.
La salida del Ejemplo 2.4 se muestra en la Figura 2.2.
2.1. MENSAJES Y MÉTODOS 19
Figura 2.2: Salida del Ejemplo 2.4
2.1.3. Métodos y atributos
Por el principio de ocultación de información, es conveniente que única-
mente se tenga acceso a los atributos de una clase a través de su interfaz. La
interfaz de un objeto está representada por sus métodos públicos (public).
1 /∗ Ejemplo de envio de mensaje e invocacion de metodos ( Version 1.2) .
2 Se introducen l o s metodos s e t y get para a t r i b u t o s de c l a s e .
3 @autor Ricardo Ruiz Rodriguez
4 ∗/
5 public class Parvulo3 {
6 private String nombre ;
7
8 public void estableceNombre ( String n) {
9 nombre = n ;
10 }
11
12 public String obtenNombre () {
13 return nombre ;
14 }
15
16 public void mensaje ( ) {
17 System . out . p r i n t l n ( ”Mi nombre es ” + obtenNombre () ) ;
18 }
19 }
Ejemplo 2.5: Definición de la clase Parvulo3
El Ejemplo 2.5 hace uso de dicho principio al definir, con un acceso restrin-
gido o privado (private), el atributo nombre (lı́nea 6) para la clase Parvulo3.
Observe que dicha clase define también tres métodos públicos, los cuales es-
tablecen la interfaz de los objetos que sean instanciados:
1. estableceNombre: este método es utilizado comúnmente para ajus-
tar o establecer el valor de un atributo, y en principio, deberı́a ha-
ber un método de este tipo por cada atributo que contenga la clase y
que se requiera manipular desde el exterior. Este tipo de métodos son
comúnmente referidos como métodos de tipo set.
2. obtenNombre: este método es utilizado comúnmente para recuperar
u obtener el valor de un atributo, y al igual que antes, deberı́a ha-
ber un método de este tipo por cada atributo que contenga la clase y
20 CAPÍTULO 2. PROGRAMACIÓN ORIENTADA A OBJETOS
que se requiera visualizar desde el exterior. Este tipo de métodos son
comúnmente referidos como métodos de tipo get.
3. mensaje: este tipo de métodos ha sido descrito con anterioridad. Note
que el método está definido como el del Ejemplo 2.1 (sin argumentos),
pero funciona como el del Ejemplo 2.3. Asegúrese de comprender ésto.
Observe que el método mensaje (lı́neas 16-18) se vale del método obten-
Nombre (lı́nea 17) para acceder al atributo nombre, pero no necesariamente
tiene que ser ası́, ya que un método puede acceder directamente a los atribu-
tos de la clase, siempre y cuando ambos estén definidos dentro de la misma
clase.
1 /∗ Clase de prueba para Parvulo3 . Se crea e l o b j e t o ” parvulo ” instanciado
2 de l a c l a s e Parvulo3 y se l e envian cuatro mensajes .
3 @autor Ricardo Ruiz Rodriguez
4 ∗/
5 public class PruebaParvulo3{
6 public static void main ( String [ ] args ) {
7 Parvulo3 parvulo = new Parvulo3 () ;
8
9 System . out . p r i n t l n ( ”Nombre del parvulo : ” + parvulo . obtenNombre () ) ;
10 parvulo . estableceNombre ( ” Ricardo ” ) ;
11 System . out . p r i n t l n ( ”Nombre del parvulo : ” + parvulo . obtenNombre () ) ;
12 parvulo . mensaje () ;
13 }
14 }
Ejemplo 2.6: Clase de prueba para la clase Parvulo3
Los métodos de tipo set sólo deben trabajar sobre un atributo, por lo
que habitualmente sólo reciben un argumento, mismo que corresponde con
la clase (tipo) del atributo a modificar2
.
De manera análoga, los métodos de tipo get no reciben ningún tipo de
argumentos, y la clase de objetos que regresan, está directamente relacionada
con la clase del atributo al que accederán 3
.
Es importante hacer notar también que la clase Parvulo4, a diferencia
de las anteriores, establece ya una caracterı́stica representada y definida por
el atributo nombre, de tal forma que los objetos derivados de ella (párvu-
los4
), compartirán dicha caracterı́stica, aunque cada uno poseerá su propia
identidad (nombre).
2
String para el caso del Ejemplo 2.5.
3
Ídem.
4
Un párvulo es un niño pequeño en edad preescolar.
2.1. MENSAJES Y MÉTODOS 21
Figura 2.3: Salida del Ejemplo 2.6
El Ejemplo 2.6 muestra la clase de prueba para la clase Parvulo3. Al igual
que en los ejemplos anteriores para las clases de prueba, observe que en la
lı́nea 7 se define y crea el objeto parvulo.
Las lı́neas 9 y 11 hacen uso del método obtenNombre a través del envı́o
del mensaje correspondiente, mientras que la lı́nea 10 envı́a el mensaje esta-
bleceNombre con un argumento especı́fico. Finalmente, la lı́nea 12 muestra el
envı́o del mensaje mensaje, el cual deberı́a resultarle ya familiar al lector.
La salida del Ejemplo 2.6 se muestra en la Figura 2.3. Observe que ini-
cialmente el atributo nombre del objeto parvulo no está definido, de ahı́ que
se imprima null en la salida estándar, el cual es el valor por omisión en Java
para las referencias a objetos que no han sido instanciadas, es decir, cuando
los objetos todavı́a no existen, y por consiguiente, no han sido inicializados.
2.1.4. Métodos y constructores
Un constructor es un método especial que se invoca implı́citamente cuan-
do se crea el objeto por medio de la cláusula new.
La cláusula new genera la memoria necesaria para representar al objeto
correspondiente, y lo inicializa por medio de un constructor. En este sentido,
puede haber más de una forma de inicializar un objeto y, en consecuencia,
más de un constructor.
El identificador o nombre de los métodos constructores debe coincidir con
el identificador o nombre de la clase que los define, y como puede haber más
de un constructor cuyo identificador es el mismo, la forma de distinguirse
entre sı́, es a través del número y clase o tipo de los argumentos que definen,
constituyendo con ello una forma de polimorfismo comúnmente conocida co-
mo sobrecarga5
. En la creación del objeto, se invoca el constructor que
coincida con el número y tipo de argumentos proporcionados a la cláusula
new.
Las lı́neas 9-11 del Ejemplo 2.7 muestran la definición del constructor
5
La sobrecarga se trata con un poco más de detalle en la Sección 2.1.5.
22 CAPÍTULO 2. PROGRAMACIÓN ORIENTADA A OBJETOS
Parvulo4, observe cómo el nombre del constructor coincide exactamente con
el nombre de la clase. Dicho constructor define un único argumento n, el cual
es un objeto de la clase String.
La inicialización que hace el constructor Parvulo4 consiste únicamente
de la asignación del objeto n al atributo representado por el objeto nombre.
1 /∗ Ejemplo de envio de mensaje e invocacion de metodos ( Version 1.3) .
2 Se agrega un constructor , e l cual define e l estado i n i c i a l del
3 o b j e t o instanciado .
4 @autor Ricardo Ruiz Rodriguez
5 ∗/
6 public class Parvulo4 {
7 private String nombre ;
8
9 Parvulo4 ( String n) {
10 nombre = n ;
11 }
12
13 public void estableceNombre ( String n) {
14 nombre = n ;
15 }
16
17 public String obtenNombre () {
18 return nombre ;
19 }
20
21 public void mensaje ( ) {
22 System . out . p r i n t l n ( ”Mi nombre es ” + obtenNombre () ) ;
23 }
24 }
Ejemplo 2.7: Definición de la clase Parvulo4
Es importante mencionar que la labor de inicialización de un constructor
en particular puede ser un proceso mucho más elaborado que el descrito hasta
ahora, y estará en función directa de las responsabilidades de inicialización
con que se quiera dotar al constructor, e indudablemente también, de la
problemática en particular que se esté resolviendo por medio del objeto en
cuestión.
Los elementos restantes de la clase Parvulo4 han sido previamente abor-
dados en las secciones anteriores.
El Ejemplo 2.8 presenta la clase de prueba para el Ejemplo 2.7. Observe
que a diferencia de los ejemplos anteriores, en la lı́nea 8 se proporciona un
argumento al constructor Parvulo4, lo cual hace que desde la creación del
objeto parvulo, le sea definido un nombre.
Observe también cómo la secuencia de mensajes subsecuentes coincide con
las del Ejemplo 2.6, excepto que en la lı́nea 11 del Ejemplo 2.8, se envı́a el
2.1. MENSAJES Y MÉTODOS 23
Figura 2.4: Salida del Ejemplo 2.8
mensaje estableceNombre al objeto parvulo para ponerle el nombre completo
(con apellidos) al párvulo.
1 /∗ Clase de prueba para Parvulo4 . Se crea e l o b j e t o ” parvulo ” instanciado
2 de l a c l a s e Parvulo4 , se usa e l constructor definido , y se l e envian
3 cuatro mensajes .
4 @autor Ricardo Ruiz Rodriguez
5 ∗/
6 public class PruebaParvulo4{
7 public static void main ( String [ ] args ) {
8 Parvulo4 parvulo = new Parvulo4 ( ” Ricardo ” ) ;
9
10 System . out . p r i n t l n ( ”Nombre del parvulo : ” + parvulo . obtenNombre () ) ;
11 parvulo . estableceNombre ( ” Ricardo Ruiz Rodriguez ” ) ;
12 System . out . p r i n t l n ( ”Nombre del parvulo : ” + parvulo . obtenNombre () ) ;
13 parvulo . mensaje () ;
14 }
15 }
Ejemplo 2.8: Clase de prueba para la clase Parvulo4
Asegúrese de comprender antes de continuar, que la Figura 2.4 muestra
la salida correspondiente a la ejecución del Ejemplo 2.8.
2.1.5. Sobrecarga
La sobrecarga (overload) es un tipo de polimorfismo, que se caracteriza
por la capacidad de poder definir más de un método o constructor con el
mismo nombre (identificador), siendo distinguidos entre sı́ por el número y
la clase (tipo) de los argumentos que se definen.
El Ejemplo 2.9 muestra la sobrecarga de constructores. Note que las lı́neas
8-10 definen el mismo constructor que el del Ejemplo 2.7 excepto por el
nombre, y que se ha añadido o sobrecargado un nuevo constructor (lı́neas 12-
14), el cual recibe tres argumentos que representan el nombre (n), el primer
apellido (a1), y el segundo apellido (a2) de un párvulo.
La sobrecarga de constructores se da porque ambos constructores tiene el
mismo identificador (Parvulo5), pero tienen distinto número de parámetros.
No puede existir sobrecarga para constructores o métodos con el mismo
identificador, y el mismo número o clase (tipo) de parámetros, tiene que
24 CAPÍTULO 2. PROGRAMACIÓN ORIENTADA A OBJETOS
Figura 2.5: Salida del Ejemplo 2.10
haber algo que los distinga entre sı́, ya que en otro caso, habrı́a ambigüedad.
Los métodos restantes del Ejemplo 2.9 ya ha sido comentados con ante-
rioridad.
1 /∗ Ejemplo de envio de mensaje e invocacion de metodos ( Version 1.4) .
2 Se muestra l a sobrecarga de constructores .
3 @autor Ricardo Ruiz Rodriguez
4 ∗/
5 public class Parvulo5 {
6 private String nombre ;
7
8 Parvulo5 ( String n) {
9 nombre = n ;
10 }
11
12 Parvulo5 ( String n , String a1 , String a2 ) {
13 nombre = n + ” ” + a1 + ” ” + a2 ;
14 }
15
16 public void estableceNombre ( String n) {
17 nombre = n ;
18 }
19
20 public String obtenNombre () {
21 return nombre ;
22 }
23
24 public void mensaje ( ) {
25 System . out . p r i n t l n ( ”Mi nombre es ” + obtenNombre () ) ;
26 }
27 }
Ejemplo 2.9: Definición de la clase Parvulo5
La clase de prueba para el Ejemplo 2.9 se muestra en el Ejemplo 2.10,
y es también muy similar a las clases de prueba anteriormente explicadas.
Únicamente cabe resaltar la creación del objeto parvulo en la lı́nea 7, note
que ahora se le proporcionan tres argumentos al constructor, lo cual hace que
el constructor utilizado sea el definido en las lı́neas 12-14 del Ejemplo 2.9.
La salida del Ejemplo 2.10 aparece en la Figura 2.5. Compare dicha salida
con la de la Figura 2.4 y asegúrese de comprender la diferencia.
1 /∗ Clase de prueba para Parvulo5 . Se crea e l o b j e t o ” parvulo ” instanciado
2 de l a c l a s e Parvulo5 mostrando la sobrecarga de constructores .
2.2. HERENCIA 25
3 @autor Ricardo Ruiz Rodriguez
4 ∗/
5 public class PruebaParvulo5{
6 public static void main ( String [ ] args ) {
7 Parvulo5 parvulo = new Parvulo5 ( ” Ricardo ” , ”Ruiz” , ” Rodriguez ” ) ;
8
9 System . out . p r i n t l n ( ”Nombre del parvulo : ” + parvulo . obtenNombre () ) ;
10 parvulo . estableceNombre ( ” Ricardo ” ) ;
11 System . out . p r i n t l n ( ”Nombre del parvulo : ” + parvulo . obtenNombre () ) ;
12 parvulo . mensaje () ;
13 }
14 }
Ejemplo 2.10: Clase de prueba para la clase Parvulo5
2.2. Herencia
Todos los conceptos del paradigma orientado a objetos discutidos en el
Capı́tulo 1 son importantes, pero el concepto de herencia es uno de los más
importantes, ya que dicho mecanismo de abstracción permite la reutilización
de código de una manera sumamente conveniente, y habilita las capacidades
del polimorfismo a través de la sobre escritura de métodos.
2.2.1. Abstracción
La descripción del concepto de herencia estará basado en los Ejemplos
2.11 y 2.12, pero para poder describirlos, considero pertinente presentar pri-
mero en un diagrama, los detalles de la relación que se quiere ejemplificar
para elevar el nivel de abstracción, es decir, a la forma en que las personas
comprendemos y analizamos las cosas, para posteriormente profundizar con
más conocimiento de causa, en los detalles de la implementación del concepto
en un lenguaje de programación.
El diagrama de clases UML6
del que partirá el análisis se muestra en la
Figura 2.6.
Los detalles completos de la explicación de un diagrama de clases UML
quedan fuera de los alcances de este libro, y sólo se describirán los aspectos
más relevantes que ayuden al lector a visualizar de mejor manera la herencia,
en caso de que el lector no cuente con experiencia en UML.
6
Leguaje de Modelado Unificado (Unified Modeling Language).
26 CAPÍTULO 2. PROGRAMACIÓN ORIENTADA A OBJETOS
Figura 2.6: Diagrama de clases UML para la relación de herencia entre Cien-
tifico y Persona
Un diagrama de clases UML está compuesto, grosso modo, por clases y
las relaciones entre dichas clases. Por otro lado, cada clase es un recuadro
dividido en tres partes:
1. Identificador de la clase.
2. Listado de atributos con la especificación de su clase (tipo) y sus niveles
de acceso correspondientes.
3. Listado de métodos con la especificación de la clase (tipo) de sus ar-
gumentos y valor de retorno, ası́ como los niveles de acceso correspon-
dientes para los métodos.
Tanto para el caso de los atributos como para el de los métodos, los niveles
de acceso están representados por un signo de más para un acceso público
(+), y un signo de menos para un acceso privado (-).
En base a lo anterior, puede observarse de la Figura 2.6 que la clase
Persona, y por lo tanto las instancias que se deriven de ella, tendrán las
siguientes caracterı́sticas (atributos) comunes a una persona: un nombre, una
edad, y una nacionalidad7
. Observe también que se ha definido un conjunto
de operaciones, acciones, responsabilidades o comportamiento comunes a una
persona, definido por los métodos.
7
Podrı́an definirse mucho más caracterı́sticas, o caracterı́sticas diferentes a las descritas,
pero no es la intención del ejemplo representar las caracterı́sticas completas y comunes a
una persona, y lo mismo ocurre para el comportamiento o las responsabilidades represen-
tadas en los métodos.
2.2. HERENCIA 27
Caracterı́sticas más caracterı́sticas menos, acciones más, acciones menos,
es posible decir que una persona en promedio está en general representada
por la clase Persona.
Ahora bien, un cientı́fico es8
una persona, y por lo tanto comparte las
caracterı́sticas y las acciones inherentes a una persona, y es precisamente
esta relación de compartir, la que se refiere a la herencia, ya que se dice que
en la herencia, una clase hereda (comparte) los atributos (caracterı́sticas) y
métodos (acciones) a otra.
La herencia en UML se representa por medio de una flecha como la de la
Figura 2.6, y es importante señalar que el sentido de la flecha es muy impor-
tante, ya que tal y como aparece en la figura, indica que la clase Cientifico
hereda las caracterı́sticas y el comportamiento de la clase Persona (y no al
revés).
Note que la clase Cientifico define un atributo adicional (especialidad),
mismo que se añade a todos los atributos que implı́citamente ya tiene, los
cuales fueron heredados de la clase Persona. Observe también que se han de-
finido cuatro métodos para la clase Cientifico, los cuales tienen las siguientes
caracterı́sticas:
estableceEspecialidad : es un método set para el atributo especialidad
definido en la clase Cientifico.
obtenEspecialidad : es un método get para el atributo especialidad defi-
nido en la clase Cientifico.
mensaje : este método ya estaba definido en la clase Persona, pero al ser
redefinido en la clase Cientifico, se dice que sobre escribe (override) al
primero, lo cual significa que un objeto instanciado de la clase Cien-
tifico, responderá al mensaje mensaje con la definición de su propio
método, y no con la definición del método mensaje definido en la clase
Persona.
mensajeEspecial : este es un nuevo método particular y especı́fico a las
instancias derivadas de la clase Cientifico.
Es sumamente importante que el lector se asegure de comprender la
descripción hasta aquı́ realizada respecto a las clases Persona y Cientifi-
co, ası́ como de entender la relación existente entre ellas antes de continuar
8
Recuerde la idea de división en especializaciones (relación is-a) presentada en el
Capı́tulo 1.
28 CAPÍTULO 2. PROGRAMACIÓN ORIENTADA A OBJETOS
a la siguiente sección, en donde se abordarán los aspectos relacionados con
la implementación.
2.2.2. Implementación
El Ejemplo 2.11 muestra la implementación en Java de la clase Persona
mostrada en la Figura 2.6. Todos los detalles de la clase Persona del Ejemplo
2.11 ya han sido discutidos con anterioridad, por lo que es importante que
el lector los revise, analice, y compare, con los elementos del diagrama UML
descritos en la sección anterior, y que se asegure de comprender la relación
que existe entre ellos.
1 /∗ Ejemplo de herencia .
2 La c l a s e Persona sera l a c l a s e padre ( super c l a s e )
3 de l a c l a s e C i e n t i f i c o .
4 @autor Ricardo Ruiz Rodriguez
5 ∗/
6 public class Persona {
7 // Atributos de l a c l a s e
8 private String nombre ;
9 private int edad ;
10 private String nacionalidad ;
11
12 // Constructor de un argumento ( nombre )
13 Persona ( String n) {
14 nombre = n ;
15 }
16
17 // Constructor de dos argumentos ( nombre y edad )
18 Persona ( String n , int e ) {
19 nombre = n ;
20 edad = e ;
21 }
22
23 // Constructor de t r e s argumentos (nombre , edad y nacionalidad )
24 Persona ( String n , int e , String nac ) {
25 nombre = n ;
26 edad = e ;
27 nacionalidad = nac ;
28 }
29
30 // Metodo para e s t a b l e c e r ( s e t ) e l a t r i b u t o ”nombre”
31 public void estableceNombre ( String n) {
32 nombre = n ;
33 }
34
35 // Metodo para obtener ( get ) e l a t r i b u t o ”nombre”
36 public String obtenNombre () {
37 return nombre ;
38 }
39
40 // Metodo para e s t a b l e c e r ( s e t ) e l a t r i b u t o ”edad”
2.2. HERENCIA 29
41 public void estableceEdad ( int e ) {
42 edad = e ;
43 }
44
45 // Metodo para obtener ( get ) e l a t r i b u t o ”edad”
46 public int obtenEdad () {
47 return edad ;
48 }
49
50 // Metodo para e s t a b l e c e r ( s e t ) e l a t r i b u t o ” nacionalidad ”
51 public void estableceNacionalidad ( String n) {
52 nacionalidad = n ;
53 }
54
55 // Metodo para obtener ( get ) e l a t r i b u t o ” nacionalidad ”
56 public String obtenNacionalidad ( ) {
57 return nacionalidad ;
58 }
59
60 // Metodo para imprimir un mensaje en la s a l i d a estandar
61 public void mensaje ( ) {
62 System . out . p r i n t l n ( ”Puedo hablar , mi nombre es ” + obtenNombre () ) ;
63 }
64
65 // Metodo que simula l a accion de comer por parte de una persona
66 public void comer () {
67 System . out . p r i n t l n ( ”M
m
m
m
m
m uno de l o s p l a c e r e s de la vida . . . ” ) ;
68 }
69 }
Ejemplo 2.11: Definición de la clase Persona
Por otro lado, el Ejemplo 2.12 contiene la implementación de la clase
Cientifico mostrada en la Figura 2.6. Observe que la herencia es implemen-
tada en Java a través del uso de la cláusula extends (lı́nea 6), seguida de la
clase de la que se hereda (Persona) en la definición de la clase Cientifico.
Es importante que el lector note el uso de la cláusula super en los cons-
tructores (lı́neas 11 y 18). El uso en Java de dicha cláusula sólo puede hacerse
en el contexto de constructores, y sirve para delegarle al constructor corres-
pondiente de la clase padre, los detalles de inicialización del objeto en cuestión
que, para el caso de la clase Cientifico, corresponden a los constructores de
dos y tres argumentos de la clase Persona. Asegúrese de comprender ésto
antes de continuar.
Al igual que antes, se deja como ejercicio de análisis para el lector, tanto
los detalles restantes de implementación de la clase Cientifico, como el asegu-
rarse de comprender la relación del diagrama UML con el código del Ejemplo
2.12.
30 CAPÍTULO 2. PROGRAMACIÓN ORIENTADA A OBJETOS
En este punto, es importante también que el lector ponga especial aten-
ción en los métodos mensaje del Ejemplo 2.11 (lı́neas 61-63), y del Ejemplo
2.12 (lı́neas 33-35), ya que serán fundamentales para comprender la sobre es-
critura de métodos que se discute más adelante en la clase de prueba (Ejemplo
2.13).
1 /∗ Ejemplo de herencia .
2 La c l a s e C i e n t i f i c o hereda l a s c a r a c t e r i s t i c a s ( a t r i b u t o s )
3 y operaciones ( metodos ) de l a c l a s e Persona .
4 @autor Ricardo Ruiz Rodriguez
5 ∗/
6 public class C i e n t i f i c o extends Persona {
7 private String e s p e c i a l i d a d ;
8
9 // Constructor de t r e s argumentos (nombre , edad y e s p e c i a l i d a d )
10 C i e n t i f i c o ( String n , int e , String esp ) {
11 super (n , e ) ;
12 e s p e c i a l i d a d = esp ;
13 }
14
15 // Constructor de cuatro argumentos (nombre , edad ,
16 // nacionalidad y e s p e c i a l i d a d )
17 C i e n t i f i c o ( String n , int e , String nac , String esp ) {
18 super (n , e , nac ) ;
19 e s p e c i a l i d a d = esp ;
20 }
21
22 // Metodo para e s t a b l e c e r ( s e t ) e l a t r i b u t o ” e s p e c i a l i d a d ”
23 public void e s t a b l e c e E s p e c i a l i d a d ( String e ) {
24 e s p e c i a l i d a d = e ;
25 }
26
27 // Metodo para obtener ( get ) e l a t r i b u t o ” e s p e c i a l i d a d ”
28 public String obtenEspecialidad () {
29 return e s p e c i a l i d a d ;
30 }
31
32 // Metodo para imprimir un mensaje en la s a l i d a estandar
33 public void mensaje ( ) {
34 System . out . p r i n t l n ( ”Yo, ” + obtenNombre ( ) + ” , soy ” +
obtenEspecialidad () ) ;
35 }
36
37 // Metodo para imprimir un mensaje e s p e c i a l en l a s a l i d a estandar
38 public void mensajeEspecial () {
39 System . out . p r i n t l n ( ”La d i s t a n c i a del s o l a la t i e r r a es 149 600 000
kms” ) ;
40 }
41 }
Ejemplo 2.12: Definición de la clase Cientifico
La clase de prueba para la herencia se presenta en el Ejemplo 2.13 y
se describe a continuación. La lı́nea 10 define el objeto persona y genera
2.2. HERENCIA 31
Figura 2.7: Salida del Ejemplo 2.13
una instancia de la clase Persona con caracterı́sticas especı́ficas; note que
el constructor que está siendo utilizado es el definido en las lı́neas 24-28 del
Ejemplo 2.11.
Observe cómo en las lı́neas 13, 15, 19 y 21 del Ejemplo 2.13, se envı́an
mensajes especı́ficos al objeto persona para obtener su nombre, cambiarle el
nombre, volver a obtener su nombre, solicitarle comer y un mensaje respec-
tivamente; cuya salida se ve expresada en las primeras cuatro lı́neas de la
Figura 2.7.
Por otro lado, la lı́nea 26 define y crea el objeto cientifico como una
instancia de la clase Cientifico. Al igual que antes, note cómo el constructor
utilizado es el definido en las lı́neas 17-20 del Ejemplo 2.12.
A su vez, las lı́neas 28 y 30 del Ejemplo 2.13, realizan algo semejante
a lo que se hizo con el objeto persona, es decir, envı́an mensajes al objeto
cientifico para obtener y cambiar el nombre del cientı́fico respectivamente.
La lı́nea 32 por su parte, cambia la especialidad del cientı́fico a través de
un mensaje de tipo set.
Finalmente, las lı́neas 34, 36, 38 y 40, envı́an mensajes especı́ficos al
objeto cientifico para obtener su nombre y solicitarle comer, un mensaje
y un mensaje especial respectivamente. Note cómo para el mensaje mensaje,
las respuestas del objeto persona y el objeto cientifico difieren por completo,
debido a que aunque el mensaje es el mismo, el objeto que los recibe responde
de manera distinta a dicho mensaje; ésto último fue lo que en el Capı́tulo 1
se definió como polimorfismo9
.
La salida del Ejemplo 2.13 se muestra en la Figura 2.7.
9
El polimorfismo está expresado en el ejemplo en su forma de sobre escritura (override)
de métodos.
32 CAPÍTULO 2. PROGRAMACIÓN ORIENTADA A OBJETOS
1 /∗ Clase de prueba para l a herencia .
2 se l e envian mensajes . Posteriormente se crea e l o b j e t o ”persona”
3 instanciado de l a c l a s e C i e n t i f i c o y tambien se l e envian mensajes ,
4 note que algunos mensajes son heredados de l a super c l a s e .
5 @autor Ricardo Ruiz Rodriguez
6 ∗/
7 public class PruebaHerencia {
8 public static void main ( String [ ] args ) {
9 // Se crea e l o b j e t o ”persona” instanciado de l a c l a s e Persona
10 Persona persona = new Persona ( ” Ricardo ” , 38 , ”Mexicano” ) ;
11
12 // Se imprime e l nombre del o bjeto ”persona” a traves de un mensaje
13 System . out . p r i n t l n ( ”Nombre : ” + persona . obtenNombre () ) ;
14 // Se e s t a b l e c e un nuevo nombre para e l o b j e t o ”persona”
15 persona . estableceNombre ( ” Ricardo Ruiz Rodriguez ” ) ;
16 // Se s o l i c i t a nuevamente a l o b j e t o ”persona” imprimir su nombre
17 System . out . p r i n t l n ( ”Nombre : ” + persona . obtenNombre () ) ;
18 // Se l e envia a l o b j e t o ”persona” e l mensaje ”comer”
19 persona . comer ( ) ;
20 // Se l e envia a l o b j e t o ”persona” e l mensaje ”mensaje”
21 persona . mensaje ( ) ;
22
23 System . out . p r i n t l n ( ) ;
24
25 // Se crea e l o b j e t o ” c i e n t i f i c o ” instanciado de l a c l a s e C i e n t i f i c o
26 C i e n t i f i c o c i e n t i f i c o = new C i e n t i f i c o ( ” Carl Sagan” , 62 ,
” Estadounidense ” , ”Astronomo” ) ;
27 // Se imprime e l nombre del o b j e t o ” c i e n t i f i c o ” a traves de un mensaje
28 System . out . p r i n t l n ( ”Nombre : ” + c i e n t i f i c o . obtenNombre () ) ;
29 // Se e s t a b l e c e un nuevo nombre para e l o b j e t o ” c i e n t i f i c o ”
30 c i e n t i f i c o . estableceNombre ( ” Carl Edward Sagan” ) ;
31 // Se e s t a b l e c e una nueva e s p e c i a l i d a d para e l o b j e t o ” c i e n t i f i c o ”
32 c i e n t i f i c o . e s t a b l e c e E s p e c i a l i d a d ( ”Astronomo y A s t r o f i s i c o ” ) ;
33 // Se s o l i c i t a nuevamente a l o b j e t o ” c i e n t i f i c o ” imprimir su nombre
34 System . out . p r i n t l n ( ”Nombre : ” + c i e n t i f i c o . obtenNombre () ) ;
35 // Se l e envia a l o b j e t o ” c i e n t i f i c o ” e l mensaje ”comer”
36 c i e n t i f i c o . comer ( ) ;
37 // Se l e envia a l o b j e t o ” c i e n t i f i c o ” e l mensaje ”mensaje”
38 c i e n t i f i c o . mensaje ( ) ;
39 // Se l e envia a l o b j e t o ” c i e n t i f i c o ” e l mensaje ” mensajeEspecial ”
40 c i e n t i f i c o . mensajeEspecial ( ) ;
41 // persona . mensajeEspecial () ;
42 }
43 }
Ejemplo 2.13: Clase de prueba para la herencia
2.3. CONSIDERACIONES FINALES 33
2.3. Consideraciones finales
2.3.1. Respecto al envı́o de mensajes
La sintaxis general en Java para el envı́o de mensajes a un objeto es la
siguiente:
objeto.mensaje(lista de argumentos)
donde objeto es un objeto de una clase previamente definida, y mensaje es uno
de los métodos públicos definidos para dicha clase. La lista de argumentos es
una lista de argumentos separada por comas, en donde cada argumento puede
ser un objeto, o un tipo de dato primitivo.
2.3.2. Respecto a la sobrecarga de operadores
Algunos lenguajes de programación soportan un concepto relacionado con
sobrecarga de operadores. La idea general del concepto de sobrecarga se ha
planteado en la Sección 2.1.5. El lenguaje de programación Java no soporta
la sobrecarga de operadores, y por consiguiente, se ha omitido su descripción;
pero es importante que el lector conozca que el concepto de sobrecarga no es
exclusivo de los métodos o constructores, y mucho menos de un lenguaje de
programación en particular.
2.3.3. Respecto al paradigma
El establecimiento de niveles de acceso como private para los atributos
de una clase, y el uso de métodos de tipo set y get están directamente rela-
cionados con el principio de ocultación de información.
Ahora bien, es probable que el lector haya notado que en la descripción del
Ejemplo 2.13, en distintas ocasiones se hizo referencia a los objetos persona y
cientifico como si fueran en sı́ mismos personas o entidades existentes. Ésto
se hizo de manera deliberada, ya que como se comentó en el Capı́tulo 1,
el paradigma orientado a objetos eleva el nivel de abstracción, y hace que
se haga referencia a las entidades fundamentales del paradigma (objetos),
como elementos comunes de nuestro lenguaje natural, lo cual permite que los
problemas se puedan expresar de una manera más natural e intuitiva.
En éste sentido, al dotar a los objetos de una personalidad propia con
caracterı́sticas y responsabilidades, en lugar de pensar en términos de datos,
34 CAPÍTULO 2. PROGRAMACIÓN ORIENTADA A OBJETOS
variables, y funciones o procedimientos que operen sobre dichos datos, se
eleva el nivel de abstracción, facilitando ası́ el análisis y la comprensión, ya
que el problema y su solución pueden ser expresados y analizados en términos
del dominio del problema, y no en el del medio (lenguaje de programación) de
la solución. Ésta es la forma en la que las personas abstraemos y utilizamos
la información.
Es sumamente importante que el lector tenga presente, que en el paradig-
ma orientado a objetos, no se piensa en términos de datos, sino en términos
de entidades con caracterı́sticas y responsabilidades especı́ficas, por lo que,
cuando defina una clase, puede resultarle útil el plantearse al menos un par
de preguntas10
que le permitan determinar si los los objetos derivados de su
clase tienen o no sentido, además de una alta cohesión:
¿Los atributos representan caracterı́sticas o propiedades, o definen un
estado para los objetos que serán instanciados?
¿La clase representa en sus métodos servicios, comportamiento, accio-
nes o responsabilidades inherentes a los objetos que deriven de ella?
Con estas dos sencillas preguntas, además de validar y verificar su diseño
de clases, estará reforzando el concepto de encapsulamiento.
10
Las preguntas propuestas son sólo una guı́a y una sugerencia al lector, no pretenden
ser de ninguna manera una lista completa y absoluta.
2.4. EJERCICIOS 35
2.4. Ejercicios
1. En el Ejemplo 2.5 se hizo referencia a la invocación del mensaje ob-
tenNombre (lı́nea 17) dentro del método mensaje. Cambie el método
obtenNombre por el atributo nombre y compruebe lo descrito en el
texto.
2. Considere el Ejemplo 2.6. ¿Qué sucede si en lugar de acceder al atributo
nombre por medio del método obtenNombre (lı́neas 9 y 11) se intenta
acceder directamente al atributo a través del operador punto?.
Para probar lo anterior, cambie la expresión:
parvulo.obtenNombre()
por la expresión:
parvulo.nombre
recompile y analice lo que suceda.
3. Modifique el Ejemplo 2.6 para que genere más de un objeto de la clase
Parvulo3 del Ejemplo 2.5, de tal forma que tenga un conjunto de al
menos tres párvulos.
Para los objetos creados, definales una identidad a cada uno de los
párvulos instanciados por medio de la asignación de un nombre distinto
a cada uno de ellos, envı́eles mensajes, experimente y juegue con ellos,
recuerde que sus objetos son, al fin y al cabo, niñ@s pequeñ@s.
4. Para el Ejemplo 2.7, defina y añada un constructor sin argumentos, de
tal forma que la labor del constructor sea definir su propio nombre (el
nombre del lector) al atributo nombre.
Modifique en consecuencia la clase del Ejemplo 2.8 para que haga uso
del constructor recién definido, y compruebe su funcionamiento.
5. La Sección 2.1.5 abordó el tema de la sobrecarga, y ejemplificó el con-
cepto utilizando sobrecarga de constructores. La sobrecarga de métodos
es análoga a la de constructores.
36 CAPÍTULO 2. PROGRAMACIÓN ORIENTADA A OBJETOS
Modifique el Ejemplo 2.9 para que implemente la sobrecarga de méto-
dos de la siguiente manera:
a) Defina un nuevo método con la siguiente firma:
public void mensaje(String m)
b) La responsabilidad del nuevo método mensaje, será la de imprimir
en la salida estándar la leyenda “Mensaje recibido”, seguido de la
cadena m.
c) Realice una clase de prueba (puede basarse en la del Ejemplo
2.10) para comprobar el funcionamiento de todos los métodos,
especialmente, el método sobrecargado mensaje.
6. Considere el Ejemplo 2.9 y modifı́quelo para que, en lugar de uno,
defina tres atributos:
nombre (String).
apellido1 (String).
apellido2 (String).
En base a lo anterior:
a) Agregue el método set correspondiente para cada uno de los atri-
butos, en base a lo descrito en el texto.
b) Agregue el método get correspondiente para cada uno de los atri-
butos, también en base a lo descrito en el texto.
c) Agregue un constructor para que sea posible construir un objeto
(párvulo) utilizando únicamente el nombre, y el primer apellido.
d) Modifique el método mensaje para que, en caso de que alguno de
los atributos del objeto en cuestión sea null, dicho atributo sea
ignorado y en consecuencia, no se imprima en la salida estándar.
e) Construya una clase de prueba que demuestre tanto el funciona-
miento de todas las posibles opciones de construcción de objetos,
como el adecuado funcionamiento de los métodos set, get y men-
saje.
2.4. EJERCICIOS 37
7. El Ejemplo 2.13 tiene la lı́nea 41 comentada, por lo que el compilador
y la JVM la ignoran. Si la descomenta ¿qué piensa que sucederá?,
¿compilará?, ¿se ejecutará?, ¿imprimirá algo en la salida estándar?,
¿fallará la ejecución?.
Después de analizar el programa, responda dichas preguntas, y corro-
bore su respuesta con la experimentación.
8. Modifique el Ejemplo 2.11 para que contenga más atributos, es decir,
para que las caracterı́sticas de una persona estén más completas. No
olvide agregar métodos de tipo set y get por cada uno de los atributos
que añada.
Para los atributos, añada al menos los siguientes cambios:
Cambie el atributo nombre por una distribución más convencional:
nombre, primer apellido, y segundo apellido.
Agregue un atributo que represente la dirección o domicilio.
Agregue un atributo que represente el sexo, femenino o masculino,
según sea el caso.
Después de lo anterior:
a) Compruebe el adecuado funcionamiento de la clase Persona res-
pecto de las modificaciones recién hechas. Asegúrese de comprobar
que los métodos set y get trabajan de la manera esperada.
b) Compruebe que con los cambios realizados a la clase Persona, los
aspectos relacionados con la herencia de la clase Cientifico del
Ejemplo 2.12, siguen funcionando sin ningún tipo de problema.
c) Modifique la clase Cientifico de manera análoga, y compruebe
también que el mecanismo de la herencia permanece inalterado.
Para la clase Cientifico agregue dos atributos (y sus correspon-
dientes métodos de acceso):
1) Institución o lugar donde labora.
2) Grado de estudios.
d) Agregue nuevas acciones, comportamientos o responsabilidades a
las clases Persona y Cientifico, y asegúrese de probar su adecua-
do funcionamiento. No olvide experimentar con los conceptos de
sobrecarga y sobre escritura.
38 CAPÍTULO 2. PROGRAMACIÓN ORIENTADA A OBJETOS
9. Construya un ejemplo completamente diferente al visto en el texto,
donde ponga de relieve los conceptos de envı́o de mensajes, herencia,
polimorfismo, encapsulamiento y ocultación de información.
Para realizar lo anterior, puede apoyarse de la jerarquı́a de clases de la
Figura 1.2, o de alguna otra figura o idea que sea de su preferencia.
Capı́tulo 3
Estructuras de datos
Ask not what you can do to your data structures, but rather ask
what your data structures can do for you.
3.1. Panorama general
De manera general, es posible decir que una computadora es una máquina
que manipula y procesa datos.
Las estructuras de datos están relacionadas con el estudio de cómo es que
se organizan los datos dentro de una computadora, y de cómo se manipulan,
procesan y emplean dichos datos, para representar información que sea de
utilidad para las personas.
Existen muchos tipos de estructuras de datos, y para cada estructura de
datos, hay diferentes variaciones que las particularizan para un contexto de
uso especı́fico.
Un tratado amplio y completo de las estructuras de datos, queda fuera
de los alcances de este libro, por lo que sólo se mencionarán algunas de las
estructuras de datos más comunes y convencionales, ası́ como algunas de sus
variaciones.
A continuación se presenta una descripción muy general de las estructuras
de datos que se analizarán en los capı́tulos siguientes:
Pilas : son estructuras de datos ampliamente utilizadas y sumamente im-
portantes en compiladores y sistemas operativos por ejemplo. En una
pila, las inserciones y las eliminaciones se efectúan únicamente en un
extremo de la estructura de datos: su parte superior.
39
40 CAPÍTULO 3. ESTRUCTURAS DE DATOS
Colas de espera : este tipo de estructuras de datos representan en general
lı́neas de espera; las inserciones se efectúan en la parte posterior de la
misma, y las eliminaciones se hacen por la parte delantera.
Listas enlazadas : son colecciones de elementos de datos alineados en una
fila. En una lista enlazada, las inserciones y las eliminaciones se efectúan
en cualquier parte de la estructura de datos.
Árboles binarios : son estructuras de datos que facilitan la búsqueda, la
clasificación u ordenamiento de los datos a alta velocidad, la elimina-
ción de elementos duplicados, la representación de sistemas de archivos
y directorios, y las expresiones de compilación entre otras muchas apli-
caciones.
Cada una de estas estructuras de datos tienen muchas otras, y muy in-
teresantes aplicaciones, algunas de las cuales, se presentan y discuten en los
capı́tulos correspondientes a cada una de ellas.
3.2. Tipos de datos y referencias
Probablemente el lector esté familiarizado con el concepto de tipo de
dato, ya sea debido a que tenga experiencia previa con algún lenguaje de
programación, o simplemente porque ha revisado el material del Apéndice A
o del Capı́tulo 2. Entonces ¿podrı́a definir qué es un tipo de dato?.
Un tipo de dato es un método para interpretar un patrón de bits. En
éste sentido, una secuencia de bits determinada podrı́a ser interpretada de
una forma u otra, en función del tipo de dato.
En la mayorı́a de los lenguajes de programación, el programador especifi-
ca, mediante las declaraciones de variables u objetos, cómo es que el programa
va a interpretar el contenido de la memoria de la computadora.
Las declaraciones también le especifican al compilador exactamente, qué es
lo que representan los sı́mbolos de las operaciones que se utilizarán, ya que
aunque en apariencia es lo mismo, los mecanismos de implementación de una
operación aritmética tan aparentemente simple como la adición, difieren de
un tipo de dato a otro.
Por otro lado, para la mayorı́a de los lenguajes de programación, los
nombres de variables o identificadores asociados a los objetos, son en reali-
dad referencias, es decir, direcciones de memoria en las que se almacenan
fı́sicamente los objetos a los que hacen referencia.
3.3. TIPOS DE DATOS ABSTRACTOS (ADT) 41
El manejo de referencias o direcciones de memoria puede ser explı́cito,
como en el caso de los lenguajes C y C++ por ejemplo, donde el manejo
de referencias se realiza a través de apuntadores. En algunos otros lenguajes
como Java y C#, el manejo de referencias es implı́cito, es decir, se realiza a
través del nombre o identificador de los objetos.
Tanto el manejo de referencias explı́cito como el implı́cito, tienen sus
ventajas y desventajas, y las fortalezas de uno, son las debilidades del otro
y viceversa. No es la intención de esta sección ni la del libro extenderse en
dichos aspectos, ya que para los objetivos especı́ficos que se persiguen en
este texto, basta con saber que Java hace uso de referencias implı́citas, y que
el nombre los objetos son en realidad dichas referencias y no los objetos en
sı́ mismos. En la Sección 3.4.1 se detalla y ejemplifica el manejo de referencias
para los objetos.
3.3. Tipos de datos abstractos (ADT)
Desde el punto de vista de la programación, es importante que los pro-
gramadores puedan definir sus propias abstracciones de datos, de tal forma
que dichas abstracciones trabajen de manera parecida a las abstracciones o
a las primitivas de datos proporcionadas por el sistema subyacente.
Un tipo de dato abstracto o ADT (Abstract Data Type), es definido
por una especificación abstracta, es decir, permite especificar las propiedades
lógicas y funcionales de un tipo de dato.
Desde el punto de vista de los ADT, un tipo de dato es un conjunto de
valores y un grupo de operaciones definidas sobre dichos valores. El conjunto
de valores y el de las operaciones, forman una estructura matemática que
se implementa usando una estructura de datos particular de hardware o de
software.
El concepto de ADT está relacionado con la concepción matemática que
define al tipo de datos, por lo que, al definir un ADT como concepto ma-
temático, no interesa la eficiencia del espacio o del tiempo1
, sino las pro-
piedades y caracterı́sticas inherentes a él. La definición de un ADT no se
relaciona en lo absoluto con los detalles de la implementación; de hecho, tal
vez ni siquiera sea posible implementar un ADT particular en ningún tipo
de hardware o software2
.
1
Los cuales son aspectos relacionados con la implementación del ADT.
2
Piense por ejemplo en los números reales y en la propiedad de la densidad de los
Libro Fundamentos-de-la-programacion O.O-Ruiz-Rodriguez-Ricardo.pdf
Libro Fundamentos-de-la-programacion O.O-Ruiz-Rodriguez-Ricardo.pdf
Libro Fundamentos-de-la-programacion O.O-Ruiz-Rodriguez-Ricardo.pdf
Libro Fundamentos-de-la-programacion O.O-Ruiz-Rodriguez-Ricardo.pdf
Libro Fundamentos-de-la-programacion O.O-Ruiz-Rodriguez-Ricardo.pdf
Libro Fundamentos-de-la-programacion O.O-Ruiz-Rodriguez-Ricardo.pdf
Libro Fundamentos-de-la-programacion O.O-Ruiz-Rodriguez-Ricardo.pdf
Libro Fundamentos-de-la-programacion O.O-Ruiz-Rodriguez-Ricardo.pdf
Libro Fundamentos-de-la-programacion O.O-Ruiz-Rodriguez-Ricardo.pdf
Libro Fundamentos-de-la-programacion O.O-Ruiz-Rodriguez-Ricardo.pdf
Libro Fundamentos-de-la-programacion O.O-Ruiz-Rodriguez-Ricardo.pdf
Libro Fundamentos-de-la-programacion O.O-Ruiz-Rodriguez-Ricardo.pdf
Libro Fundamentos-de-la-programacion O.O-Ruiz-Rodriguez-Ricardo.pdf
Libro Fundamentos-de-la-programacion O.O-Ruiz-Rodriguez-Ricardo.pdf
Libro Fundamentos-de-la-programacion O.O-Ruiz-Rodriguez-Ricardo.pdf
Libro Fundamentos-de-la-programacion O.O-Ruiz-Rodriguez-Ricardo.pdf
Libro Fundamentos-de-la-programacion O.O-Ruiz-Rodriguez-Ricardo.pdf
Libro Fundamentos-de-la-programacion O.O-Ruiz-Rodriguez-Ricardo.pdf
Libro Fundamentos-de-la-programacion O.O-Ruiz-Rodriguez-Ricardo.pdf
Libro Fundamentos-de-la-programacion O.O-Ruiz-Rodriguez-Ricardo.pdf
Libro Fundamentos-de-la-programacion O.O-Ruiz-Rodriguez-Ricardo.pdf
Libro Fundamentos-de-la-programacion O.O-Ruiz-Rodriguez-Ricardo.pdf
Libro Fundamentos-de-la-programacion O.O-Ruiz-Rodriguez-Ricardo.pdf
Libro Fundamentos-de-la-programacion O.O-Ruiz-Rodriguez-Ricardo.pdf
Libro Fundamentos-de-la-programacion O.O-Ruiz-Rodriguez-Ricardo.pdf
Libro Fundamentos-de-la-programacion O.O-Ruiz-Rodriguez-Ricardo.pdf
Libro Fundamentos-de-la-programacion O.O-Ruiz-Rodriguez-Ricardo.pdf
Libro Fundamentos-de-la-programacion O.O-Ruiz-Rodriguez-Ricardo.pdf
Libro Fundamentos-de-la-programacion O.O-Ruiz-Rodriguez-Ricardo.pdf
Libro Fundamentos-de-la-programacion O.O-Ruiz-Rodriguez-Ricardo.pdf
Libro Fundamentos-de-la-programacion O.O-Ruiz-Rodriguez-Ricardo.pdf
Libro Fundamentos-de-la-programacion O.O-Ruiz-Rodriguez-Ricardo.pdf
Libro Fundamentos-de-la-programacion O.O-Ruiz-Rodriguez-Ricardo.pdf
Libro Fundamentos-de-la-programacion O.O-Ruiz-Rodriguez-Ricardo.pdf
Libro Fundamentos-de-la-programacion O.O-Ruiz-Rodriguez-Ricardo.pdf
Libro Fundamentos-de-la-programacion O.O-Ruiz-Rodriguez-Ricardo.pdf
Libro Fundamentos-de-la-programacion O.O-Ruiz-Rodriguez-Ricardo.pdf
Libro Fundamentos-de-la-programacion O.O-Ruiz-Rodriguez-Ricardo.pdf
Libro Fundamentos-de-la-programacion O.O-Ruiz-Rodriguez-Ricardo.pdf
Libro Fundamentos-de-la-programacion O.O-Ruiz-Rodriguez-Ricardo.pdf
Libro Fundamentos-de-la-programacion O.O-Ruiz-Rodriguez-Ricardo.pdf
Libro Fundamentos-de-la-programacion O.O-Ruiz-Rodriguez-Ricardo.pdf
Libro Fundamentos-de-la-programacion O.O-Ruiz-Rodriguez-Ricardo.pdf
Libro Fundamentos-de-la-programacion O.O-Ruiz-Rodriguez-Ricardo.pdf
Libro Fundamentos-de-la-programacion O.O-Ruiz-Rodriguez-Ricardo.pdf
Libro Fundamentos-de-la-programacion O.O-Ruiz-Rodriguez-Ricardo.pdf
Libro Fundamentos-de-la-programacion O.O-Ruiz-Rodriguez-Ricardo.pdf
Libro Fundamentos-de-la-programacion O.O-Ruiz-Rodriguez-Ricardo.pdf
Libro Fundamentos-de-la-programacion O.O-Ruiz-Rodriguez-Ricardo.pdf
Libro Fundamentos-de-la-programacion O.O-Ruiz-Rodriguez-Ricardo.pdf
Libro Fundamentos-de-la-programacion O.O-Ruiz-Rodriguez-Ricardo.pdf
Libro Fundamentos-de-la-programacion O.O-Ruiz-Rodriguez-Ricardo.pdf
Libro Fundamentos-de-la-programacion O.O-Ruiz-Rodriguez-Ricardo.pdf
Libro Fundamentos-de-la-programacion O.O-Ruiz-Rodriguez-Ricardo.pdf
Libro Fundamentos-de-la-programacion O.O-Ruiz-Rodriguez-Ricardo.pdf
Libro Fundamentos-de-la-programacion O.O-Ruiz-Rodriguez-Ricardo.pdf
Libro Fundamentos-de-la-programacion O.O-Ruiz-Rodriguez-Ricardo.pdf
Libro Fundamentos-de-la-programacion O.O-Ruiz-Rodriguez-Ricardo.pdf
Libro Fundamentos-de-la-programacion O.O-Ruiz-Rodriguez-Ricardo.pdf
Libro Fundamentos-de-la-programacion O.O-Ruiz-Rodriguez-Ricardo.pdf
Libro Fundamentos-de-la-programacion O.O-Ruiz-Rodriguez-Ricardo.pdf
Libro Fundamentos-de-la-programacion O.O-Ruiz-Rodriguez-Ricardo.pdf
Libro Fundamentos-de-la-programacion O.O-Ruiz-Rodriguez-Ricardo.pdf
Libro Fundamentos-de-la-programacion O.O-Ruiz-Rodriguez-Ricardo.pdf
Libro Fundamentos-de-la-programacion O.O-Ruiz-Rodriguez-Ricardo.pdf
Libro Fundamentos-de-la-programacion O.O-Ruiz-Rodriguez-Ricardo.pdf
Libro Fundamentos-de-la-programacion O.O-Ruiz-Rodriguez-Ricardo.pdf
Libro Fundamentos-de-la-programacion O.O-Ruiz-Rodriguez-Ricardo.pdf
Libro Fundamentos-de-la-programacion O.O-Ruiz-Rodriguez-Ricardo.pdf
Libro Fundamentos-de-la-programacion O.O-Ruiz-Rodriguez-Ricardo.pdf
Libro Fundamentos-de-la-programacion O.O-Ruiz-Rodriguez-Ricardo.pdf
Libro Fundamentos-de-la-programacion O.O-Ruiz-Rodriguez-Ricardo.pdf
Libro Fundamentos-de-la-programacion O.O-Ruiz-Rodriguez-Ricardo.pdf
Libro Fundamentos-de-la-programacion O.O-Ruiz-Rodriguez-Ricardo.pdf
Libro Fundamentos-de-la-programacion O.O-Ruiz-Rodriguez-Ricardo.pdf
Libro Fundamentos-de-la-programacion O.O-Ruiz-Rodriguez-Ricardo.pdf
Libro Fundamentos-de-la-programacion O.O-Ruiz-Rodriguez-Ricardo.pdf
Libro Fundamentos-de-la-programacion O.O-Ruiz-Rodriguez-Ricardo.pdf
Libro Fundamentos-de-la-programacion O.O-Ruiz-Rodriguez-Ricardo.pdf
Libro Fundamentos-de-la-programacion O.O-Ruiz-Rodriguez-Ricardo.pdf
Libro Fundamentos-de-la-programacion O.O-Ruiz-Rodriguez-Ricardo.pdf
Libro Fundamentos-de-la-programacion O.O-Ruiz-Rodriguez-Ricardo.pdf
Libro Fundamentos-de-la-programacion O.O-Ruiz-Rodriguez-Ricardo.pdf
Libro Fundamentos-de-la-programacion O.O-Ruiz-Rodriguez-Ricardo.pdf
Libro Fundamentos-de-la-programacion O.O-Ruiz-Rodriguez-Ricardo.pdf
Libro Fundamentos-de-la-programacion O.O-Ruiz-Rodriguez-Ricardo.pdf
Libro Fundamentos-de-la-programacion O.O-Ruiz-Rodriguez-Ricardo.pdf
Libro Fundamentos-de-la-programacion O.O-Ruiz-Rodriguez-Ricardo.pdf
Libro Fundamentos-de-la-programacion O.O-Ruiz-Rodriguez-Ricardo.pdf
Libro Fundamentos-de-la-programacion O.O-Ruiz-Rodriguez-Ricardo.pdf
Libro Fundamentos-de-la-programacion O.O-Ruiz-Rodriguez-Ricardo.pdf
Libro Fundamentos-de-la-programacion O.O-Ruiz-Rodriguez-Ricardo.pdf
Libro Fundamentos-de-la-programacion O.O-Ruiz-Rodriguez-Ricardo.pdf
Libro Fundamentos-de-la-programacion O.O-Ruiz-Rodriguez-Ricardo.pdf
Libro Fundamentos-de-la-programacion O.O-Ruiz-Rodriguez-Ricardo.pdf
Libro Fundamentos-de-la-programacion O.O-Ruiz-Rodriguez-Ricardo.pdf
Libro Fundamentos-de-la-programacion O.O-Ruiz-Rodriguez-Ricardo.pdf
Libro Fundamentos-de-la-programacion O.O-Ruiz-Rodriguez-Ricardo.pdf
Libro Fundamentos-de-la-programacion O.O-Ruiz-Rodriguez-Ricardo.pdf
Libro Fundamentos-de-la-programacion O.O-Ruiz-Rodriguez-Ricardo.pdf
Libro Fundamentos-de-la-programacion O.O-Ruiz-Rodriguez-Ricardo.pdf
Libro Fundamentos-de-la-programacion O.O-Ruiz-Rodriguez-Ricardo.pdf
Libro Fundamentos-de-la-programacion O.O-Ruiz-Rodriguez-Ricardo.pdf
Libro Fundamentos-de-la-programacion O.O-Ruiz-Rodriguez-Ricardo.pdf
Libro Fundamentos-de-la-programacion O.O-Ruiz-Rodriguez-Ricardo.pdf
Libro Fundamentos-de-la-programacion O.O-Ruiz-Rodriguez-Ricardo.pdf
Libro Fundamentos-de-la-programacion O.O-Ruiz-Rodriguez-Ricardo.pdf
Libro Fundamentos-de-la-programacion O.O-Ruiz-Rodriguez-Ricardo.pdf
Libro Fundamentos-de-la-programacion O.O-Ruiz-Rodriguez-Ricardo.pdf
Libro Fundamentos-de-la-programacion O.O-Ruiz-Rodriguez-Ricardo.pdf
Libro Fundamentos-de-la-programacion O.O-Ruiz-Rodriguez-Ricardo.pdf
Libro Fundamentos-de-la-programacion O.O-Ruiz-Rodriguez-Ricardo.pdf
Libro Fundamentos-de-la-programacion O.O-Ruiz-Rodriguez-Ricardo.pdf
Libro Fundamentos-de-la-programacion O.O-Ruiz-Rodriguez-Ricardo.pdf
Libro Fundamentos-de-la-programacion O.O-Ruiz-Rodriguez-Ricardo.pdf
Libro Fundamentos-de-la-programacion O.O-Ruiz-Rodriguez-Ricardo.pdf
Libro Fundamentos-de-la-programacion O.O-Ruiz-Rodriguez-Ricardo.pdf
Libro Fundamentos-de-la-programacion O.O-Ruiz-Rodriguez-Ricardo.pdf
Libro Fundamentos-de-la-programacion O.O-Ruiz-Rodriguez-Ricardo.pdf
Libro Fundamentos-de-la-programacion O.O-Ruiz-Rodriguez-Ricardo.pdf
Libro Fundamentos-de-la-programacion O.O-Ruiz-Rodriguez-Ricardo.pdf
Libro Fundamentos-de-la-programacion O.O-Ruiz-Rodriguez-Ricardo.pdf
Libro Fundamentos-de-la-programacion O.O-Ruiz-Rodriguez-Ricardo.pdf
Libro Fundamentos-de-la-programacion O.O-Ruiz-Rodriguez-Ricardo.pdf
Libro Fundamentos-de-la-programacion O.O-Ruiz-Rodriguez-Ricardo.pdf
Libro Fundamentos-de-la-programacion O.O-Ruiz-Rodriguez-Ricardo.pdf
Libro Fundamentos-de-la-programacion O.O-Ruiz-Rodriguez-Ricardo.pdf
Libro Fundamentos-de-la-programacion O.O-Ruiz-Rodriguez-Ricardo.pdf
Libro Fundamentos-de-la-programacion O.O-Ruiz-Rodriguez-Ricardo.pdf
Libro Fundamentos-de-la-programacion O.O-Ruiz-Rodriguez-Ricardo.pdf
Libro Fundamentos-de-la-programacion O.O-Ruiz-Rodriguez-Ricardo.pdf
Libro Fundamentos-de-la-programacion O.O-Ruiz-Rodriguez-Ricardo.pdf
Libro Fundamentos-de-la-programacion O.O-Ruiz-Rodriguez-Ricardo.pdf
Libro Fundamentos-de-la-programacion O.O-Ruiz-Rodriguez-Ricardo.pdf
Libro Fundamentos-de-la-programacion O.O-Ruiz-Rodriguez-Ricardo.pdf
Libro Fundamentos-de-la-programacion O.O-Ruiz-Rodriguez-Ricardo.pdf
Libro Fundamentos-de-la-programacion O.O-Ruiz-Rodriguez-Ricardo.pdf
Libro Fundamentos-de-la-programacion O.O-Ruiz-Rodriguez-Ricardo.pdf
Libro Fundamentos-de-la-programacion O.O-Ruiz-Rodriguez-Ricardo.pdf
Libro Fundamentos-de-la-programacion O.O-Ruiz-Rodriguez-Ricardo.pdf
Libro Fundamentos-de-la-programacion O.O-Ruiz-Rodriguez-Ricardo.pdf
Libro Fundamentos-de-la-programacion O.O-Ruiz-Rodriguez-Ricardo.pdf
Libro Fundamentos-de-la-programacion O.O-Ruiz-Rodriguez-Ricardo.pdf
Libro Fundamentos-de-la-programacion O.O-Ruiz-Rodriguez-Ricardo.pdf
Libro Fundamentos-de-la-programacion O.O-Ruiz-Rodriguez-Ricardo.pdf
Libro Fundamentos-de-la-programacion O.O-Ruiz-Rodriguez-Ricardo.pdf
Libro Fundamentos-de-la-programacion O.O-Ruiz-Rodriguez-Ricardo.pdf
Libro Fundamentos-de-la-programacion O.O-Ruiz-Rodriguez-Ricardo.pdf

Más contenido relacionado

Similar a Libro Fundamentos-de-la-programacion O.O-Ruiz-Rodriguez-Ricardo.pdf

Diseño de Experimentos Métodos y Aplicaciones.pdf
Diseño de Experimentos Métodos y Aplicaciones.pdfDiseño de Experimentos Métodos y Aplicaciones.pdf
Diseño de Experimentos Métodos y Aplicaciones.pdfJuvenalriv
 
TesisCSP.pdf
TesisCSP.pdfTesisCSP.pdf
TesisCSP.pdfctarquino
 
Desarrollo proyectos-informaticos-con-java
Desarrollo proyectos-informaticos-con-javaDesarrollo proyectos-informaticos-con-java
Desarrollo proyectos-informaticos-con-javaFreddy Quina
 
Libro javacontapa
Libro javacontapaLibro javacontapa
Libro javacontapaRobert Wolf
 
Libro javacontapa
Libro javacontapaLibro javacontapa
Libro javacontapaTabu Carlos
 
Desarrollo proyectos-informaticos-con-java
Desarrollo proyectos-informaticos-con-javaDesarrollo proyectos-informaticos-con-java
Desarrollo proyectos-informaticos-con-javaVictor Basurto Alonso
 
Algoritmos programacion-python
Algoritmos programacion-pythonAlgoritmos programacion-python
Algoritmos programacion-pythonLUIS COAQUIRA
 
Análisis numérico de impacto no lineal en sistemas multicomponentes, con ANSY...
Análisis numérico de impacto no lineal en sistemas multicomponentes, con ANSY...Análisis numérico de impacto no lineal en sistemas multicomponentes, con ANSY...
Análisis numérico de impacto no lineal en sistemas multicomponentes, con ANSY...Juan Báez Leva
 
Matlab adv esp
Matlab adv espMatlab adv esp
Matlab adv espLuis Maury
 
ApuntesC++.pdf
ApuntesC++.pdfApuntesC++.pdf
ApuntesC++.pdfbilgrado01
 
Bases de-datos
Bases de-datosBases de-datos
Bases de-datossabu47
 
Introducción a la programación en c
Introducción a la programación en cIntroducción a la programación en c
Introducción a la programación en cvictdiazm
 

Similar a Libro Fundamentos-de-la-programacion O.O-Ruiz-Rodriguez-Ricardo.pdf (20)

Diseño de Experimentos Métodos y Aplicaciones.pdf
Diseño de Experimentos Métodos y Aplicaciones.pdfDiseño de Experimentos Métodos y Aplicaciones.pdf
Diseño de Experimentos Métodos y Aplicaciones.pdf
 
TesisCSP.pdf
TesisCSP.pdfTesisCSP.pdf
TesisCSP.pdf
 
Desarrollo proyectos-informaticos-con-java
Desarrollo proyectos-informaticos-con-javaDesarrollo proyectos-informaticos-con-java
Desarrollo proyectos-informaticos-con-java
 
Libro javacontapa
Libro javacontapaLibro javacontapa
Libro javacontapa
 
Libro javacontapa
Libro javacontapaLibro javacontapa
Libro javacontapa
 
Desarrollo proyectos-informaticos-con-java
Desarrollo proyectos-informaticos-con-javaDesarrollo proyectos-informaticos-con-java
Desarrollo proyectos-informaticos-con-java
 
Algoritmos programacion-python
Algoritmos programacion-pythonAlgoritmos programacion-python
Algoritmos programacion-python
 
Análisis numérico de impacto no lineal en sistemas multicomponentes, con ANSY...
Análisis numérico de impacto no lineal en sistemas multicomponentes, con ANSY...Análisis numérico de impacto no lineal en sistemas multicomponentes, con ANSY...
Análisis numérico de impacto no lineal en sistemas multicomponentes, con ANSY...
 
Matlab adv esp
Matlab adv espMatlab adv esp
Matlab adv esp
 
TFM_MJVillanueva
TFM_MJVillanuevaTFM_MJVillanueva
TFM_MJVillanueva
 
ApuntesC++.pdf
ApuntesC++.pdfApuntesC++.pdf
ApuntesC++.pdf
 
Bases de-datos
Bases de-datosBases de-datos
Bases de-datos
 
Bases de-datos
Bases de-datosBases de-datos
Bases de-datos
 
Manual de c# 2
Manual de c# 2Manual de c# 2
Manual de c# 2
 
Introducción a la programación en C
Introducción a la programación en CIntroducción a la programación en C
Introducción a la programación en C
 
Introducción a la programación en c
Introducción a la programación en cIntroducción a la programación en c
Introducción a la programación en c
 
Perez calculo1
Perez calculo1Perez calculo1
Perez calculo1
 
Perez calculo1
Perez calculo1Perez calculo1
Perez calculo1
 
notas de calculo
notas de calculonotas de calculo
notas de calculo
 
Perez, calculo1
Perez, calculo1Perez, calculo1
Perez, calculo1
 

Último

LABORATORIO CALIFICADO 02 PESO VOLUMÉTRICO DE SUELOS COHESIVOS- MÉTODO DE LA ...
LABORATORIO CALIFICADO 02 PESO VOLUMÉTRICO DE SUELOS COHESIVOS- MÉTODO DE LA ...LABORATORIO CALIFICADO 02 PESO VOLUMÉTRICO DE SUELOS COHESIVOS- MÉTODO DE LA ...
LABORATORIO CALIFICADO 02 PESO VOLUMÉTRICO DE SUELOS COHESIVOS- MÉTODO DE LA ...PeraltaFrank
 
Estabilización de suelos (Física, Química y Mecánica)
Estabilización de suelos (Física, Química y Mecánica)Estabilización de suelos (Física, Química y Mecánica)
Estabilización de suelos (Física, Química y Mecánica)CristianSalas68
 
PRIMER Y SEGUNDO TEOREMA DE CASTIGLIANO.pdf
PRIMER Y SEGUNDO TEOREMA DE CASTIGLIANO.pdfPRIMER Y SEGUNDO TEOREMA DE CASTIGLIANO.pdf
PRIMER Y SEGUNDO TEOREMA DE CASTIGLIANO.pdfAuraGabriela2
 
Trabajo en altura de acuerdo a la normativa peruana
Trabajo en altura de acuerdo a la normativa peruanaTrabajo en altura de acuerdo a la normativa peruana
Trabajo en altura de acuerdo a la normativa peruana5extraviado
 
5.1 MATERIAL COMPLEMENTARIO Sesión 02.pptx
5.1 MATERIAL COMPLEMENTARIO Sesión 02.pptx5.1 MATERIAL COMPLEMENTARIO Sesión 02.pptx
5.1 MATERIAL COMPLEMENTARIO Sesión 02.pptxNayeliZarzosa1
 
Categorización de las industrias mas relevantes del ecuador.pdf
Categorización de las industrias mas relevantes del ecuador.pdfCategorización de las industrias mas relevantes del ecuador.pdf
Categorización de las industrias mas relevantes del ecuador.pdfAnthony Gualpa
 
Historia de la Arquitectura II, 1era actividad..pdf
Historia de la Arquitectura II, 1era actividad..pdfHistoria de la Arquitectura II, 1era actividad..pdf
Historia de la Arquitectura II, 1era actividad..pdfIsbelRodrguez
 
PPT - MODIFICACIONES PRESUPUESTARIAS - Anexo II VF.pdf
PPT - MODIFICACIONES PRESUPUESTARIAS - Anexo II VF.pdfPPT - MODIFICACIONES PRESUPUESTARIAS - Anexo II VF.pdf
PPT - MODIFICACIONES PRESUPUESTARIAS - Anexo II VF.pdfDarwinJPaulino
 
Sistema de gestión de turnos para negocios
Sistema de gestión de turnos para negociosSistema de gestión de turnos para negocios
Sistema de gestión de turnos para negociosfranchescamassielmor
 
01 COSTOS UNITARIOS Y PRESUPUESTO DE OBRA-EXPEDIENTE TECNICO DE OBRA.pptx
01 COSTOS UNITARIOS Y PRESUPUESTO DE OBRA-EXPEDIENTE TECNICO DE OBRA.pptx01 COSTOS UNITARIOS Y PRESUPUESTO DE OBRA-EXPEDIENTE TECNICO DE OBRA.pptx
01 COSTOS UNITARIOS Y PRESUPUESTO DE OBRA-EXPEDIENTE TECNICO DE OBRA.pptxluiscisnerosayala23
 
La Evolución Industrial en el Ecuador.pdf
La Evolución Industrial en el Ecuador.pdfLa Evolución Industrial en el Ecuador.pdf
La Evolución Industrial en el Ecuador.pdfAnthony Gualpa
 
Sanidad en alpacas, enfermedades infecciosas y parasitarias
Sanidad en alpacas, enfermedades infecciosas y parasitariasSanidad en alpacas, enfermedades infecciosas y parasitarias
Sanidad en alpacas, enfermedades infecciosas y parasitariasJilvertHuisaCenteno
 
Topografía 1 Nivelación y Carretera en la Ingenierías
Topografía 1 Nivelación y Carretera en la IngenieríasTopografía 1 Nivelación y Carretera en la Ingenierías
Topografía 1 Nivelación y Carretera en la IngenieríasSegundo Silva Maguiña
 
Revista estudiantil, trabajo final Materia ingeniería de Proyectos
Revista estudiantil, trabajo final Materia ingeniería de ProyectosRevista estudiantil, trabajo final Materia ingeniería de Proyectos
Revista estudiantil, trabajo final Materia ingeniería de ProyectosJeanCarlosLorenzo1
 
CFRD simplified sequence for Mazar Hydroelectric Project
CFRD simplified sequence for Mazar Hydroelectric ProjectCFRD simplified sequence for Mazar Hydroelectric Project
CFRD simplified sequence for Mazar Hydroelectric ProjectCarlos Delgado
 
I LINEAMIENTOS Y CRITERIOS DE INFRAESTRUCTURA DE RIEGO.pptx
I LINEAMIENTOS Y CRITERIOS DE INFRAESTRUCTURA DE RIEGO.pptxI LINEAMIENTOS Y CRITERIOS DE INFRAESTRUCTURA DE RIEGO.pptx
I LINEAMIENTOS Y CRITERIOS DE INFRAESTRUCTURA DE RIEGO.pptxPATRICIAKARIMESTELAL
 
Mano de obra.pdf Curso Costos SENA Colombia
Mano de obra.pdf Curso Costos SENA ColombiaMano de obra.pdf Curso Costos SENA Colombia
Mano de obra.pdf Curso Costos SENA ColombiaCulturaGeneral1
 
1. Cap. 4 Carga Axial (1).pdf237374335347
1. Cap. 4 Carga Axial (1).pdf2373743353471. Cap. 4 Carga Axial (1).pdf237374335347
1. Cap. 4 Carga Axial (1).pdf237374335347vd110501
 
4.3 Subestaciones eléctricas componentes principales .pptx
4.3 Subestaciones eléctricas componentes principales .pptx4.3 Subestaciones eléctricas componentes principales .pptx
4.3 Subestaciones eléctricas componentes principales .pptxEfrain Yungan
 
electricidad básica, ejemplos prácticos y ejercicios
electricidad básica, ejemplos prácticos y ejercicioselectricidad básica, ejemplos prácticos y ejercicios
electricidad básica, ejemplos prácticos y ejerciciosEfrain Yungan
 

Último (20)

LABORATORIO CALIFICADO 02 PESO VOLUMÉTRICO DE SUELOS COHESIVOS- MÉTODO DE LA ...
LABORATORIO CALIFICADO 02 PESO VOLUMÉTRICO DE SUELOS COHESIVOS- MÉTODO DE LA ...LABORATORIO CALIFICADO 02 PESO VOLUMÉTRICO DE SUELOS COHESIVOS- MÉTODO DE LA ...
LABORATORIO CALIFICADO 02 PESO VOLUMÉTRICO DE SUELOS COHESIVOS- MÉTODO DE LA ...
 
Estabilización de suelos (Física, Química y Mecánica)
Estabilización de suelos (Física, Química y Mecánica)Estabilización de suelos (Física, Química y Mecánica)
Estabilización de suelos (Física, Química y Mecánica)
 
PRIMER Y SEGUNDO TEOREMA DE CASTIGLIANO.pdf
PRIMER Y SEGUNDO TEOREMA DE CASTIGLIANO.pdfPRIMER Y SEGUNDO TEOREMA DE CASTIGLIANO.pdf
PRIMER Y SEGUNDO TEOREMA DE CASTIGLIANO.pdf
 
Trabajo en altura de acuerdo a la normativa peruana
Trabajo en altura de acuerdo a la normativa peruanaTrabajo en altura de acuerdo a la normativa peruana
Trabajo en altura de acuerdo a la normativa peruana
 
5.1 MATERIAL COMPLEMENTARIO Sesión 02.pptx
5.1 MATERIAL COMPLEMENTARIO Sesión 02.pptx5.1 MATERIAL COMPLEMENTARIO Sesión 02.pptx
5.1 MATERIAL COMPLEMENTARIO Sesión 02.pptx
 
Categorización de las industrias mas relevantes del ecuador.pdf
Categorización de las industrias mas relevantes del ecuador.pdfCategorización de las industrias mas relevantes del ecuador.pdf
Categorización de las industrias mas relevantes del ecuador.pdf
 
Historia de la Arquitectura II, 1era actividad..pdf
Historia de la Arquitectura II, 1era actividad..pdfHistoria de la Arquitectura II, 1era actividad..pdf
Historia de la Arquitectura II, 1era actividad..pdf
 
PPT - MODIFICACIONES PRESUPUESTARIAS - Anexo II VF.pdf
PPT - MODIFICACIONES PRESUPUESTARIAS - Anexo II VF.pdfPPT - MODIFICACIONES PRESUPUESTARIAS - Anexo II VF.pdf
PPT - MODIFICACIONES PRESUPUESTARIAS - Anexo II VF.pdf
 
Sistema de gestión de turnos para negocios
Sistema de gestión de turnos para negociosSistema de gestión de turnos para negocios
Sistema de gestión de turnos para negocios
 
01 COSTOS UNITARIOS Y PRESUPUESTO DE OBRA-EXPEDIENTE TECNICO DE OBRA.pptx
01 COSTOS UNITARIOS Y PRESUPUESTO DE OBRA-EXPEDIENTE TECNICO DE OBRA.pptx01 COSTOS UNITARIOS Y PRESUPUESTO DE OBRA-EXPEDIENTE TECNICO DE OBRA.pptx
01 COSTOS UNITARIOS Y PRESUPUESTO DE OBRA-EXPEDIENTE TECNICO DE OBRA.pptx
 
La Evolución Industrial en el Ecuador.pdf
La Evolución Industrial en el Ecuador.pdfLa Evolución Industrial en el Ecuador.pdf
La Evolución Industrial en el Ecuador.pdf
 
Sanidad en alpacas, enfermedades infecciosas y parasitarias
Sanidad en alpacas, enfermedades infecciosas y parasitariasSanidad en alpacas, enfermedades infecciosas y parasitarias
Sanidad en alpacas, enfermedades infecciosas y parasitarias
 
Topografía 1 Nivelación y Carretera en la Ingenierías
Topografía 1 Nivelación y Carretera en la IngenieríasTopografía 1 Nivelación y Carretera en la Ingenierías
Topografía 1 Nivelación y Carretera en la Ingenierías
 
Revista estudiantil, trabajo final Materia ingeniería de Proyectos
Revista estudiantil, trabajo final Materia ingeniería de ProyectosRevista estudiantil, trabajo final Materia ingeniería de Proyectos
Revista estudiantil, trabajo final Materia ingeniería de Proyectos
 
CFRD simplified sequence for Mazar Hydroelectric Project
CFRD simplified sequence for Mazar Hydroelectric ProjectCFRD simplified sequence for Mazar Hydroelectric Project
CFRD simplified sequence for Mazar Hydroelectric Project
 
I LINEAMIENTOS Y CRITERIOS DE INFRAESTRUCTURA DE RIEGO.pptx
I LINEAMIENTOS Y CRITERIOS DE INFRAESTRUCTURA DE RIEGO.pptxI LINEAMIENTOS Y CRITERIOS DE INFRAESTRUCTURA DE RIEGO.pptx
I LINEAMIENTOS Y CRITERIOS DE INFRAESTRUCTURA DE RIEGO.pptx
 
Mano de obra.pdf Curso Costos SENA Colombia
Mano de obra.pdf Curso Costos SENA ColombiaMano de obra.pdf Curso Costos SENA Colombia
Mano de obra.pdf Curso Costos SENA Colombia
 
1. Cap. 4 Carga Axial (1).pdf237374335347
1. Cap. 4 Carga Axial (1).pdf2373743353471. Cap. 4 Carga Axial (1).pdf237374335347
1. Cap. 4 Carga Axial (1).pdf237374335347
 
4.3 Subestaciones eléctricas componentes principales .pptx
4.3 Subestaciones eléctricas componentes principales .pptx4.3 Subestaciones eléctricas componentes principales .pptx
4.3 Subestaciones eléctricas componentes principales .pptx
 
electricidad básica, ejemplos prácticos y ejercicios
electricidad básica, ejemplos prácticos y ejercicioselectricidad básica, ejemplos prácticos y ejercicios
electricidad básica, ejemplos prácticos y ejercicios
 

Libro Fundamentos-de-la-programacion O.O-Ruiz-Rodriguez-Ricardo.pdf

  • 1.
  • 2. Fundamentos de la Programación Orientada a Objetos Una Aplicación a las Estructuras de Datos en JavaTM Ricardo Ruiz Rodrı́guez Universidad Tecnológica de la Mixteca Instituto de Computación
  • 3.
  • 5. Ruiz Rodríguez, Ricardo Fundamentos de la programación orientada a objetos: una aplicación a las estructuras de datos en Java - 1º ed. - El Cid Editor, 2014. pdf ISBN digital – pdf 978-1-4135-2433-8 Fecha de catalogación: 18/02/2014 © Ricardo Ruiz Rodríguez © El Cid Editor ISBN versión digital pdf: 978-1-4135-2433-8
  • 6. Índice general Índice de figuras ix Índice de ejemplos xiii Prefacio xvii 1. Orientación a Objetos 1 1.1. Orı́genes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1 1.2. Paradigma . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2 1.2.1. Una perspectiva diferente . . . . . . . . . . . . . . . . 4 1.2.2. Objetos . . . . . . . . . . . . . . . . . . . . . . . . . . 5 1.2.3. Objetos y clases . . . . . . . . . . . . . . . . . . . . . . 6 1.3. Orientación a objetos y modularidad . . . . . . . . . . . . . . 8 1.3.1. Cohesión y Acoplamiento . . . . . . . . . . . . . . . . 9 1.4. Caracterı́sticas fundamentales de la POO . . . . . . . . . . . . 9 1.5. Consideraciones finales . . . . . . . . . . . . . . . . . . . . . . 12 1.6. Ejercicios . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13 2. Programación Orientada a Objetos 15 2.1. Mensajes y métodos . . . . . . . . . . . . . . . . . . . . . . . 16 2.1.1. Métodos sin argumentos . . . . . . . . . . . . . . . . . 16 2.1.2. Métodos con argumentos . . . . . . . . . . . . . . . . . 17 2.1.3. Métodos y atributos . . . . . . . . . . . . . . . . . . . 19 2.1.4. Métodos y constructores . . . . . . . . . . . . . . . . . 21 2.1.5. Sobrecarga . . . . . . . . . . . . . . . . . . . . . . . . . 23 2.2. Herencia . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 25 2.2.1. Abstracción . . . . . . . . . . . . . . . . . . . . . . . . 25 2.2.2. Implementación . . . . . . . . . . . . . . . . . . . . . . 28 v
  • 7. ÍNDICE GENERAL 2.3. Consideraciones finales . . . . . . . . . . . . . . . . . . . . . . 33 2.3.1. Respecto al envı́o de mensajes . . . . . . . . . . . . . . 33 2.3.2. Respecto a la sobrecarga de operadores . . . . . . . . . 33 2.3.3. Respecto al paradigma . . . . . . . . . . . . . . . . . . 33 2.4. Ejercicios . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 35 3. Estructuras de datos 39 3.1. Panorama general . . . . . . . . . . . . . . . . . . . . . . . . . 39 3.2. Tipos de datos y referencias . . . . . . . . . . . . . . . . . . . 40 3.3. Tipos de datos abstractos (ADT) . . . . . . . . . . . . . . . . 41 3.3.1. Especificación del ADT Racional . . . . . . . . . . . . 43 3.3.2. Implementación del ADT Racional . . . . . . . . . . . 44 3.4. Abstracción de estructuras de datos . . . . . . . . . . . . . . . 47 3.4.1. Clases autorreferidas . . . . . . . . . . . . . . . . . . . 48 3.4.2. Implementación . . . . . . . . . . . . . . . . . . . . . . 50 3.5. Consideraciones finales . . . . . . . . . . . . . . . . . . . . . . 50 3.6. Ejercicios . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 52 4. Pilas 55 4.1. Definición . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 55 4.1.1. Operaciones primitivas . . . . . . . . . . . . . . . . . . 56 4.2. Implementación . . . . . . . . . . . . . . . . . . . . . . . . . . 57 4.2.1. Pila primitiva . . . . . . . . . . . . . . . . . . . . . . . 57 4.2.2. Pila genérica . . . . . . . . . . . . . . . . . . . . . . . 63 4.3. Aplicaciones . . . . . . . . . . . . . . . . . . . . . . . . . . . . 66 4.3.1. Análisis básico de expresiones . . . . . . . . . . . . . . 66 4.3.2. Notación interfija, postfija y prefija . . . . . . . . . . . 69 4.3.3. Evaluación de expresiones . . . . . . . . . . . . . . . . 71 4.4. Consideraciones finales . . . . . . . . . . . . . . . . . . . . . . 72 4.5. Ejercicios . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 74 5. Colas de espera 79 5.1. Definición . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 79 5.1.1. Operaciones primitivas . . . . . . . . . . . . . . . . . . 80 5.1.2. Representación . . . . . . . . . . . . . . . . . . . . . . 81 5.2. Implementación . . . . . . . . . . . . . . . . . . . . . . . . . . 82 5.3. Colas de prioridad . . . . . . . . . . . . . . . . . . . . . . . . 86 5.3.1. Cola de prioridad ascendente . . . . . . . . . . . . . . . 88 vi
  • 8. 6.3.1. Implementacion de una pila utilizando herencia . . . . 110 6.3.2. Implementacion de una pila utilizando composición . . 115 ÍNDICE GENERAL 5.3.2. Cola de prioridad descendente . . . . . . . . . . . . . . 94 5.4. Consideraciones finales . . . . . . . . . . . . . . . . . . . . . . 95 5.5. Ejercicios . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 97 6. Listas enlazadas 103 6.1. Definición . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 103 103 6.1.1. Operaciones primitivas . . . . . . . . . . . . . . . . . . 104 6.1.2. Representación . . . . . . . . . . . . . . . . . . . . . . 105 6.2. Implementación . . . . . . . . . . . . . . . . . . . . . . . . . . 106 6.3. Herencia vs. composición . . . . . . . . . . . . . . . . . . . . . 110 6.4. Listas circulares . . . . . . . . . . . . . . . . . . . . . . . . . . 117 6.4.1. El problema de Josephus . . . . . . . . . . . . . . . . . 119 6.5. Listas doblemente enlazadas . . . . . . . . . . . . . . . . . . . 119 6.5.1. Definición, primitivas y representación . . . . . . . . . 120 6.6. Consideraciones finales . . . . . . . . . . . . . . . . . . . . . . 122 6.7. Ejercicios . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 123 7. Árboles binarios 129 7.1. Definición . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 129 7.1.1. Representación y conceptos . . . . . . . . . . . . . . . 129 7.1.2. Operaciones primitivas . . . . . . . . . . . . . . . . . . 131 7.2. Árbol binario de búsqueda (ABB) . . . . . . . . . . . . . . . . 134 7.2.1. Operaciones primitivas . . . . . . . . . . . . . . . . . . 135 7.2.2. Representación . . . . . . . . . . . . . . . . . . . . . . 136 7.2.3. Implementación . . . . . . . . . . . . . . . . . . . . . . 137 7.2.4. Eliminación . . . . . . . . . . . . . . . . . . . . . . . . 145 7.3. Árboles binarios balanceados (AVL) . . . . . . . . . . . . . . . 147 7.3.1. Definición y conceptos . . . . . . . . . . . . . . . . . . 147 7.3.2. Rotación simple . . . . . . . . . . . . . . . . . . . . . . 148 7.3.3. Rotación doble . . . . . . . . . . . . . . . . . . . . . . 150 7.4. Consideraciones finales . . . . . . . . . . . . . . . . . . . . . . 153 7.5. Ejercicios . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 154 A. Java 159 A.1. Orı́genes y caracterı́sticas . . . . . . . . . . . . . . . . . . . . . 160 A.2. Estructura general de una clase . . . . . . . . . . . . . . . . . 160 vii
  • 9. ÍNDICE GENERAL A.3. Bienvenid@ a Java . . . . . . . . . . . . . . . . . . . . . . . . 162 A.4. Compilación . . . . . . . . . . . . . . . . . . . . . . . . . . . . 164 A.5. Ejemplos selectos . . . . . . . . . . . . . . . . . . . . . . . . . 165 A.5.1. Lectura de datos . . . . . . . . . . . . . . . . . . . . . 165 A.5.2. Estructuras de control . . . . . . . . . . . . . . . . . . 167 A.5.3. Arreglos . . . . . . . . . . . . . . . . . . . . . . . . . . 170 A.5.4. Argumentos en la lı́nea de comandos . . . . . . . . . . 171 A.5.5. Excepciones . . . . . . . . . . . . . . . . . . . . . . . . 172 A.5.6. Genéricos . . . . . . . . . . . . . . . . . . . . . . . . . 174 A.6. Ejercicios . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 176 Bibliografı́a 179 Índice Analı́tico 181 Agradecimientos 187 Acerca del Autor 189 viii
  • 10. Índice de figuras 1.1. Ilusión óptica del conejo-pato creada por Joseph Jastrow . . . 3 1.2. Jerarquı́a de clases . . . . . . . . . . . . . . . . . . . . . . . . 7 2.1. Salida del Ejemplo 2.2 . . . . . . . . . . . . . . . . . . . . . . 17 2.2. Salida del Ejemplo 2.4 . . . . . . . . . . . . . . . . . . . . . . 19 2.3. Salida del Ejemplo 2.6 . . . . . . . . . . . . . . . . . . . . . . 21 2.4. Salida del Ejemplo 2.8 . . . . . . . . . . . . . . . . . . . . . . 23 2.5. Salida del Ejemplo 2.10 . . . . . . . . . . . . . . . . . . . . . . 24 2.6. Diagrama de clases UML para la relación de herencia entre Cientifico y Persona . . . . . . . . . . . . . . . . . . . . . . . 26 2.7. Salida del Ejemplo 2.13 . . . . . . . . . . . . . . . . . . . . . . 31 3.1. Salida de una ejecución del Ejemplo 3.2 al intentar crear un número racional cuyo denominador sea cero . . . . . . . . . . 44 3.2. Salida de la ejecución del Ejemplo 3.2 . . . . . . . . . . . . . . 46 3.3. Representación de un objeto de la clase Nodo (Ejemplo 3.3) . 49 3.4. Secuencia de nodos generados por una clase autorreferida . . . 50 3.5. Representación de un objeto autorreferido . . . . . . . . . . . 54 4.1. Crecimiento y decrecimiento de una pila . . . . . . . . . . . . 56 4.2. Abstracción de una pila como una secuencia de nodos . . . . . 57 4.3. Inserción de elementos en la pila primitiva . . . . . . . . . . . 61 4.4. Eliminación de elementos de la pila primitiva . . . . . . . . . . 62 4.5. Diagrama de clases UML para la pila genérica . . . . . . . . . 73 5.1. Inserción y eliminación de elementos en una cola de espera . . 80 5.2. Abstracción de una cola de espera como una secuencia de nodos 81 5.3. Diagrama de clases UML para la cola de espera . . . . . . . . 81 5.4. Salida del Ejemplo 5.4 . . . . . . . . . . . . . . . . . . . . . . 87 ix
  • 11. ÍNDICE DE FIGURAS 5.5. Diagrama de clases en UML para una cola de prioridad ascen- dente con la redefinición del método elimina . . . . . . . . . . 88 5.6. Diagrama de clases en UML para una cola de prioridad ascen- dente con la redefinición del método inserta . . . . . . . . . . 89 5.7. Salida del Ejemplo 5.6 . . . . . . . . . . . . . . . . . . . . . . 93 5.8. Diagrama de clases en UML para una cola de prioridad ascen- dente con la redefinición del método elimina . . . . . . . . . . 94 5.9. Diagrama de clases en UML para una cola de prioridad ascen- dente con la redefinición del método inserta . . . . . . . . . . 95 5.10. Abstracción y representación de Round robin . . . . . . . . . . 98 5.11. Abstracción de una estructura de datos compuesta . . . . . . . 102 6.1. Abstraccion de una lista enlazada como una secuencia de nodos105 6.2. Diagrama de clases UML para la lista enlazada . . . . . . . . 106 6.3. Salida del Ejemplo 5.4 . . . . . . . . . . . . . . . . . . . . . . 111 6.4. Diagrama de clases UML para la implementación de una pila utilizando herencia y una lista lista enlazada . . . . . . . . . . 112 6.5. Salida del Ejemplo 6.4 . . . . . . . . . . . . . . . . . . . . . . 114 6.6. Diagrama de clases UML para la implementación de una pila utilizando composición y una lista lista enlazada . . . . . . . . 115 6.7. Abstraccion de una lista enlazada circular como una secuencia de nodos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 118 6.8. Abstracción de una lista doblemente enlazada . . . . . . . . . 121 6.9. Diagrama de clases UML para una lista doblemente enlazada . 121 6.10. Representación de Round robin por niveles de prioridad . . . . 128 7.1. Abstraccion de un árbol binario como una estructura de nodos 130 7.2. Diagrama de clases UML para un árbol binario de búsqueda . 137 7.3. Una posible salida para el Ejemplo 7.3 y el Ejemplo 7.5 . . . . 142 7.4. Diagrama de clases UML para un árbol binario de búsqueda con eliminación . . . . . . . . . . . . . . . . . . . . . . . . . . 147 7.5. Caso 1: Rotación derecha [Wirth] . . . . . . . . . . . . . . . . 149 7.6. Ejemplo de aplicación de la rotación sencilla . . . . . . . . . . 150 7.7. Caso 3: Rotación doble izquierda derecha (adaptada de [Wirth])151 7.8. Ejemplo de aplicación de la rotación doble . . . . . . . . . . . 152 7.9. Representación de un ABB . . . . . . . . . . . . . . . . . . . . 154 7.10. Eliminación en un árbol AVL (adaptada de [Wirth]) . . . . . . 158 x
  • 12. ÍNDICE DE FIGURAS A.1. Salida del Ejemplo A.2 . . . . . . . . . . . . . . . . . . . . . . 163 A.2. Salida del Ejemplo A.4 . . . . . . . . . . . . . . . . . . . . . . 163 A.3. Salida del Ejemplo A.6 . . . . . . . . . . . . . . . . . . . . . . 167 A.4. Salida del Ejemplo A.7 . . . . . . . . . . . . . . . . . . . . . . 169 A.5. Salida de los Ejemplos A.8, A.9 y A.10 . . . . . . . . . . . . . 170 A.6. Salida del Ejemplo A.11 . . . . . . . . . . . . . . . . . . . . . 171 A.7. Salida del Ejemplo A.12 sin argumentos . . . . . . . . . . . . 172 A.8. Salida del Ejemplo A.12 con argumentos . . . . . . . . . . . . 172 A.9. Relación UML de la jerarquı́a de la clases Exception en Java . 173 xi
  • 13.
  • 14. Índice de ejemplos 2.1. Definición de la clase Parvulo1 . . . . . . . . . . . . . . . . . . 16 2.2. Clase de prueba para la clase Parvulo1 . . . . . . . . . . . . . 16 2.3. Definición de la clase Parvulo2 . . . . . . . . . . . . . . . . . . 18 2.4. Clase de prueba para la clase Parvulo2 . . . . . . . . . . . . . 18 2.5. Definición de la clase Parvulo3 . . . . . . . . . . . . . . . . . . 19 2.6. Clase de prueba para la clase Parvulo3 . . . . . . . . . . . . . 20 2.7. Definición de la clase Parvulo4 . . . . . . . . . . . . . . . . . . 22 2.8. Clase de prueba para la clase Parvulo4 . . . . . . . . . . . . . 23 2.9. Definición de la clase Parvulo5 . . . . . . . . . . . . . . . . . . 24 2.10. Clase de prueba para la clase Parvulo5 . . . . . . . . . . . . . 24 2.11. Definición de la clase Persona . . . . . . . . . . . . . . . . . . 28 2.12. Definición de la clase Cientifico . . . . . . . . . . . . . . . . . 30 2.13. Clase de prueba para la herencia . . . . . . . . . . . . . . . . 32 3.1. Clase implementa la abstracción de un número racional . . . . 44 3.2. Clase de prueba para la clase Racional . . . . . . . . . . . . . 47 3.3. Clase autorreferida . . . . . . . . . . . . . . . . . . . . . . . . 49 4.1. Definición de la clase NodoPrimitivo . . . . . . . . . . . . . . 57 4.2. Definición de la clase PilaPrimitiva . . . . . . . . . . . . . . . 58 4.3. Definición de la clase ExcepcionEDVacia que se utiliza para la implementación de todas las estructuras de datos . . . . . . . 60 4.4. Clase de prueba para la clase PilaPrimitiva . . . . . . . . . . . 61 4.5. Definición de la clase para un nodo genérico (NodoG) . . . . . 63 4.6. Definición de la clase Pila que permite almacenar objetos genéri- cos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 64 4.7. Clase de prueba para la pila genérica . . . . . . . . . . . . . . 65 5.1. Nodo genérico utilizado en la cola de espera . . . . . . . . . . 82 5.2. Excepción utilizada en la cola de espera . . . . . . . . . . . . 83 xiii
  • 15. ÍNDICE DE EJEMPLOS 5.3. Definición de la clase Cola que permite almacenar objetos genéricos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 84 5.4. Clase de prueba para la cola de espera . . . . . . . . . . . . . 86 5.5. Clase que define una cola de prioridad ascendente sobre escri- biendo el método inserta . . . . . . . . . . . . . . . . . . . . . 90 5.6. Clase de prueba para la cola de prioridad ascendente . . . . . 92 5.7. Clase que implementa la interfaz Comparable . . . . . . . . . . 99 6.1. Definición de la clase Lista que permite almacenar objetos genéricos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 107 6.2. Clase de prueba para la clase Lista . . . . . . . . . . . . . . . 109 6.3. Definición de la clase PilaH que implementa una pila de obje- tos genéricos utilizando herencia y una lista enlazada . . . . . 112 6.4. Clase de prueba para PilaH . . . . . . . . . . . . . . . . . . . 113 6.5. Definición de la clase PilaC que implementa una pila de obje- tos genéricos utilizando composición y una lista enlazada . . . 116 6.6. Clase de prueba para PilaC . . . . . . . . . . . . . . . . . . . 117 7.1. Definición de la clase NodoABB que permite representar ob- jetos (nodos) genéricos para un árbol binario de búsqueda . . 138 7.2. Definición de la clase ABBr que permite almacenar nodos (No- doABB) en un árbol binario de búsqueda . . . . . . . . . . . . 139 7.3. Clase de prueba para el árbol binario de búsqueda (recursivo) 141 7.4. Definición de la clase ABB que permite almacenar nodos (No- doABB) en un árbol binario de búsqueda . . . . . . . . . . . . 143 7.5. Clase de prueba para el árbol binario de búsqueda . . . . . . . 145 A.1. Estructura general de una clase en Java . . . . . . . . . . . . . 161 A.2. Primer programa en Java (versión 1.0) . . . . . . . . . . . . . 162 A.3. Primer programa en Java (versión 1.1) . . . . . . . . . . . . . 163 A.4. Primer programa en Java (versión 1.2) . . . . . . . . . . . . . 163 A.5. Primer programa en Java (versión 1.3) . . . . . . . . . . . . . 164 A.6. Lectura de datos desde la entrada estándar . . . . . . . . . . . 166 A.7. Uso de la estructura de selección if y de los operadores rela- cionales . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 168 A.8. Estructura de repetición while . . . . . . . . . . . . . . . . . 169 A.9. Estructura de repetición do-while . . . . . . . . . . . . . . . 170 A.10.Estructura de repetición for . . . . . . . . . . . . . . . . . . . 170 A.11.Arreglo de enteros (int) . . . . . . . . . . . . . . . . . . . . . 171 A.12.Procesamiento de argumentos en la lı́nea de comandos . . . . 172 A.13.Definición de una excepción . . . . . . . . . . . . . . . . . . . 174 xiv
  • 16. ÍNDICE DE EJEMPLOS A.14.Uso de una colección ArrayList . . . . . . . . . . . . . . . . . 177 xv
  • 17.
  • 18. Prefacio Estimado lector, este libro tiene una orientación especı́fica. Está pensado para un curso introductorio de programación orientada a objetos, en donde, de manera preferente aunque de ninguna manera obligatoria, se haya tenido un contacto previo con algún lenguaje de programación utilizando el enfo- que estructurado; sin embargo, también es mi intención que el libro sea de utilidad para aquellos lectores que se quieran iniciar en el mundo de la pro- gramación y el paradigma orientado a objetos, sin ningún requisito previo de programación. El libro asume que el lector posee conocimientos básicos de algoritmos y/o programación, ası́ como el funcionamiento de las estructuras de control secuencial, de selección, y de repetición. Por otro lado, si bien es cierto que para la comprensión del paradigma no es preciso dichos conocimientos (de hecho podrı́an generar un vicio para un paradigma de programación orien- tado a objetos más puro), sı́ lo son para la comprensión y el seguimiento correspondiente de los programas de ejemplo. Con todo, el libro proporciona un apéndice para apoyar al lector a través de ejemplos selectos, tanto en la introducción del lenguaje de programación utilizado, como en los conceptos fundamentales de la programación. Al respecto, existe un debate acerca de si es mejor enseñar el paradig- ma orientado a objetos sin antes tener un conocimiento de otro enfoque de programación (como el estructurado por ejemplo), o si es mejor partir de la programación estructurada para realizar una transición hacia la programa- ción orientada a objetos. En mi opinión ambos enfoques tienen sus ventajas y desventajas, y se podrı́a estar ante el sempiterno problema del huevo y la gallina. Java es un lenguaje de programación hı́brido, en el sentido de que no es un lenguaje totalmente orientado a objetos como Smalltalk, y en ese sentido, tiene estructuras de control y tipos de datos primitivos al estilo del lenguaje xvii
  • 19. PREFACIO de programación C, el cual es el lenguaje por antonomasia para la progra- macion estructurada y, dado que este libro utiliza a Java como lenguaje de programación, aquellos lectores que conozcan el lenguaje C se sentirán fami- liarizados rápidamente con Java, concentrándose entonces en la asimilación del paradigma y en su aplicación. Por otro lado, aquellos lectores que no conozcan el enfoque estructurado estarı́an, al menos de primera instancia, sin la predisposición a cometer uno de los vicios más comunes en la programación orientada a objetos, como lo es el de utilizar Java por ejemplo, para escribir programas siguiendo un enfoque estructurado. En éste sentido, resulta fundamental enfatizar desde ahora que el uso de un lenguaje de programación orientado a objetos, no hace per se, ni mucho menos garantiza, que los programas que se escriban en dicho lenguaje sigan el modelo de programación orientado a objetos. Como en muchas cosas, más que establecer qué es lo mejor y qué no lo es, ya que se está ante una disyuntiva subjetiva, finalmente el beneficio dependerá tanto de las intenciones del lector, como de su disposición hacia la comprensión del paradigma orientado a objetos, ası́ como de que se entienda, que la asimilación de un nuevo enfoque de programación no es excluyente de otros, sino que la diversidad de enfoques de solución o formas de resolver un problema, amplı́an el repertorio de conocimientos y capacidades intelectuales en pro de ser progresiva y eventualmente, mejores programadores. Para ilustrar y complementar de mejor manera tanto el diseño como los conceptos relacionados con los objetos, el libro se apoya de diagramas de clase UML para su correspondiente representación, por lo que serı́a también de mucha utilidad tener bases de UML, sin embargo, tampoco son indispen- sables. La intención de este libro es también la de introducir al lector en algunas de las estructuras de datos más convencionales, y al mismo tiempo, utilizarlas para ilustrar los conceptos del paradigma orientado a objetos a través de su implementación. En éste sentido, la estructura general del libro, es la que se describe a continuación: Capı́tulo 1 presenta los elementos fundamentales de la orientación a obje- tos. La intención del capı́tulo es la de proporcionar al lector un pano- rama general del paradigma orientado a objetos sin asociarlo necesa- riamente con la programación, y mucho menos con algún lenguaje de programación en particular. xviii
  • 20. Capı́tulo 2 describe las bases del paradigma orientado a objetos en el con- texto de su aplicación a la programación, utilizando a Java como len- guaje de programación. La intención del capı́tulo es la de concretizar en un lenguaje de progra- macion especı́fico, los conceptos más distintivos del paradigma orienta- do a objetos, para que en los capı́tulos siguientes, se puedan aplicar al desarrollo de las estructuras de datos, y mejorar ası́ tanto su compren- sión, como la experiencia del lector de manera progresiva. Capı́tulo 3 presenta un panorama general de las estructuras de datos, tipos de datos y referencias en Java. Se aborda también un concepto central tanto para el paradigma orientado a objetos, como para las estructuras de datos: los tipos de datos abstractos (ADT). Ası́ mismo, se sientan las bases para la implementación de estructuras de datos basadas en clases de autorreferencia. Capı́tulo 4 presenta la primera de las estructuras de datos estudiadas en el libro. El capı́tulo comienza con la definición de las propiedades y operaciones definidas para el ADT pila, para después presentar la im- plementación de una pila utilizando un tipo de dato primitivo. Poste- riormente, tomando como base dicha implementación, se generaliza el concepto para mostrar la implementación de una pila cuyos elementos son objetos genéricos. Finalmente, se refuerza la definición del ADT, y se muestra la relación que existe entre la implementación y el diseño con el correspondiente diagrama de clases en UML. Capı́tulo 5 introduce al lector en el estudio de las estructuras de datos de- nominadas colas de espera. Se realiza una presentación de la cola de espera ası́ como de su correspondiente implementación, para posterior- mente analizar una variante de dicha estructura de datos: las colas de prioridad. Ası́ mismo, el capı́tulo también presenta los elementos princi- pales para la implementación de objetos con caracterı́sticas de relación de orden a través de la interfaz Comparable del API de Java. Dicha caracterı́stica resultará fundamental para los capı́tulos posteriores. Capı́tulo 6 presenta al lector la última de las estructuras de datos linea- les estudiadas en el libro: las listas enlazadas. Ası́ mismo, toda vez que se asume completado el estudio de las pilas, el capı́tulo muestra la posibilidad de la implementación de dicha estructura de datos por xix
  • 21. PREFACIO medio de una lista enlazada. Adicionalmente, se comentan las ventajas y desventajas de los enfoques de implementación utilizados. Capı́tulo 7 introduce al lector tanto a los conceptos de árboles binarios, como al conocimiento de algunas de las estructuras de datos de árboles mas comunes: árboles binarios, árboles binarios de búsqueda (ABB), y árboles AVL. Los árboles binarios son estructuras de datos no lineales, y sus aplica- ciones y usos son tan diversos, que están únicamente limitados por la imaginación de quien los utiliza. El capı́tulo inicia presentando los con- ceptos relacionados con los árboles binarios en general, y con los ABB y AVL en particular. Presenta además dos tipos de implementación para un ABB: con recursividad y con ciclos, y se describen también los diferentes recorridos que es posible realizar con árboles binarios. Apéndice A presenta un compendio de referencia a la mano de Java para el lector familiarizado con algún lenguaje de programación. Al mismo tiempo, es un marco de referencia respecto a caracterı́sticas que no se tienen en un enfoque estructurado, como lo son las excepciones y los genéricos por ejemplo. El apéndice presenta además una selección de ejemplos de transición respecto a la forma de hacer las cosas en Java, sin entrar en detalles especı́ficos respecto a la definición y descripción de las estructuras de control, representación y notación de arreglos, etc. Insisto en que este libro tiene una naturaleza introductoria, pero no por ello informal. Confı́o plenamente en que puede servir como inicio de un largo camino en la asimilación progresiva de los conceptos asociados con el para- digma orientado a objetos. Espero sinceramente haber podido alcanzar la meta de transmitir los conceptos fundamentales de la orientación a objetos, ası́ como su aplicación en las estructuras de datos, utilizando al lenguaje de programación Java como medio. Ricardo Ruiz Rodrı́guez xx
  • 22. I consider to paradigms as universally recognized scientific achievements that, for a time, provide model problems and solutions for a community of researchers. Thomas Samuel Kuhn Programming is one of the most difficult branches of applied mathematics; the poorer mathematicians had better remain pure mathematicians. Edsger Wybe Dijkstra xxi
  • 23.
  • 24. Capı́tulo 1 Orientación a Objetos Technology is anything that wasn’t around when you were born. Alan Curtis Kay Hong Kong press conference 1.1. Orı́genes Las caracterı́sticas principales de lo que actualmente se denomina Pro- gramación Orientada a Objetos (POO) surgen en 1960, y aunque algunos autores difieren en sus orı́genes, los conceptos de la POO tienen su inicio en Simula 67, un lenguaje diseñado en el centro de cómputo noruego en Oslo1 . Posteriormente, en Agosto de 1981, se publica en la revista Byte la des- cripción del lenguaje de programación Smalltalk2 , el cual refinó algunos de los conceptos originados con el lenguaje Simula. Lo anterior dio pie a que en la década de 1980, los lenguajes de progra- mación Orientados a Objetos (OO) tuvieran un rápido auge y expansión, por lo que la POO se fue convirtiendo en el estilo de programación dominan- te a mediados de los años ochenta del siglo XX, continuando vigente hasta nuestros dı́as. La POO es una de las propuestas de solución para ayudar a resolver la denominada, aunque no generalmente aceptada, “crisis del software”. En este sentido, es importante decir que, si bien las técnicas OO facilitan la 1 Lenguaje para simulaciones creado por Ole-Johan Dahl y Kristen Nygaard. 2 Desarrollado en Xerox PARC (Palo Alto-California Research Center). 1
  • 25. 2 CAPÍTULO 1. ORIENTACIÓN A OBJETOS creación de complejos sistemas de software por medio de mejores mecanismos de abstracción, no son la panacea universal de solución. Programar una computadora sigue siendo una de las tareas más difı́ci- les jamás realizadas por un ser humano. Volverse experto en programación requiere, no sólo de saber manejar herramientas y conocer técnicas de pro- gramación, sino que es preciso contar también con: Talento. Creatividad. Inteligencia. Lógica. Habilidad para construir y utilizar abstracciones. Experiencia. Por lo anterior, hacer un uso efectivo de los principios OO requiere de una visión del mundo desde una perspectiva distinta, sobre todo si se parte de la base de resolución de problemas a través de un enfoque estructurado. Es importante señalar y tener presente desde este momento, que el uso de un lenguaje de POO no hace, por sı́ mismo, que se programe OO, ya que se podrı́a tener en el mejor de los casos, un programa o sistema implementado con un enfoque estructurado, pero programado en un lenguaje orientado a objetos. La POO requiere de la comprensión del paradigma orientado a objetos. La sección 1.2 discute el concepto de paradigma que se utilizará a lo largo del texto. 1.2. Paradigma El concepto de paradigma resulta fundamental en la comprensión del paradigma orientado a objetos. Antes de proporcionar la definición que se adoptará, describiré algunas definiciones de paradigma que encontré: paradigma m. Ejemplo o ejemplar: esa chica es el paradigma de la pacien- cia.
  • 26. 1.2. PARADIGMA 3 Figura 1.1: Ilusión óptica del conejo-pato creada por Joseph Jastrow paradigma ling. Cada uno de los esquemas formales a los que se ajustan las palabras, según sus respectivas flexiones: paradigma de la conjugación verbal. paradigma ling. Conjunto de elementos de una misma clase gramatical que pueden aparecer en un mismo contexto: paradigma de las preposiciones. paradigma ejemplo o modelo. En todo el ámbito cientı́fico, religioso u otro contexto epistemológico, el término paradigma puede indicar el concep- to de esquema formal de organización, y ser utilizado como sinónimo de marco teórico o conjunto de teorı́as. Pero entonces, ¿qué entender por paradigma de programación? La palabra paradigma irrumpió en el vocabulario moderno a través del influyente libro “The Structure of Scientific Revolutions”del historiador de la ciencia Thomas Samuel Kuhn[Kuhn]. Thomas Kuhn utilizó el término en la forma de la última definición: un paradigma es un modelo para describir un conjunto de teorı́as, estándares y métodos que en conjunto representan una forma de organizar el conocimiento, esto es, una forma de ver el mundo. En base a lo anterior se entederá como paradigma de programación al modelo de programación utilizado, el cual está descrito y definido por un conjunto de teorı́as, estándares y métodos que en conjunto, representan una propuesta de solución por software hacia una problemática determinada.
  • 27. 4 CAPÍTULO 1. ORIENTACIÓN A OBJETOS Kuhn utilizó la ilusión óptica de la Figura 1.1 para ilustrar el concepto de paradigma. En dicha figura puede verse un conejo o un pato, dependiendo de la perspectiva que se utilice. El paradigma orientado a objetos cambió la perspectiva respecto del en- foque estructurado, el cual era el paradigma dominante hasta entonces. 1.2.1. Una perspectiva diferente El concepto sobre el que subyace la esencia de la orientación a objetos es la abstracción. Por lo que, al pensar en este paradigma, deberá tener en mente una perspectiva basada en los siguientes conceptos: 1. Entidades: agentes u objetos en interacción, donde cada objeto tiene un rol. 2. Responsabilidades: cada objeto proporciona un conjunto de servicios o lleva a cabo acciones que son utilizadas por otras entidades u objetos. Las responsabilidades determinan el comportamiento del objeto. 3. Mensajes: en la POO la acción es iniciada por la transmisión de un mensaje a un objeto responsable de dicha acción. En respuesta al men- saje, el objeto receptor llevará a cabo un método para satisfacer la solicitud que le fue realizada por dicho mensaje. Los tres elementos anteriormente mencionados, constituyen los funda- mentos primordiales de la orientación a objetos. A lo largo del texto se desa- rrollarán de manera progresiva, y se ejemplificarán con programas. Mensajes, procedimientos/funciones y métodos Los mensajes son solicitudes especı́ficas de alguno de los servicios o res- ponsabilidades asignadas a un objeto. Los mensajes tienen un receptor es- pecı́fico, por lo que son enviados a un objeto en particular con una posible lista de argumentos determinada. Los mensajes son llevados a cabo por métodos, los cuales son algoritmos asociado a un objeto (o a una clase de objetos), cuya ejecución se desencadena tras la recepción de un mensaje. En este sentido, tanto los métodos como los procedimientos o funciones son un conjunto de pasos bien definidos que llevan a cabo una acción; sin embargo, los mensajes y los procedimientos o funciones se distinguen esencialmente por dos aspectos:
  • 28. 1.2. PARADIGMA 5 1. En un mensaje, hay un receptor designado para dicho mensaje. 2. La interpretación o método utilizado para responder al mensaje es de- terminado por el receptor, y puede variar en función del receptor. 1.2.2. Objetos Los objetos son esencialmente abstracciones. Son entidades que tienen un determinado estado, un comportamiento (determinado por sus responsabili- dades), y una identidad. El estado está representado por los datos o los valores que contienen los atributos del objeto, los cuales son a su vez, otros objetos o variables que representan las caracterı́sticas inherentes del objeto. El comportamiento está determinado por las responsabilidades o servicios del objeto, los cuales son definidos por los métodos, mismos que se solicitan a través de mensajes a los que sabe responder dicho objeto. La identidad es la propiedad que tiene un objeto que lo distingue de los demás. La identidad está representada por un identificador. Un objeto es una entidad que contiene en sı́ mismo, toda la información necesaria, misma que permite definirlo, identificarlo, y accederlo3 frente a otros objetos pertenecientes a otras clases, e incluso frente a objetos de su misma clase. Los objetos se valen de mecanismos de interacción llamados métodos, que favorecen la comunicación entre ellos. Dicha comunicación favorece a su vez el cambio de estado en los propios objetos. Esta caracterı́stica define a los objetos como unidades indivisibles, en las que no se separa el estado del comportamiento. Orientación a objetos vs. enfoque estructurado La orientación a objetos difiere del enfoque estructurado básicamente, en que en la programación estructurada los datos y los procedimientos están 3 La forma de acceder a un objeto es a través de su interfaz. La interfaz de un objeto es el conjunto de servicios públicos que ofrece el objeto, los cuales se solicitan a través de mensajes o solicitudes realizadas a dicho objeto.
  • 29. 6 CAPÍTULO 1. ORIENTACIÓN A OBJETOS separados y sin relación, ya que lo único que se busca en ésta última, es el procesamiento de los datos de entrada para obtener los datos de salida. La programación estructurada utiliza en primera instancia, un enfoque basado en procedimientos o funciones, y en segunda instancia, las estructuras de datos que dichos procedimientos o funciones manejan, cumpliendo ası́ la Ecuación 1.1 planteada por Niklaus Wirth. Algoritmos + Estructuras de Datos = Programas (1.1) Por otro lado, un programa en un enfoque OO solicita estructuras de datos (las cuales son otros objetos) para llevar a cabo un servicio. La perspectiva OO también define programas compuestos por algoritmos y estructuras de datos esencialmente (como los de la Ecuación 1.1), sin em- bargo lo hace desde un enfoque diferente. En la orientación a objetos la des- cripción del objeto se da en términos de responsabilidades y caracterı́sticas, y al analizar un problema en dichos términos, se eleva el nivel de abstracción. Lo anterior permite una mayor independencia entre los objetos, lo cual es un factor crı́tico en la solución de problemas complejos. Cabe mencionar por último, que al conjunto completo de responsabilidades asociadas con un objeto es comúnmente referido como protocolo. 1.2.3. Objetos y clases Todos los objetos son instancias de una clase (categorı́a). Esta relación de un objeto con una clase, hace que los objetos tengan las siguientes carac- terı́sticas: El método invocado por un objeto en respuesta a un mensaje, es de- terminado por la clase del objeto receptor. Todos los objetos de una clase determinada, utilizan el mismo método en respuesta a mensajes similares. Las clases pueden ser organizadas en una estructura jerárquica de he- rencia como la que se muestra en la Figura 1.2. Una clase hija o subclase heredará todas las caracterı́sticas de la clase de la que deriva (clase padre).
  • 30. 1.2. PARADIGMA 7 Figura 1.2: Jerarquı́a de clases Una clase abstracta es una clase de la que no se derivan instancias directamente, sino que es utilizada únicamente para crear subclases. La búsqueda del método a invocar en respuesta a un mensaje deter- minado, inicia en la clase del receptor. Si no se encuentra el método apropiado, la búsqueda se realiza en la clase padre, y ası́ sucesivamente hasta encontrar el método correspondiente. Si se encuentran métodos con el mismo nombre dentro de la jerarquı́a de clases, se dice que el método procesado sobre escribe (override) el comportamiento heredado. La Figura 1.2 presenta una posible jerarquı́a de clases para un Ser Vivo. Mas que una clasificación o taxonomı́a completa, la figura muestra el concepto de herencia a través de un árbol, el cual exhibe, que los elementos que se derivan, comparten caracterı́sticas (atributos) y comportamientos (métodos) semejantes. Ası́ por ejemplo, es posible decir que Flipper es una instancia particular de todos los posibles delfines que podrı́an existir. A su vez, un Delfı́n comparte
  • 31. 8 CAPÍTULO 1. ORIENTACIÓN A OBJETOS caracterı́sticas comunes con una Ballena en cuanto a que ambos son Cetáceos, pero difieren en otras4 . Un Delfı́n es un Cetáceo, y un Cetáceo es un Mamı́fero. En muchas oca- siones a éste tipo de relaciones se le denomina “es un”(is a), y es una carac- terı́stica útil para identificar herencia, pero no es la única. Existe otro tipo de relación y se denomina “tiene” (has-a). Estas relacio- nes son las dos formas más importantes de abstracción en la orientación a objetos: 1. La idea de división en partes (has-a): un automóvil tiene un motor, tiene una transmisión, tiene un sistema eléctrico, etc. 2. La idea de división en especializaciones (is-a): un automóvil es un medio de transporte, es un objeto de cuatro ruedas, es un objeto que se dirige con un volante, etc. Finalmente, la Figura 1.2 muestra que Flipper es un Delfı́n, que un Delfı́n es un Cetáceo, y que éste a su vez es un Mamı́fero; que un Mamı́fero per- tenece al Reino Animal, y que el Reino Animal es parte de los seres vivos representados por la super clase o clase base Ser Vivo. 1.3. Orientación a objetos y modularidad La modularidad no está exclusivamente relacionada con los procedimien- tos o funciones de la programación estructurada, sino con el grado en el que los componentes de un sistema pueden ser separados y reutilizados. En base a lo anterior, tanto los métodos como los objetos son en sı́ mismos módulos de una aplicación determinada, y en consecuencia, las clases de las que se derivan constituyen los módulos del sistema, por lo que de aquı́ en adelante se hará referencia a la modularidad de manera indistinta tanto para clases, como para los métodos de las clases. La modularidad ayuda también a hacer el código más comprensible, y ésto a su vez hace que en consecuencia el código sea más fácil de mantener. Sin embargo, sin las debidas consideraciones, la modularidad tiene también sus consecuencias negativas, las cuales están en función directa de dos conceptos 4 Si un delfı́n y una ballena coincidieran en todo (caracterı́sticas y comportamiento) serı́an de la misma clase.
  • 32. 1.4. CARACTERÍSTICAS FUNDAMENTALES DE LA POO 9 fundamentales en el desarrollo de software en general, y en el paradigma orientado a objetos en particular: 1. Cohesión. 2. Acoplamiento. 1.3.1. Cohesión y Acoplamiento La cohesión está relacionada con la integridad interna de un módulo. Es el grado o nivel de relación o integridad entre los elementos que componen un módulo. El nivel de cohesión determina, qué tan fuerte están relacionados cada unos de los elementos de funcionalidad expresados en el código fuente de un módulo. Por otro lado, el acoplamiento describe qué tan fuerte un módulo está re- lacionado con otros, es decir, es el grado en que un módulo depende de cada uno de los otros módulos que componen un sistema. El acoplamiento también puede ser referido o entendido como dependen- cia, lo cual ayuda a recordar que lo que se desea es mantener un bajo nivel de dependencia entre los módulos, es decir un bajo acoplamiento. En general, se desea que los módulos de un programa o sistema tengan, un alto nivel de cohesión y un bajo nivel de acoplamiento, y el paradigma orientado a objetos persigue y enfatiza dichos objetivos. 1.4. Caracterı́sticas fundamentales de la POO Por último, pero no por ello menos importante, es importante mencionar que Alan Curtis Kay, quien es considerado por muchos como el padre de la POO, definió un conjunto de caracterı́sticas fundamentales para el paradig- ma. En base a lo propuesto por Kay, en la Programación Orientada a Objetos: 1. Todo es un objeto. 2. El procesamiento es llevado a cabo por objetos:
  • 33. 10 CAPÍTULO 1. ORIENTACIÓN A OBJETOS Los objetos se comunican unos con otros solicitando que se lleven a cabo determinadas acciones. Los objetos se comunican enviando y recibiendo mensajes. Un mensaje es la solicitud de una acción, la cual incluye los argu- mentos que son necesarios para completar la tarea. 3. Cada objeto tiene su propia memoria, misma que está compuesta de otros objetos. 4. Cada objeto es una instancia de una clase. Una clase representa un grupo de objetos similares. 5. La clase es el repositorio del comportamiento asociado con un objeto. Todos los objetos que son instancias de la misma clase, llevan a cabo las mismas acciones. 6. Las clases están organizadas en una estructura jerárquica de árbol de- nominada jerarquı́a de herencia. La memoria y el comportamiento asociados con las instancias de una clase, están automáticamente disponibles para cualquier clase asociada con la descendencia dentro de la estructura jerárquica de árbol. Complementando la visión de Alan Kay, se presenta a continuación un compendio de conceptos que definen también y refuerzan, las caracterı́sticas principales de la POO: La abstracción denota las caracterı́sticas esenciales de un objeto. El proceso de abstracción permite seleccionar las caracterı́sticas rele- vantes dentro de un conjunto, e identificar comportamientos comunes para definir nuevos tipos de entidades. La abstracción es la consideración aislada de las cualidades esenciales de un objeto en su pura esencia o noción. La modularidad es la propiedad que permite subdividir una aplicación en partes más pequeñas (llamadas módulos), cada una de las cuales debe
  • 34. 1.4. CARACTERÍSTICAS FUNDAMENTALES DE LA POO 11 ser tan independiente como sea posible de la aplicación en sı́, y de las partes restantes. La modularidad es el grado en el que los componentes de un sistema pueden ser separados y reutilizados. El encapsulamiento tiene que ver con reunir todos los elementos que pue- den considerarse pertenecientes a una misma entidad, al mismo nivel de abstracción. Esto permite aumentar la cohesión de los módulos o componentes del sistema. El principio de ocultación de información (information hiding) se re- fiere a que cada objeto está aislado del exterior, es un módulo indepen- diente, y cada tipo de objeto presenta una interfaz a otros objetos, la cual especifica cómo es que pueden interactuar con él. El aislamiento protege a las propiedades de un objeto contra su mo- dificación por quien no tenga derecho a acceder a ellas; solamente los propios métodos internos del objeto pueden acceder a su estado. Ésto asegura que otros objetos no puedan cambiar el estado interno de un objeto de manera accidental o intencionada, eliminando efectos secun- darios e interacciones inesperadas. El polimorfismo está relacionado con el aspecto de que comportamientos diferentes asociados a objetos distintos, pueden compartir el mismo nombre. El polimorfismo es la capacidad que tienen los objetos de naturaleza heterogénea, de responder de manera diferente a un mismo mensaje, en función de las caracterı́sticas y responsabilidades del objeto que recibe dicho mensaje. La herencia organiza y facilita el polimorfismo y el encapsulamiento, per- mitiendo a los objetos ser definidos y creados como tipos especializados de objetos preexistentes. Las clases no están aisladas, sino que se relacionan entre sı́ formando una jerarquı́a de clasificación. Los objetos heredan las propiedades y el comportamiento de todas las clases a las que pertenecen. Ası́, los objetos pueden compartir y exten- der su comportamiento sin tener que volver a implementarlo.
  • 35. 12 CAPÍTULO 1. ORIENTACIÓN A OBJETOS Cuando un objeto hereda de más de una clase se dice que hay herencia múltiple. Es importante tener todos estos conceptos presentes, estudiarlos, anali- zarlos y comprenderlos, la memorización no es recomendable, ya que es bien sabido que el memorizar conceptos no implica su comprensión, pero si un concepto es comprendido, es posible explicarlo y deducir en consecuencia su definición. Mi deseo es que el lector reflexione sobre este aspecto y que, con un poco de paciencia, sume a su repertorio de conocimientos el conjunto de conceptos descritos hasta aquı́, los cuales se pondrán en práctica eventual y progresivamente, en los capı́tulos siguientes. 1.5. Consideraciones finales Este capı́tulo discutió los elementos fundamentales de la orientación a objetos. La intención del capı́tulo es la de proporcionar al lector un panorama general del paradigma orientado a objetos, sin asociarlo necesariamente con la programación, y mucho menos con algún lenguaje de programación en particular. Un lenguaje de programación es sólo un medio para el paradigma, no el paradigma en sı́. Por otro lado, el ejercicio de la programación es la forma de aplicar los conceptos asociados al paradigma. Los capı́tulos siguientes irán detallando al lector los conceptos presentados hasta ahora, pero desde la perspectiva de la programación y su aplicación en un lenguaje de programación. Sin embargo, es importante aclarar que el objetivo del libro no es enseñar un lenguaje de programación, sino el de utilizar al lenguaje como un medio para hacer tangibles los conceptos de orientación a objetos. El Apéndice A introduce algunos aspectos del lenguaje de programación Java que podrı́an ser de utilidad para el lector, pero de ninguna manera pretende cubrir los elementos completos de dicho lenguaje, sino solamente presentar un panorama general.
  • 36. 1.6. EJERCICIOS 13 1.6. Ejercicios 1. Investigue más acerca de la historia y desarrollo de la programación orientada a objetos. 2. Xerox es actualmente una compañı́a que desarrolla equipo de foto copia- do e impresión entre otras cosas. Investigue cuál era el sistema operativo que utilizaban, que por cierto, ya incluı́a una GUI (Interfaz Gráfica de Usuario), pionera de las GUI que actualmente se utilizan. 3. Investigue la historia y la ideologı́a del lenguaje de programación Small- talk. Aproveche para conocer el nombre de su(s) creador(es). 4. Investigue la historia y la ideologı́a del lenguaje de programación Eiffel. Aproveche para conocer el nombre de su(s) creador(es). 5. Investigue la historia del lenguaje de programación C++. Aproveche para conocer el nombre de su(s) creador(es). 6. Investigue el papel del Dr. Alan Curtis Kay en la concepción y desa- rrollo de la programación orientada a objetos. 7. Investigue qué otros paradigmas de programación existen. 8. Investigue qué lenguajes de programación actuales soportan el paradig- ma orientado a objetos, cuáles lo soportan de manera nativa y cuáles como una extensión.
  • 37. 14 CAPÍTULO 1. ORIENTACIÓN A OBJETOS
  • 38. Capı́tulo 2 Programación Orientada a Objetos Object-oriented programming is an exceptionally bad idea which could only have originated in California. Edsger Wybe Dijkstra (attributed to) I don’t know how many of you have ever met Dijkstra, but you probably know that arrogance in computer science is measured in nano-Dijkstras. Alan Curtis Kay Este capı́tulo presenta las bases del paradigma orientado a objetos en el contexto de su aplicación a la programación utilizando un lenguaje de programación. La intención principal del capı́tulo, es concretizar en un lenguaje de pro- gramación los conceptos más distintivos del paradigma orientado a objetos, para que en los capı́tulos subsecuentes, se puedan aplicar al desarrollo de las estructuras de datos, y mejorar ası́ tanto la comprensión de los conceptos, como la experiencia del lector. Antes de continuar con este capı́tulo, no estarı́a de más que el lector revisara el Apéndice A, a excepción de que se esté ampliamente familiarizado con el lenguaje de programación Java. 15
  • 39. 16 CAPÍTULO 2. PROGRAMACIÓN ORIENTADA A OBJETOS 2.1. Mensajes y métodos Una de las principales inquietudes que expresan los estudiantes acerca del paradigma orientado a objetos, está relacionada con los mensajes y los métodos. En este sentido, se iniciará con un ejemplo sumamente sencillo, el cual irá evolucionando progresivamente con la finalidad de ilustrar dichos conceptos. 2.1.1. Métodos sin argumentos El Ejemplo 2.1 muestra la definición de la clase Parvulo1, la cual no contiene atributos, pero sı́ un método cuyo identificador o nombre es mensaje. 1 /∗ Ejemplo de envio de mensaje e invocacion de metodos ( Version 1.0) . 2 @autor Ricardo Ruiz Rodriguez 3 ∗/ 4 public class Parvulo1 { 5 public void mensaje ( ) { 6 System . out . p r i n t l n ( ”Dentro del metodo mensaje ( ) ” ) ; 7 } 8 } Ejemplo 2.1: Definición de la clase Parvulo1 El método mensaje tiene como única responsabilidad la impresión en la salida estándar de una cadena1 . En base a lo anterior, la clase Parvulo1 es una plantilla capaz de generar objetos con una única responsabilidad o servicio, y no puede ser instanciada ni ejecutada por sı́ misma. Para poder instanciar objetos de la clase Parvulo1 y poder visualizar su funcionamiento, se requiere de una clase de prueba que permita generar una instancia de ella. 1 /∗ Clase de prueba para Parvulo1 . Se crea e l o b j e t o ” parvulo ” instanciado 2 de l a c l a s e Parvulo1 y se l e envia e l mensaje ”mensaje” . 3 @autor Ricardo Ruiz Rodriguez 4 ∗/ 5 public class PruebaParvulo1{ 6 public static void main ( String [ ] args ) { 7 Parvulo1 parvulo = new Parvulo1 () ; 8 9 parvulo . mensaje () ; 10 } 11 } Ejemplo 2.2: Clase de prueba para la clase Parvulo1 1 Los detalles generales del funcionamiento de println son presentados en la Sección A.3.
  • 40. 2.1. MENSAJES Y MÉTODOS 17 Figura 2.1: Salida del Ejemplo 2.2 La clase de prueba para el Ejemplo 2.1 es la clase PruebaParvulo1 que se presenta en el Ejemplo 2.2. La clase PruebaParvulo1 tiene la estructura de la mayorı́a de las clases de prueba que se utilizarán en el texto, y está basada en la definición del método main. En la lı́nea 7 se define el objeto parvulo cuya clase (tipo) es Parvulo1; ası́ mismo, observe que se genera una instancia por medio de la cláusula new, el cual, entre otras cosas, construye el objeto. Si la clase Parvulo1 tuviera un constructor explı́cito, serı́a precisamente aquı́ en donde se invocarı́a. Más adelante en esta misma sección, se profundizará un poco más al respecto. Una vez que el objeto existe (ha sido instanciado), es posible interactuar con él por medio de mensajes para solicitarle acciones que correspondan con las responsabilidades o servicios definidos para dicho objeto que, para el caso del objeto parvulo, es sólo una. La solicitud del único servicio que puede proporcionar el objeto parvulo se realiza a través del mensaje mensaje, el cual es enviado (invocado) al objeto en la lı́nea 9: parvulo.mensaje(); La expresión anterior se interpreta como: “se envı́a el mensaje mensaje al objeto parvulo”. El envı́o de mensajes no es otra cosa más que la invocación explı́cita de un método a través de su identificador, es utilizar el método correspondiente para realizar una acción, misma que está relacionada con el comportamiento o las responsabilidades del objeto en cuestión. La salida del Ejemplo 2.2 se muestra en la Figura 2.1. Asegúrese de com- prender lo hasta aquı́ descrito antes de continuar. 2.1.2. Métodos con argumentos En esta sección se presenta una versión ligeramente distinta del Ejemplo 2.1, en el cual se presentó el envı́o de mensajes sin argumentos. Tómese el tiempo necesario para comparar el Ejemplo 2.3 de esta sección con el Ejemplo 2.1, y compruebe que son esencialmente iguales. El argumento nombre en el método mensaje constituye la diferencia de los
  • 41. 18 CAPÍTULO 2. PROGRAMACIÓN ORIENTADA A OBJETOS ejemplos anteriormente mencionados. En el Ejemplo 2.3 el método mensaje (lı́nea 5) define ahora la capacidad de recibir el argumento nombre, el cual se define como un objeto de la clase String. El método mensaje imprime en la salida estándar un cadena conformada por un texto predefinido (lı́nea 6) y la cadena referida por nombre. 1 /∗ Ejemplo de envio de mensaje e invocacion de metodos ( Version 1.1) . 2 @autor Ricardo Ruiz Rodriguez 3 ∗/ 4 public class Parvulo2 { 5 public void mensaje ( String nombre ) { 6 System . out . p r i n t l n ( ”Mi nombre es ” + nombre ) ; 7 } 8 } Ejemplo 2.3: Definición de la clase Parvulo2 Por otro lado, el Ejemplo 2.4 muestra la clase de prueba para el Ejemplo 2.3, la cual es también similar a la del Ejemplo 2.2 excepto en la forma en que se envı́a el mensaje al objeto parvulo (lı́nea 10 del Ejemplo 2.4). Observe que el mensaje enviado tiene ahora una cadena como argumento, la cual es referida por el objeto nombre del método mensaje (lı́nea 5 del Ejemplo 2.3) en el momento en que se le envı́a el mensaje mensaje al objeto parvulo. 1 /∗ Clase de prueba para Parvulo2 . Se crea e l o b j e t o ” parvulo ” 2 instanciado de l a c l a s e Parvulo2 y se l e envia e l mensaje 3 ”mensaje” con un argumento . 4 @autor Ricardo Ruiz Rodriguez 5 ∗/ 6 public class PruebaParvulo2{ 7 public static void main ( String [ ] args ) { 8 Parvulo2 parvulo = new Parvulo2 () ; 9 10 parvulo . mensaje ( ” Ricardo ” ) ; 11 } 12 } Ejemplo 2.4: Clase de prueba para la clase Parvulo2 Asegúrese de realizar una labor analı́tica al comparar lı́nea a lı́nea, tanto las clases Parvulo1 y Parvulo2, como las clases PruebaParvulo1 y Prueba- Parvulo2, ası́ como de comprender sus diferencias en base a lo que se ha descrito hasta ahora. La salida del Ejemplo 2.4 se muestra en la Figura 2.2.
  • 42. 2.1. MENSAJES Y MÉTODOS 19 Figura 2.2: Salida del Ejemplo 2.4 2.1.3. Métodos y atributos Por el principio de ocultación de información, es conveniente que única- mente se tenga acceso a los atributos de una clase a través de su interfaz. La interfaz de un objeto está representada por sus métodos públicos (public). 1 /∗ Ejemplo de envio de mensaje e invocacion de metodos ( Version 1.2) . 2 Se introducen l o s metodos s e t y get para a t r i b u t o s de c l a s e . 3 @autor Ricardo Ruiz Rodriguez 4 ∗/ 5 public class Parvulo3 { 6 private String nombre ; 7 8 public void estableceNombre ( String n) { 9 nombre = n ; 10 } 11 12 public String obtenNombre () { 13 return nombre ; 14 } 15 16 public void mensaje ( ) { 17 System . out . p r i n t l n ( ”Mi nombre es ” + obtenNombre () ) ; 18 } 19 } Ejemplo 2.5: Definición de la clase Parvulo3 El Ejemplo 2.5 hace uso de dicho principio al definir, con un acceso restrin- gido o privado (private), el atributo nombre (lı́nea 6) para la clase Parvulo3. Observe que dicha clase define también tres métodos públicos, los cuales es- tablecen la interfaz de los objetos que sean instanciados: 1. estableceNombre: este método es utilizado comúnmente para ajus- tar o establecer el valor de un atributo, y en principio, deberı́a ha- ber un método de este tipo por cada atributo que contenga la clase y que se requiera manipular desde el exterior. Este tipo de métodos son comúnmente referidos como métodos de tipo set. 2. obtenNombre: este método es utilizado comúnmente para recuperar u obtener el valor de un atributo, y al igual que antes, deberı́a ha- ber un método de este tipo por cada atributo que contenga la clase y
  • 43. 20 CAPÍTULO 2. PROGRAMACIÓN ORIENTADA A OBJETOS que se requiera visualizar desde el exterior. Este tipo de métodos son comúnmente referidos como métodos de tipo get. 3. mensaje: este tipo de métodos ha sido descrito con anterioridad. Note que el método está definido como el del Ejemplo 2.1 (sin argumentos), pero funciona como el del Ejemplo 2.3. Asegúrese de comprender ésto. Observe que el método mensaje (lı́neas 16-18) se vale del método obten- Nombre (lı́nea 17) para acceder al atributo nombre, pero no necesariamente tiene que ser ası́, ya que un método puede acceder directamente a los atribu- tos de la clase, siempre y cuando ambos estén definidos dentro de la misma clase. 1 /∗ Clase de prueba para Parvulo3 . Se crea e l o b j e t o ” parvulo ” instanciado 2 de l a c l a s e Parvulo3 y se l e envian cuatro mensajes . 3 @autor Ricardo Ruiz Rodriguez 4 ∗/ 5 public class PruebaParvulo3{ 6 public static void main ( String [ ] args ) { 7 Parvulo3 parvulo = new Parvulo3 () ; 8 9 System . out . p r i n t l n ( ”Nombre del parvulo : ” + parvulo . obtenNombre () ) ; 10 parvulo . estableceNombre ( ” Ricardo ” ) ; 11 System . out . p r i n t l n ( ”Nombre del parvulo : ” + parvulo . obtenNombre () ) ; 12 parvulo . mensaje () ; 13 } 14 } Ejemplo 2.6: Clase de prueba para la clase Parvulo3 Los métodos de tipo set sólo deben trabajar sobre un atributo, por lo que habitualmente sólo reciben un argumento, mismo que corresponde con la clase (tipo) del atributo a modificar2 . De manera análoga, los métodos de tipo get no reciben ningún tipo de argumentos, y la clase de objetos que regresan, está directamente relacionada con la clase del atributo al que accederán 3 . Es importante hacer notar también que la clase Parvulo4, a diferencia de las anteriores, establece ya una caracterı́stica representada y definida por el atributo nombre, de tal forma que los objetos derivados de ella (párvu- los4 ), compartirán dicha caracterı́stica, aunque cada uno poseerá su propia identidad (nombre). 2 String para el caso del Ejemplo 2.5. 3 Ídem. 4 Un párvulo es un niño pequeño en edad preescolar.
  • 44. 2.1. MENSAJES Y MÉTODOS 21 Figura 2.3: Salida del Ejemplo 2.6 El Ejemplo 2.6 muestra la clase de prueba para la clase Parvulo3. Al igual que en los ejemplos anteriores para las clases de prueba, observe que en la lı́nea 7 se define y crea el objeto parvulo. Las lı́neas 9 y 11 hacen uso del método obtenNombre a través del envı́o del mensaje correspondiente, mientras que la lı́nea 10 envı́a el mensaje esta- bleceNombre con un argumento especı́fico. Finalmente, la lı́nea 12 muestra el envı́o del mensaje mensaje, el cual deberı́a resultarle ya familiar al lector. La salida del Ejemplo 2.6 se muestra en la Figura 2.3. Observe que ini- cialmente el atributo nombre del objeto parvulo no está definido, de ahı́ que se imprima null en la salida estándar, el cual es el valor por omisión en Java para las referencias a objetos que no han sido instanciadas, es decir, cuando los objetos todavı́a no existen, y por consiguiente, no han sido inicializados. 2.1.4. Métodos y constructores Un constructor es un método especial que se invoca implı́citamente cuan- do se crea el objeto por medio de la cláusula new. La cláusula new genera la memoria necesaria para representar al objeto correspondiente, y lo inicializa por medio de un constructor. En este sentido, puede haber más de una forma de inicializar un objeto y, en consecuencia, más de un constructor. El identificador o nombre de los métodos constructores debe coincidir con el identificador o nombre de la clase que los define, y como puede haber más de un constructor cuyo identificador es el mismo, la forma de distinguirse entre sı́, es a través del número y clase o tipo de los argumentos que definen, constituyendo con ello una forma de polimorfismo comúnmente conocida co- mo sobrecarga5 . En la creación del objeto, se invoca el constructor que coincida con el número y tipo de argumentos proporcionados a la cláusula new. Las lı́neas 9-11 del Ejemplo 2.7 muestran la definición del constructor 5 La sobrecarga se trata con un poco más de detalle en la Sección 2.1.5.
  • 45. 22 CAPÍTULO 2. PROGRAMACIÓN ORIENTADA A OBJETOS Parvulo4, observe cómo el nombre del constructor coincide exactamente con el nombre de la clase. Dicho constructor define un único argumento n, el cual es un objeto de la clase String. La inicialización que hace el constructor Parvulo4 consiste únicamente de la asignación del objeto n al atributo representado por el objeto nombre. 1 /∗ Ejemplo de envio de mensaje e invocacion de metodos ( Version 1.3) . 2 Se agrega un constructor , e l cual define e l estado i n i c i a l del 3 o b j e t o instanciado . 4 @autor Ricardo Ruiz Rodriguez 5 ∗/ 6 public class Parvulo4 { 7 private String nombre ; 8 9 Parvulo4 ( String n) { 10 nombre = n ; 11 } 12 13 public void estableceNombre ( String n) { 14 nombre = n ; 15 } 16 17 public String obtenNombre () { 18 return nombre ; 19 } 20 21 public void mensaje ( ) { 22 System . out . p r i n t l n ( ”Mi nombre es ” + obtenNombre () ) ; 23 } 24 } Ejemplo 2.7: Definición de la clase Parvulo4 Es importante mencionar que la labor de inicialización de un constructor en particular puede ser un proceso mucho más elaborado que el descrito hasta ahora, y estará en función directa de las responsabilidades de inicialización con que se quiera dotar al constructor, e indudablemente también, de la problemática en particular que se esté resolviendo por medio del objeto en cuestión. Los elementos restantes de la clase Parvulo4 han sido previamente abor- dados en las secciones anteriores. El Ejemplo 2.8 presenta la clase de prueba para el Ejemplo 2.7. Observe que a diferencia de los ejemplos anteriores, en la lı́nea 8 se proporciona un argumento al constructor Parvulo4, lo cual hace que desde la creación del objeto parvulo, le sea definido un nombre. Observe también cómo la secuencia de mensajes subsecuentes coincide con las del Ejemplo 2.6, excepto que en la lı́nea 11 del Ejemplo 2.8, se envı́a el
  • 46. 2.1. MENSAJES Y MÉTODOS 23 Figura 2.4: Salida del Ejemplo 2.8 mensaje estableceNombre al objeto parvulo para ponerle el nombre completo (con apellidos) al párvulo. 1 /∗ Clase de prueba para Parvulo4 . Se crea e l o b j e t o ” parvulo ” instanciado 2 de l a c l a s e Parvulo4 , se usa e l constructor definido , y se l e envian 3 cuatro mensajes . 4 @autor Ricardo Ruiz Rodriguez 5 ∗/ 6 public class PruebaParvulo4{ 7 public static void main ( String [ ] args ) { 8 Parvulo4 parvulo = new Parvulo4 ( ” Ricardo ” ) ; 9 10 System . out . p r i n t l n ( ”Nombre del parvulo : ” + parvulo . obtenNombre () ) ; 11 parvulo . estableceNombre ( ” Ricardo Ruiz Rodriguez ” ) ; 12 System . out . p r i n t l n ( ”Nombre del parvulo : ” + parvulo . obtenNombre () ) ; 13 parvulo . mensaje () ; 14 } 15 } Ejemplo 2.8: Clase de prueba para la clase Parvulo4 Asegúrese de comprender antes de continuar, que la Figura 2.4 muestra la salida correspondiente a la ejecución del Ejemplo 2.8. 2.1.5. Sobrecarga La sobrecarga (overload) es un tipo de polimorfismo, que se caracteriza por la capacidad de poder definir más de un método o constructor con el mismo nombre (identificador), siendo distinguidos entre sı́ por el número y la clase (tipo) de los argumentos que se definen. El Ejemplo 2.9 muestra la sobrecarga de constructores. Note que las lı́neas 8-10 definen el mismo constructor que el del Ejemplo 2.7 excepto por el nombre, y que se ha añadido o sobrecargado un nuevo constructor (lı́neas 12- 14), el cual recibe tres argumentos que representan el nombre (n), el primer apellido (a1), y el segundo apellido (a2) de un párvulo. La sobrecarga de constructores se da porque ambos constructores tiene el mismo identificador (Parvulo5), pero tienen distinto número de parámetros. No puede existir sobrecarga para constructores o métodos con el mismo identificador, y el mismo número o clase (tipo) de parámetros, tiene que
  • 47. 24 CAPÍTULO 2. PROGRAMACIÓN ORIENTADA A OBJETOS Figura 2.5: Salida del Ejemplo 2.10 haber algo que los distinga entre sı́, ya que en otro caso, habrı́a ambigüedad. Los métodos restantes del Ejemplo 2.9 ya ha sido comentados con ante- rioridad. 1 /∗ Ejemplo de envio de mensaje e invocacion de metodos ( Version 1.4) . 2 Se muestra l a sobrecarga de constructores . 3 @autor Ricardo Ruiz Rodriguez 4 ∗/ 5 public class Parvulo5 { 6 private String nombre ; 7 8 Parvulo5 ( String n) { 9 nombre = n ; 10 } 11 12 Parvulo5 ( String n , String a1 , String a2 ) { 13 nombre = n + ” ” + a1 + ” ” + a2 ; 14 } 15 16 public void estableceNombre ( String n) { 17 nombre = n ; 18 } 19 20 public String obtenNombre () { 21 return nombre ; 22 } 23 24 public void mensaje ( ) { 25 System . out . p r i n t l n ( ”Mi nombre es ” + obtenNombre () ) ; 26 } 27 } Ejemplo 2.9: Definición de la clase Parvulo5 La clase de prueba para el Ejemplo 2.9 se muestra en el Ejemplo 2.10, y es también muy similar a las clases de prueba anteriormente explicadas. Únicamente cabe resaltar la creación del objeto parvulo en la lı́nea 7, note que ahora se le proporcionan tres argumentos al constructor, lo cual hace que el constructor utilizado sea el definido en las lı́neas 12-14 del Ejemplo 2.9. La salida del Ejemplo 2.10 aparece en la Figura 2.5. Compare dicha salida con la de la Figura 2.4 y asegúrese de comprender la diferencia. 1 /∗ Clase de prueba para Parvulo5 . Se crea e l o b j e t o ” parvulo ” instanciado 2 de l a c l a s e Parvulo5 mostrando la sobrecarga de constructores .
  • 48. 2.2. HERENCIA 25 3 @autor Ricardo Ruiz Rodriguez 4 ∗/ 5 public class PruebaParvulo5{ 6 public static void main ( String [ ] args ) { 7 Parvulo5 parvulo = new Parvulo5 ( ” Ricardo ” , ”Ruiz” , ” Rodriguez ” ) ; 8 9 System . out . p r i n t l n ( ”Nombre del parvulo : ” + parvulo . obtenNombre () ) ; 10 parvulo . estableceNombre ( ” Ricardo ” ) ; 11 System . out . p r i n t l n ( ”Nombre del parvulo : ” + parvulo . obtenNombre () ) ; 12 parvulo . mensaje () ; 13 } 14 } Ejemplo 2.10: Clase de prueba para la clase Parvulo5 2.2. Herencia Todos los conceptos del paradigma orientado a objetos discutidos en el Capı́tulo 1 son importantes, pero el concepto de herencia es uno de los más importantes, ya que dicho mecanismo de abstracción permite la reutilización de código de una manera sumamente conveniente, y habilita las capacidades del polimorfismo a través de la sobre escritura de métodos. 2.2.1. Abstracción La descripción del concepto de herencia estará basado en los Ejemplos 2.11 y 2.12, pero para poder describirlos, considero pertinente presentar pri- mero en un diagrama, los detalles de la relación que se quiere ejemplificar para elevar el nivel de abstracción, es decir, a la forma en que las personas comprendemos y analizamos las cosas, para posteriormente profundizar con más conocimiento de causa, en los detalles de la implementación del concepto en un lenguaje de programación. El diagrama de clases UML6 del que partirá el análisis se muestra en la Figura 2.6. Los detalles completos de la explicación de un diagrama de clases UML quedan fuera de los alcances de este libro, y sólo se describirán los aspectos más relevantes que ayuden al lector a visualizar de mejor manera la herencia, en caso de que el lector no cuente con experiencia en UML. 6 Leguaje de Modelado Unificado (Unified Modeling Language).
  • 49. 26 CAPÍTULO 2. PROGRAMACIÓN ORIENTADA A OBJETOS Figura 2.6: Diagrama de clases UML para la relación de herencia entre Cien- tifico y Persona Un diagrama de clases UML está compuesto, grosso modo, por clases y las relaciones entre dichas clases. Por otro lado, cada clase es un recuadro dividido en tres partes: 1. Identificador de la clase. 2. Listado de atributos con la especificación de su clase (tipo) y sus niveles de acceso correspondientes. 3. Listado de métodos con la especificación de la clase (tipo) de sus ar- gumentos y valor de retorno, ası́ como los niveles de acceso correspon- dientes para los métodos. Tanto para el caso de los atributos como para el de los métodos, los niveles de acceso están representados por un signo de más para un acceso público (+), y un signo de menos para un acceso privado (-). En base a lo anterior, puede observarse de la Figura 2.6 que la clase Persona, y por lo tanto las instancias que se deriven de ella, tendrán las siguientes caracterı́sticas (atributos) comunes a una persona: un nombre, una edad, y una nacionalidad7 . Observe también que se ha definido un conjunto de operaciones, acciones, responsabilidades o comportamiento comunes a una persona, definido por los métodos. 7 Podrı́an definirse mucho más caracterı́sticas, o caracterı́sticas diferentes a las descritas, pero no es la intención del ejemplo representar las caracterı́sticas completas y comunes a una persona, y lo mismo ocurre para el comportamiento o las responsabilidades represen- tadas en los métodos.
  • 50. 2.2. HERENCIA 27 Caracterı́sticas más caracterı́sticas menos, acciones más, acciones menos, es posible decir que una persona en promedio está en general representada por la clase Persona. Ahora bien, un cientı́fico es8 una persona, y por lo tanto comparte las caracterı́sticas y las acciones inherentes a una persona, y es precisamente esta relación de compartir, la que se refiere a la herencia, ya que se dice que en la herencia, una clase hereda (comparte) los atributos (caracterı́sticas) y métodos (acciones) a otra. La herencia en UML se representa por medio de una flecha como la de la Figura 2.6, y es importante señalar que el sentido de la flecha es muy impor- tante, ya que tal y como aparece en la figura, indica que la clase Cientifico hereda las caracterı́sticas y el comportamiento de la clase Persona (y no al revés). Note que la clase Cientifico define un atributo adicional (especialidad), mismo que se añade a todos los atributos que implı́citamente ya tiene, los cuales fueron heredados de la clase Persona. Observe también que se han de- finido cuatro métodos para la clase Cientifico, los cuales tienen las siguientes caracterı́sticas: estableceEspecialidad : es un método set para el atributo especialidad definido en la clase Cientifico. obtenEspecialidad : es un método get para el atributo especialidad defi- nido en la clase Cientifico. mensaje : este método ya estaba definido en la clase Persona, pero al ser redefinido en la clase Cientifico, se dice que sobre escribe (override) al primero, lo cual significa que un objeto instanciado de la clase Cien- tifico, responderá al mensaje mensaje con la definición de su propio método, y no con la definición del método mensaje definido en la clase Persona. mensajeEspecial : este es un nuevo método particular y especı́fico a las instancias derivadas de la clase Cientifico. Es sumamente importante que el lector se asegure de comprender la descripción hasta aquı́ realizada respecto a las clases Persona y Cientifi- co, ası́ como de entender la relación existente entre ellas antes de continuar 8 Recuerde la idea de división en especializaciones (relación is-a) presentada en el Capı́tulo 1.
  • 51. 28 CAPÍTULO 2. PROGRAMACIÓN ORIENTADA A OBJETOS a la siguiente sección, en donde se abordarán los aspectos relacionados con la implementación. 2.2.2. Implementación El Ejemplo 2.11 muestra la implementación en Java de la clase Persona mostrada en la Figura 2.6. Todos los detalles de la clase Persona del Ejemplo 2.11 ya han sido discutidos con anterioridad, por lo que es importante que el lector los revise, analice, y compare, con los elementos del diagrama UML descritos en la sección anterior, y que se asegure de comprender la relación que existe entre ellos. 1 /∗ Ejemplo de herencia . 2 La c l a s e Persona sera l a c l a s e padre ( super c l a s e ) 3 de l a c l a s e C i e n t i f i c o . 4 @autor Ricardo Ruiz Rodriguez 5 ∗/ 6 public class Persona { 7 // Atributos de l a c l a s e 8 private String nombre ; 9 private int edad ; 10 private String nacionalidad ; 11 12 // Constructor de un argumento ( nombre ) 13 Persona ( String n) { 14 nombre = n ; 15 } 16 17 // Constructor de dos argumentos ( nombre y edad ) 18 Persona ( String n , int e ) { 19 nombre = n ; 20 edad = e ; 21 } 22 23 // Constructor de t r e s argumentos (nombre , edad y nacionalidad ) 24 Persona ( String n , int e , String nac ) { 25 nombre = n ; 26 edad = e ; 27 nacionalidad = nac ; 28 } 29 30 // Metodo para e s t a b l e c e r ( s e t ) e l a t r i b u t o ”nombre” 31 public void estableceNombre ( String n) { 32 nombre = n ; 33 } 34 35 // Metodo para obtener ( get ) e l a t r i b u t o ”nombre” 36 public String obtenNombre () { 37 return nombre ; 38 } 39 40 // Metodo para e s t a b l e c e r ( s e t ) e l a t r i b u t o ”edad”
  • 52. 2.2. HERENCIA 29 41 public void estableceEdad ( int e ) { 42 edad = e ; 43 } 44 45 // Metodo para obtener ( get ) e l a t r i b u t o ”edad” 46 public int obtenEdad () { 47 return edad ; 48 } 49 50 // Metodo para e s t a b l e c e r ( s e t ) e l a t r i b u t o ” nacionalidad ” 51 public void estableceNacionalidad ( String n) { 52 nacionalidad = n ; 53 } 54 55 // Metodo para obtener ( get ) e l a t r i b u t o ” nacionalidad ” 56 public String obtenNacionalidad ( ) { 57 return nacionalidad ; 58 } 59 60 // Metodo para imprimir un mensaje en la s a l i d a estandar 61 public void mensaje ( ) { 62 System . out . p r i n t l n ( ”Puedo hablar , mi nombre es ” + obtenNombre () ) ; 63 } 64 65 // Metodo que simula l a accion de comer por parte de una persona 66 public void comer () { 67 System . out . p r i n t l n ( ”M m m m m m uno de l o s p l a c e r e s de la vida . . . ” ) ; 68 } 69 } Ejemplo 2.11: Definición de la clase Persona Por otro lado, el Ejemplo 2.12 contiene la implementación de la clase Cientifico mostrada en la Figura 2.6. Observe que la herencia es implemen- tada en Java a través del uso de la cláusula extends (lı́nea 6), seguida de la clase de la que se hereda (Persona) en la definición de la clase Cientifico. Es importante que el lector note el uso de la cláusula super en los cons- tructores (lı́neas 11 y 18). El uso en Java de dicha cláusula sólo puede hacerse en el contexto de constructores, y sirve para delegarle al constructor corres- pondiente de la clase padre, los detalles de inicialización del objeto en cuestión que, para el caso de la clase Cientifico, corresponden a los constructores de dos y tres argumentos de la clase Persona. Asegúrese de comprender ésto antes de continuar. Al igual que antes, se deja como ejercicio de análisis para el lector, tanto los detalles restantes de implementación de la clase Cientifico, como el asegu- rarse de comprender la relación del diagrama UML con el código del Ejemplo 2.12.
  • 53. 30 CAPÍTULO 2. PROGRAMACIÓN ORIENTADA A OBJETOS En este punto, es importante también que el lector ponga especial aten- ción en los métodos mensaje del Ejemplo 2.11 (lı́neas 61-63), y del Ejemplo 2.12 (lı́neas 33-35), ya que serán fundamentales para comprender la sobre es- critura de métodos que se discute más adelante en la clase de prueba (Ejemplo 2.13). 1 /∗ Ejemplo de herencia . 2 La c l a s e C i e n t i f i c o hereda l a s c a r a c t e r i s t i c a s ( a t r i b u t o s ) 3 y operaciones ( metodos ) de l a c l a s e Persona . 4 @autor Ricardo Ruiz Rodriguez 5 ∗/ 6 public class C i e n t i f i c o extends Persona { 7 private String e s p e c i a l i d a d ; 8 9 // Constructor de t r e s argumentos (nombre , edad y e s p e c i a l i d a d ) 10 C i e n t i f i c o ( String n , int e , String esp ) { 11 super (n , e ) ; 12 e s p e c i a l i d a d = esp ; 13 } 14 15 // Constructor de cuatro argumentos (nombre , edad , 16 // nacionalidad y e s p e c i a l i d a d ) 17 C i e n t i f i c o ( String n , int e , String nac , String esp ) { 18 super (n , e , nac ) ; 19 e s p e c i a l i d a d = esp ; 20 } 21 22 // Metodo para e s t a b l e c e r ( s e t ) e l a t r i b u t o ” e s p e c i a l i d a d ” 23 public void e s t a b l e c e E s p e c i a l i d a d ( String e ) { 24 e s p e c i a l i d a d = e ; 25 } 26 27 // Metodo para obtener ( get ) e l a t r i b u t o ” e s p e c i a l i d a d ” 28 public String obtenEspecialidad () { 29 return e s p e c i a l i d a d ; 30 } 31 32 // Metodo para imprimir un mensaje en la s a l i d a estandar 33 public void mensaje ( ) { 34 System . out . p r i n t l n ( ”Yo, ” + obtenNombre ( ) + ” , soy ” + obtenEspecialidad () ) ; 35 } 36 37 // Metodo para imprimir un mensaje e s p e c i a l en l a s a l i d a estandar 38 public void mensajeEspecial () { 39 System . out . p r i n t l n ( ”La d i s t a n c i a del s o l a la t i e r r a es 149 600 000 kms” ) ; 40 } 41 } Ejemplo 2.12: Definición de la clase Cientifico La clase de prueba para la herencia se presenta en el Ejemplo 2.13 y se describe a continuación. La lı́nea 10 define el objeto persona y genera
  • 54. 2.2. HERENCIA 31 Figura 2.7: Salida del Ejemplo 2.13 una instancia de la clase Persona con caracterı́sticas especı́ficas; note que el constructor que está siendo utilizado es el definido en las lı́neas 24-28 del Ejemplo 2.11. Observe cómo en las lı́neas 13, 15, 19 y 21 del Ejemplo 2.13, se envı́an mensajes especı́ficos al objeto persona para obtener su nombre, cambiarle el nombre, volver a obtener su nombre, solicitarle comer y un mensaje respec- tivamente; cuya salida se ve expresada en las primeras cuatro lı́neas de la Figura 2.7. Por otro lado, la lı́nea 26 define y crea el objeto cientifico como una instancia de la clase Cientifico. Al igual que antes, note cómo el constructor utilizado es el definido en las lı́neas 17-20 del Ejemplo 2.12. A su vez, las lı́neas 28 y 30 del Ejemplo 2.13, realizan algo semejante a lo que se hizo con el objeto persona, es decir, envı́an mensajes al objeto cientifico para obtener y cambiar el nombre del cientı́fico respectivamente. La lı́nea 32 por su parte, cambia la especialidad del cientı́fico a través de un mensaje de tipo set. Finalmente, las lı́neas 34, 36, 38 y 40, envı́an mensajes especı́ficos al objeto cientifico para obtener su nombre y solicitarle comer, un mensaje y un mensaje especial respectivamente. Note cómo para el mensaje mensaje, las respuestas del objeto persona y el objeto cientifico difieren por completo, debido a que aunque el mensaje es el mismo, el objeto que los recibe responde de manera distinta a dicho mensaje; ésto último fue lo que en el Capı́tulo 1 se definió como polimorfismo9 . La salida del Ejemplo 2.13 se muestra en la Figura 2.7. 9 El polimorfismo está expresado en el ejemplo en su forma de sobre escritura (override) de métodos.
  • 55. 32 CAPÍTULO 2. PROGRAMACIÓN ORIENTADA A OBJETOS 1 /∗ Clase de prueba para l a herencia . 2 se l e envian mensajes . Posteriormente se crea e l o b j e t o ”persona” 3 instanciado de l a c l a s e C i e n t i f i c o y tambien se l e envian mensajes , 4 note que algunos mensajes son heredados de l a super c l a s e . 5 @autor Ricardo Ruiz Rodriguez 6 ∗/ 7 public class PruebaHerencia { 8 public static void main ( String [ ] args ) { 9 // Se crea e l o b j e t o ”persona” instanciado de l a c l a s e Persona 10 Persona persona = new Persona ( ” Ricardo ” , 38 , ”Mexicano” ) ; 11 12 // Se imprime e l nombre del o bjeto ”persona” a traves de un mensaje 13 System . out . p r i n t l n ( ”Nombre : ” + persona . obtenNombre () ) ; 14 // Se e s t a b l e c e un nuevo nombre para e l o b j e t o ”persona” 15 persona . estableceNombre ( ” Ricardo Ruiz Rodriguez ” ) ; 16 // Se s o l i c i t a nuevamente a l o b j e t o ”persona” imprimir su nombre 17 System . out . p r i n t l n ( ”Nombre : ” + persona . obtenNombre () ) ; 18 // Se l e envia a l o b j e t o ”persona” e l mensaje ”comer” 19 persona . comer ( ) ; 20 // Se l e envia a l o b j e t o ”persona” e l mensaje ”mensaje” 21 persona . mensaje ( ) ; 22 23 System . out . p r i n t l n ( ) ; 24 25 // Se crea e l o b j e t o ” c i e n t i f i c o ” instanciado de l a c l a s e C i e n t i f i c o 26 C i e n t i f i c o c i e n t i f i c o = new C i e n t i f i c o ( ” Carl Sagan” , 62 , ” Estadounidense ” , ”Astronomo” ) ; 27 // Se imprime e l nombre del o b j e t o ” c i e n t i f i c o ” a traves de un mensaje 28 System . out . p r i n t l n ( ”Nombre : ” + c i e n t i f i c o . obtenNombre () ) ; 29 // Se e s t a b l e c e un nuevo nombre para e l o b j e t o ” c i e n t i f i c o ” 30 c i e n t i f i c o . estableceNombre ( ” Carl Edward Sagan” ) ; 31 // Se e s t a b l e c e una nueva e s p e c i a l i d a d para e l o b j e t o ” c i e n t i f i c o ” 32 c i e n t i f i c o . e s t a b l e c e E s p e c i a l i d a d ( ”Astronomo y A s t r o f i s i c o ” ) ; 33 // Se s o l i c i t a nuevamente a l o b j e t o ” c i e n t i f i c o ” imprimir su nombre 34 System . out . p r i n t l n ( ”Nombre : ” + c i e n t i f i c o . obtenNombre () ) ; 35 // Se l e envia a l o b j e t o ” c i e n t i f i c o ” e l mensaje ”comer” 36 c i e n t i f i c o . comer ( ) ; 37 // Se l e envia a l o b j e t o ” c i e n t i f i c o ” e l mensaje ”mensaje” 38 c i e n t i f i c o . mensaje ( ) ; 39 // Se l e envia a l o b j e t o ” c i e n t i f i c o ” e l mensaje ” mensajeEspecial ” 40 c i e n t i f i c o . mensajeEspecial ( ) ; 41 // persona . mensajeEspecial () ; 42 } 43 } Ejemplo 2.13: Clase de prueba para la herencia
  • 56. 2.3. CONSIDERACIONES FINALES 33 2.3. Consideraciones finales 2.3.1. Respecto al envı́o de mensajes La sintaxis general en Java para el envı́o de mensajes a un objeto es la siguiente: objeto.mensaje(lista de argumentos) donde objeto es un objeto de una clase previamente definida, y mensaje es uno de los métodos públicos definidos para dicha clase. La lista de argumentos es una lista de argumentos separada por comas, en donde cada argumento puede ser un objeto, o un tipo de dato primitivo. 2.3.2. Respecto a la sobrecarga de operadores Algunos lenguajes de programación soportan un concepto relacionado con sobrecarga de operadores. La idea general del concepto de sobrecarga se ha planteado en la Sección 2.1.5. El lenguaje de programación Java no soporta la sobrecarga de operadores, y por consiguiente, se ha omitido su descripción; pero es importante que el lector conozca que el concepto de sobrecarga no es exclusivo de los métodos o constructores, y mucho menos de un lenguaje de programación en particular. 2.3.3. Respecto al paradigma El establecimiento de niveles de acceso como private para los atributos de una clase, y el uso de métodos de tipo set y get están directamente rela- cionados con el principio de ocultación de información. Ahora bien, es probable que el lector haya notado que en la descripción del Ejemplo 2.13, en distintas ocasiones se hizo referencia a los objetos persona y cientifico como si fueran en sı́ mismos personas o entidades existentes. Ésto se hizo de manera deliberada, ya que como se comentó en el Capı́tulo 1, el paradigma orientado a objetos eleva el nivel de abstracción, y hace que se haga referencia a las entidades fundamentales del paradigma (objetos), como elementos comunes de nuestro lenguaje natural, lo cual permite que los problemas se puedan expresar de una manera más natural e intuitiva. En éste sentido, al dotar a los objetos de una personalidad propia con caracterı́sticas y responsabilidades, en lugar de pensar en términos de datos,
  • 57. 34 CAPÍTULO 2. PROGRAMACIÓN ORIENTADA A OBJETOS variables, y funciones o procedimientos que operen sobre dichos datos, se eleva el nivel de abstracción, facilitando ası́ el análisis y la comprensión, ya que el problema y su solución pueden ser expresados y analizados en términos del dominio del problema, y no en el del medio (lenguaje de programación) de la solución. Ésta es la forma en la que las personas abstraemos y utilizamos la información. Es sumamente importante que el lector tenga presente, que en el paradig- ma orientado a objetos, no se piensa en términos de datos, sino en términos de entidades con caracterı́sticas y responsabilidades especı́ficas, por lo que, cuando defina una clase, puede resultarle útil el plantearse al menos un par de preguntas10 que le permitan determinar si los los objetos derivados de su clase tienen o no sentido, además de una alta cohesión: ¿Los atributos representan caracterı́sticas o propiedades, o definen un estado para los objetos que serán instanciados? ¿La clase representa en sus métodos servicios, comportamiento, accio- nes o responsabilidades inherentes a los objetos que deriven de ella? Con estas dos sencillas preguntas, además de validar y verificar su diseño de clases, estará reforzando el concepto de encapsulamiento. 10 Las preguntas propuestas son sólo una guı́a y una sugerencia al lector, no pretenden ser de ninguna manera una lista completa y absoluta.
  • 58. 2.4. EJERCICIOS 35 2.4. Ejercicios 1. En el Ejemplo 2.5 se hizo referencia a la invocación del mensaje ob- tenNombre (lı́nea 17) dentro del método mensaje. Cambie el método obtenNombre por el atributo nombre y compruebe lo descrito en el texto. 2. Considere el Ejemplo 2.6. ¿Qué sucede si en lugar de acceder al atributo nombre por medio del método obtenNombre (lı́neas 9 y 11) se intenta acceder directamente al atributo a través del operador punto?. Para probar lo anterior, cambie la expresión: parvulo.obtenNombre() por la expresión: parvulo.nombre recompile y analice lo que suceda. 3. Modifique el Ejemplo 2.6 para que genere más de un objeto de la clase Parvulo3 del Ejemplo 2.5, de tal forma que tenga un conjunto de al menos tres párvulos. Para los objetos creados, definales una identidad a cada uno de los párvulos instanciados por medio de la asignación de un nombre distinto a cada uno de ellos, envı́eles mensajes, experimente y juegue con ellos, recuerde que sus objetos son, al fin y al cabo, niñ@s pequeñ@s. 4. Para el Ejemplo 2.7, defina y añada un constructor sin argumentos, de tal forma que la labor del constructor sea definir su propio nombre (el nombre del lector) al atributo nombre. Modifique en consecuencia la clase del Ejemplo 2.8 para que haga uso del constructor recién definido, y compruebe su funcionamiento. 5. La Sección 2.1.5 abordó el tema de la sobrecarga, y ejemplificó el con- cepto utilizando sobrecarga de constructores. La sobrecarga de métodos es análoga a la de constructores.
  • 59. 36 CAPÍTULO 2. PROGRAMACIÓN ORIENTADA A OBJETOS Modifique el Ejemplo 2.9 para que implemente la sobrecarga de méto- dos de la siguiente manera: a) Defina un nuevo método con la siguiente firma: public void mensaje(String m) b) La responsabilidad del nuevo método mensaje, será la de imprimir en la salida estándar la leyenda “Mensaje recibido”, seguido de la cadena m. c) Realice una clase de prueba (puede basarse en la del Ejemplo 2.10) para comprobar el funcionamiento de todos los métodos, especialmente, el método sobrecargado mensaje. 6. Considere el Ejemplo 2.9 y modifı́quelo para que, en lugar de uno, defina tres atributos: nombre (String). apellido1 (String). apellido2 (String). En base a lo anterior: a) Agregue el método set correspondiente para cada uno de los atri- butos, en base a lo descrito en el texto. b) Agregue el método get correspondiente para cada uno de los atri- butos, también en base a lo descrito en el texto. c) Agregue un constructor para que sea posible construir un objeto (párvulo) utilizando únicamente el nombre, y el primer apellido. d) Modifique el método mensaje para que, en caso de que alguno de los atributos del objeto en cuestión sea null, dicho atributo sea ignorado y en consecuencia, no se imprima en la salida estándar. e) Construya una clase de prueba que demuestre tanto el funciona- miento de todas las posibles opciones de construcción de objetos, como el adecuado funcionamiento de los métodos set, get y men- saje.
  • 60. 2.4. EJERCICIOS 37 7. El Ejemplo 2.13 tiene la lı́nea 41 comentada, por lo que el compilador y la JVM la ignoran. Si la descomenta ¿qué piensa que sucederá?, ¿compilará?, ¿se ejecutará?, ¿imprimirá algo en la salida estándar?, ¿fallará la ejecución?. Después de analizar el programa, responda dichas preguntas, y corro- bore su respuesta con la experimentación. 8. Modifique el Ejemplo 2.11 para que contenga más atributos, es decir, para que las caracterı́sticas de una persona estén más completas. No olvide agregar métodos de tipo set y get por cada uno de los atributos que añada. Para los atributos, añada al menos los siguientes cambios: Cambie el atributo nombre por una distribución más convencional: nombre, primer apellido, y segundo apellido. Agregue un atributo que represente la dirección o domicilio. Agregue un atributo que represente el sexo, femenino o masculino, según sea el caso. Después de lo anterior: a) Compruebe el adecuado funcionamiento de la clase Persona res- pecto de las modificaciones recién hechas. Asegúrese de comprobar que los métodos set y get trabajan de la manera esperada. b) Compruebe que con los cambios realizados a la clase Persona, los aspectos relacionados con la herencia de la clase Cientifico del Ejemplo 2.12, siguen funcionando sin ningún tipo de problema. c) Modifique la clase Cientifico de manera análoga, y compruebe también que el mecanismo de la herencia permanece inalterado. Para la clase Cientifico agregue dos atributos (y sus correspon- dientes métodos de acceso): 1) Institución o lugar donde labora. 2) Grado de estudios. d) Agregue nuevas acciones, comportamientos o responsabilidades a las clases Persona y Cientifico, y asegúrese de probar su adecua- do funcionamiento. No olvide experimentar con los conceptos de sobrecarga y sobre escritura.
  • 61. 38 CAPÍTULO 2. PROGRAMACIÓN ORIENTADA A OBJETOS 9. Construya un ejemplo completamente diferente al visto en el texto, donde ponga de relieve los conceptos de envı́o de mensajes, herencia, polimorfismo, encapsulamiento y ocultación de información. Para realizar lo anterior, puede apoyarse de la jerarquı́a de clases de la Figura 1.2, o de alguna otra figura o idea que sea de su preferencia.
  • 62. Capı́tulo 3 Estructuras de datos Ask not what you can do to your data structures, but rather ask what your data structures can do for you. 3.1. Panorama general De manera general, es posible decir que una computadora es una máquina que manipula y procesa datos. Las estructuras de datos están relacionadas con el estudio de cómo es que se organizan los datos dentro de una computadora, y de cómo se manipulan, procesan y emplean dichos datos, para representar información que sea de utilidad para las personas. Existen muchos tipos de estructuras de datos, y para cada estructura de datos, hay diferentes variaciones que las particularizan para un contexto de uso especı́fico. Un tratado amplio y completo de las estructuras de datos, queda fuera de los alcances de este libro, por lo que sólo se mencionarán algunas de las estructuras de datos más comunes y convencionales, ası́ como algunas de sus variaciones. A continuación se presenta una descripción muy general de las estructuras de datos que se analizarán en los capı́tulos siguientes: Pilas : son estructuras de datos ampliamente utilizadas y sumamente im- portantes en compiladores y sistemas operativos por ejemplo. En una pila, las inserciones y las eliminaciones se efectúan únicamente en un extremo de la estructura de datos: su parte superior. 39
  • 63. 40 CAPÍTULO 3. ESTRUCTURAS DE DATOS Colas de espera : este tipo de estructuras de datos representan en general lı́neas de espera; las inserciones se efectúan en la parte posterior de la misma, y las eliminaciones se hacen por la parte delantera. Listas enlazadas : son colecciones de elementos de datos alineados en una fila. En una lista enlazada, las inserciones y las eliminaciones se efectúan en cualquier parte de la estructura de datos. Árboles binarios : son estructuras de datos que facilitan la búsqueda, la clasificación u ordenamiento de los datos a alta velocidad, la elimina- ción de elementos duplicados, la representación de sistemas de archivos y directorios, y las expresiones de compilación entre otras muchas apli- caciones. Cada una de estas estructuras de datos tienen muchas otras, y muy in- teresantes aplicaciones, algunas de las cuales, se presentan y discuten en los capı́tulos correspondientes a cada una de ellas. 3.2. Tipos de datos y referencias Probablemente el lector esté familiarizado con el concepto de tipo de dato, ya sea debido a que tenga experiencia previa con algún lenguaje de programación, o simplemente porque ha revisado el material del Apéndice A o del Capı́tulo 2. Entonces ¿podrı́a definir qué es un tipo de dato?. Un tipo de dato es un método para interpretar un patrón de bits. En éste sentido, una secuencia de bits determinada podrı́a ser interpretada de una forma u otra, en función del tipo de dato. En la mayorı́a de los lenguajes de programación, el programador especifi- ca, mediante las declaraciones de variables u objetos, cómo es que el programa va a interpretar el contenido de la memoria de la computadora. Las declaraciones también le especifican al compilador exactamente, qué es lo que representan los sı́mbolos de las operaciones que se utilizarán, ya que aunque en apariencia es lo mismo, los mecanismos de implementación de una operación aritmética tan aparentemente simple como la adición, difieren de un tipo de dato a otro. Por otro lado, para la mayorı́a de los lenguajes de programación, los nombres de variables o identificadores asociados a los objetos, son en reali- dad referencias, es decir, direcciones de memoria en las que se almacenan fı́sicamente los objetos a los que hacen referencia.
  • 64. 3.3. TIPOS DE DATOS ABSTRACTOS (ADT) 41 El manejo de referencias o direcciones de memoria puede ser explı́cito, como en el caso de los lenguajes C y C++ por ejemplo, donde el manejo de referencias se realiza a través de apuntadores. En algunos otros lenguajes como Java y C#, el manejo de referencias es implı́cito, es decir, se realiza a través del nombre o identificador de los objetos. Tanto el manejo de referencias explı́cito como el implı́cito, tienen sus ventajas y desventajas, y las fortalezas de uno, son las debilidades del otro y viceversa. No es la intención de esta sección ni la del libro extenderse en dichos aspectos, ya que para los objetivos especı́ficos que se persiguen en este texto, basta con saber que Java hace uso de referencias implı́citas, y que el nombre los objetos son en realidad dichas referencias y no los objetos en sı́ mismos. En la Sección 3.4.1 se detalla y ejemplifica el manejo de referencias para los objetos. 3.3. Tipos de datos abstractos (ADT) Desde el punto de vista de la programación, es importante que los pro- gramadores puedan definir sus propias abstracciones de datos, de tal forma que dichas abstracciones trabajen de manera parecida a las abstracciones o a las primitivas de datos proporcionadas por el sistema subyacente. Un tipo de dato abstracto o ADT (Abstract Data Type), es definido por una especificación abstracta, es decir, permite especificar las propiedades lógicas y funcionales de un tipo de dato. Desde el punto de vista de los ADT, un tipo de dato es un conjunto de valores y un grupo de operaciones definidas sobre dichos valores. El conjunto de valores y el de las operaciones, forman una estructura matemática que se implementa usando una estructura de datos particular de hardware o de software. El concepto de ADT está relacionado con la concepción matemática que define al tipo de datos, por lo que, al definir un ADT como concepto ma- temático, no interesa la eficiencia del espacio o del tiempo1 , sino las pro- piedades y caracterı́sticas inherentes a él. La definición de un ADT no se relaciona en lo absoluto con los detalles de la implementación; de hecho, tal vez ni siquiera sea posible implementar un ADT particular en ningún tipo de hardware o software2 . 1 Los cuales son aspectos relacionados con la implementación del ADT. 2 Piense por ejemplo en los números reales y en la propiedad de la densidad de los