programaciÓn orientada a objetos (072-2103) · programaciÓn orientada a objetos (072-2103) unidad...

100
PROGRAMACIÓN ORIENTADA A OBJETOS (072-2103) Unidad I: Introducción 1.1 Historia del Computador 1.2 Lenguajes de Programación 1.3 Compilación de Programas 1.4 Paradigmas de Programación Unidad II: Paradigma Orientado a Objetos 2.1 Generalidades 2.2 Clases y Objetos 2.3 Programación en Consola Unidad III: Datos Simples 3.1 Variables 3.2 Tipos de Datos 3.3 Expresiones, Operadores y Asignaciones Unidad IV: Estructuras de Control 4.1 Estructuras de Control Selectivas 4.2 Estructuras de Control Iterativas Unidad V: Datos Compuestos 5.1 Arreglos 5.2 Cadenas 5.3 Estructuras y Enumeraciones Unidad VI: Fundamentos Avanzados de Programación 6.1 Propiedades de uso, modificadores de parámetros y regiones 6.2 Recursividad 6.3 Apuntadores y clases autoreferenciadas 6.4 Herencia 6.5 Interfaces

Upload: others

Post on 10-Oct-2020

2 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: PROGRAMACIÓN ORIENTADA A OBJETOS (072-2103) · PROGRAMACIÓN ORIENTADA A OBJETOS (072-2103) Unidad I: Introducción 1.1 Historia del Computador 1.2 Lenguajes de Programación 1.3

PROGRAMACIÓN ORIENTADA A OBJETOS (072-2103)

Unidad I: Introducción

1.1 Historia del Computador

1.2 Lenguajes de Programación

1.3 Compilación de Programas

1.4 Paradigmas de Programación

Unidad II: Paradigma Orientado a Objetos

2.1 Generalidades

2.2 Clases y Objetos

2.3 Programación en Consola

Unidad III: Datos Simples

3.1 Variables

3.2 Tipos de Datos

3.3 Expresiones, Operadores y Asignaciones

Unidad IV: Estructuras de Control

4.1 Estructuras de Control Selectivas

4.2 Estructuras de Control Iterativas

Unidad V: Datos Compuestos

5.1 Arreglos

5.2 Cadenas

5.3 Estructuras y Enumeraciones

Unidad VI: Fundamentos Avanzados de Programación

6.1 Propiedades de uso, modificadores de parámetros y regiones

6.2 Recursividad

6.3 Apuntadores y clases autoreferenciadas

6.4 Herencia

6.5 Interfaces

Page 2: PROGRAMACIÓN ORIENTADA A OBJETOS (072-2103) · PROGRAMACIÓN ORIENTADA A OBJETOS (072-2103) Unidad I: Introducción 1.1 Historia del Computador 1.2 Lenguajes de Programación 1.3

Programación Orientada a Objetos

2

TABLA DE CONTENIDO

Unidad I: Introducción

1.1 Historia de la computación............................................................................................ 5

1.1.1 La computadora ............................................................................................................. 5

1.1.2 Prehistoria de la computación ....................................................................................... 5

1.1.3 Generaciones de la computadora .................................................................................. 6

1.2 Lenguajes de programación .......................................................................................... 9

1.2.1 Tipos de lenguajes ......................................................................................................... 9

1.2.2 Criterios del lenguaje .................................................................................................. 10

1.3 Compilación de programas ......................................................................................... 11

1.3.1 Tipos de compiladores ................................................................................................ 12

1.3.2 Proceso de compilación............................................................................................... 12

1.3.3 Etapas de la compilación ............................................................................................. 13

1.3.4 Otras herramientas de programación .......................................................................... 13

1.4 Paradigmas de programación ...................................................................................... 14

Unidad II: Paradigma orientado a objetos

2.1 Generalidades .............................................................................................................. 16

2.1.1 Conceptos dentro de la POO ....................................................................................... 16

2.1.2 Ventajas ....................................................................................................................... 17

2.2 Clases y objetos ........................................................................................................... 17

2.2.1 Acceso a los miembros de una clase ........................................................................... 19

2.2.2 Constructores y destructores ....................................................................................... 21

2.2.3 Ventajas del uso de clases ........................................................................................... 23

2.3 Programación en consola ............................................................................................ 24

2.3.1 Buffer de pantalla y ventana de la consola.................................................................. 24

2.3.2 La clase console .......................................................................................................... 25

2.3.3 Entrada y salida por consola ....................................................................................... 25

2.3.4 Métodos para personalizar la consola ......................................................................... 28

2.4 Ejercicios propuestos .................................................................................................. 30

Page 3: PROGRAMACIÓN ORIENTADA A OBJETOS (072-2103) · PROGRAMACIÓN ORIENTADA A OBJETOS (072-2103) Unidad I: Introducción 1.1 Historia del Computador 1.2 Lenguajes de Programación 1.3

Programación Orientada a Objetos

3

Unidad III: Datos Simples

3.1 Variables ..................................................................................................................... 31

3.1.1 Reglas para asignar nombres de variables .................................................................. 31

3.1.2 Tipos de identificadores .............................................................................................. 32

3.2 Tipos de datos ............................................................................................................. 32

3.3 Expresiones, operadores y asignaciones ..................................................................... 33

3.3.1 Operadores aritméticos................................................................................................ 34

3.3.2 Expresiones y operadores relacionales........................................................................ 35

3.3.3 Expresiones y operadores lógicos ............................................................................... 35

3.3.4 Operadores incrementales y decrementales ................................................................ 36

3.3.5 Operadores compuestos de asignación........................................................................ 36

3.3.6 Operador condicional .................................................................................................. 37

3.3.7 Precedencia de operadores .......................................................................................... 37

3.4 Ejercicios propuestos .................................................................................................. 39

Unidad IV: Estructuras de control

4.1 Estructuras de control selectivas ................................................................................. 40

4.1.1 La estructura de selección simple: if ........................................................................... 40

4.1.2 La estructura de selección doble: if/else ..................................................................... 41

4.1.3 La estructura de selección múltiple: switch/case ........................................................ 47

4.2 Estructuras de control iterativas .................................................................................. 48

4.2.1 La estructura iterativa for ............................................................................................ 49

4.2.2 La estructura iterativa while ........................................................................................ 51

4.2.3 La estructura iterativa do-while .................................................................................. 53

4.2.4 Sentencias break y continue ........................................................................................ 54

4.3 Ejercicios propuestos: ................................................................................................. 55

Unidad V: Datos compuestos

5.1 Arreglos ....................................................................................................................... 57

5.1.1 Arreglo unidimensional ............................................................................................... 57

5.1.2 Arreglos anidados........................................................................................................ 63

Page 4: PROGRAMACIÓN ORIENTADA A OBJETOS (072-2103) · PROGRAMACIÓN ORIENTADA A OBJETOS (072-2103) Unidad I: Introducción 1.1 Historia del Computador 1.2 Lenguajes de Programación 1.3

Programación Orientada a Objetos

4

5.1.3 Arreglos multidimensionales ...................................................................................... 64

5.1.4 La clase System.array.................................................................................................. 67

5.2 Cadenas ....................................................................................................................... 68

5.2.1 Operadores de igualdad y concatenación .................................................................... 69

5.2.2 Métodos de manejo de cadenas ................................................................................... 70

5.3 Estructuras y Enumeraciones ...................................................................................... 72

5.3.1 Estructuras ................................................................................................................... 72

5.3.2 Enumeraciones ............................................................................................................ 74

5.4 Ejercicios propuestos .................................................................................................. 75

Unidad VI: Fundamentos avanzados de programación

6.1 Propiedades de uso, modificadores de parámetros y regiones .................................... 77

6.1.1 Propiedades de uso: get y set ...................................................................................... 77

6.1.2 Modificadores de parámetros: ref, in y out ................................................................. 79

6.1.3 Regiones ...................................................................................................................... 83

6.2 Recursividad ................................................................................................................ 84

6.3 Referencias internas .................................................................................................... 89

6.3.1 Clases autoreferenciadas ............................................................................................. 92

6.3.2 Código inseguro y apuntadores ................................................................................... 93

6.4 Herencia ...................................................................................................................... 95

6.5 Interfaces ..................................................................................................................... 97

6.6 Ejercicios propuestos .................................................................................................. 99

Page 5: PROGRAMACIÓN ORIENTADA A OBJETOS (072-2103) · PROGRAMACIÓN ORIENTADA A OBJETOS (072-2103) Unidad I: Introducción 1.1 Historia del Computador 1.2 Lenguajes de Programación 1.3

Programación Orientada a Objetos

5

UNIDAD I: INTRODUCCIÓN

1.1 Historia de la computación

1.1.1 La computadora

Es una colección de circuitos integrados y otros componentes relacionados capaz de efectuar

una secuencia de operaciones mediante un programa, de tal manera que recibe y procesa un

conjunto de datos de entrada para convertirlos en información útil.

1.1.2 Prehistoria de la computación

Uno de los primeros dispositivos mecánicos para contar fue el ábaco, cuya historia se

remonta a las antiguas civilizaciones griega y romana, el cual tenía cuentas ensartadas en

varillas que, a su vez, estaban montadas en un marco rectangular. Al desplazar las cuentas

sobre las varillas, sus posiciones representaban valores determinados. Por supuesto, este

dispositivo no podía considerarse como una computadora, ya que carecía de un elemento

fundamental llamado programa.

Otros dispositivos mecánicos fueron la Pascalina, inventada por el francés Blaise

Pascal (1623 – 1662), y la máquina inventada por el alemán Gottfried Wilhelm Von Leibniz

(1646 – 1716), con las cuales los datos se representaban mediante las posiciones de los

engranajes, y los mismos se introducían manualmente estableciendo las posiciones finales de

la rueda, de forma similar a cómo se cuentan los kilómetros recorridos en el cuentakilómetros

de un automóvil.

En el siglo XIX Charles Babbage trabajaba en el proyecto de la “máquina de

diferencias”, es decir, aquella que realizaba una serie de sumas sucesivas, con la cual buscaba

solucionar el problema que implica la elaboración de tablas matemáticas ya que era una tarea

tediosa y propensa a errores. Sin embargo, en el año 1823 Charles Jaquard había inventado

un telar que podía reproducir patrones de tejidos leyendo la información codificada en

Page 6: PROGRAMACIÓN ORIENTADA A OBJETOS (072-2103) · PROGRAMACIÓN ORIENTADA A OBJETOS (072-2103) Unidad I: Introducción 1.1 Historia del Computador 1.2 Lenguajes de Programación 1.3

Programación Orientada a Objetos

6

patrones de agujeros perforados en papel rígido. Esto sirvió de inspiración a Babbage para

que abandonase la máquina de diferencias y se dedicase a la “máquina analítica”, un

dispositivo que podría ser programado con tarjetas perforadas para efectuar cálculos con una

precisión de hasta 20 dígitos. Desafortunadamente, la tecnología de la época no bastaba para

hacer realidad sus ideas.

Unos 100 años después, concretamente en el año 1944, se construyó en la Universidad

de Harvard la MARK I, diseñada por un equipo encabezado por Howard E. Aiken, cuyo

funcionamiento estaba basado en dispositivos electromecánicos llamados relevadores.

En 1947 se construyó en la Universidad de Pensilvania la ENIAC (Electronic

Numerical Integrator And Calculator) por el equipo de diseño dirigido por John Mauchly y

John Eckert, la cual ocupaba todo un sótano de la universidad, tenía más de 18 mil tubos de

vacío, consumía 200 KW de energía y requería todo un sistema de aire acondicionado, la

cual tenía capacidad para realizar 5 mil operaciones aritméticas por segundo. Esta máquina

marcó el inicio de las generaciones de la computadora.

1.1.3 Generaciones de la computadora

Se definen tomando en cuenta la forma en que fueron construidas, y la manera en que el ser

humano se comunica con ellas, además de las tecnologías empleadas.

1ª Generación: Tubos de Vacío (1947 – 1958)

• Utilizaban tubos de vacío para procesar la información.

• Empleaban tarjetas perforadas para realizar programas.

• La memoria principal consistía en un tambor magnético.

• Eran de un inmenso tamaño y gran peso.

• Costaban alrededor de US$ 10.000

• Surge el lenguaje máquina (código binario)

• Máquinas representativas: ENIAC y UNIVAC.

Page 7: PROGRAMACIÓN ORIENTADA A OBJETOS (072-2103) · PROGRAMACIÓN ORIENTADA A OBJETOS (072-2103) Unidad I: Introducción 1.1 Historia del Computador 1.2 Lenguajes de Programación 1.3

Programación Orientada a Objetos

7

2ª Generación: Transistores (1958 – 1964)

• Uso de transistores para procesar la información.

• Reducción del tamaño y emisión de calor.

• Menor consumo eléctrico.

• Eran comercialmente accesibles.

• Las computadoras de ese período eran muy avanzadas para la época.

• Se define la programación de sistemas.

• Máquinas representativas: PHILCO 212 y UNIVAC M460.

3ª Generación: Circuitos Integrados (1964 – 1971)

• Uso de circuitos integrados (inventados en 1959) para procesar la información.

• Las computadoras son mucho más pequeñas y producen menos calor.

• Son enérgicamente más eficientes.

• Surge la multiprogramación.

• Máquina representativa: IBM 360.

4ª Generación: Microprocesadores (1971 – 1981)

• Uso del microprocesador (inventado en 1971) para procesar información.

• Desarrollo de las microcomputadoras y supercomputadoras.

• Reemplazo de las memorias con núcleos magnéticos por chips de silicio.

• Uso de los Sistemas Operativos.

5ª Generación: Inteligencia Artificial (1981 – 1990)

• Avances en el desarrollo del software y la robótica.

• Se crea la primera súper computadora con capacidad de proceso en paralelo.

• Desarrollo de sistemas expertos e inteligencia artificial.

• Uso del lenguaje natural.

• Almacenamiento en dispositivos magnético-ópticos extraíbles.

Page 8: PROGRAMACIÓN ORIENTADA A OBJETOS (072-2103) · PROGRAMACIÓN ORIENTADA A OBJETOS (072-2103) Unidad I: Introducción 1.1 Historia del Computador 1.2 Lenguajes de Programación 1.3

Programación Orientada a Objetos

8

6ª Generación: Arquitectura Paralelo/Vectorial (1990 – 1999)

• Utilizan cientos de microprocesadores vectoriales trabajando en paralelo.

• Se crearon computadoras capaces de realizar millones de operaciones aritméticas en

punto flotante (teraflops) por segundo.

• Uso de las redes WWW y WAN para comunicar las computadoras entre sí.

• Uso de fibra óptica con gran ancho de banda y satélites para las comunicaciones.

• Desarrollo de tecnologías con inteligencia artificial distribuida, teoría de caos, holografía,

transistores ópticos, etc.

7ª Generación: LCD y Dispositivos Inteligentes (1999 – 2011)

• Aparecen las pantallas planas LCD2 y se hacen a un lado las de rayos catódicos.

• Se crea el Blu-Ray Disc, reemplazando al DVD.

• Almacenamiento de datos de alta densidad.

• Reemplazo de TV’s y equipos de sonido por dispositivos digitales.

• Aparecen las computadoras portátiles (laptops), dispositivos de bolsillo (PDA’s),

computadoras ópticas y cuánticas.

• Uso masivo de mensajería y correo electrónico.

• Tecnología de reconocimiento de voz y escritura, además de la realidad virtual y

dispositivos inalámbricos.

• Súper cómputo (procesadores paralelos masivos).

• Proliferación de los Smartphone y memorias compactas.

8ª Generación: Nuevas Tecnologías (2011 – Presente)

• Se inicia con el lanzamiento del Nintendo 3DS (25 de febrero de 2011), seguido por la

Sony PlayStation Vita (17 de diciembre de 2011).

• Empleo de tecnologías de última generación, como la estereoscopía y detección del

movimiento corporal.

• Mayor capacidad de almacenamiento en los dispositivos móviles.

• A futuro se plantea la desaparición de dispositivos físicos y de almacenamiento

mecánicos (disco duro, tarjeta madre), además del uso de la nanotecnología.

Page 9: PROGRAMACIÓN ORIENTADA A OBJETOS (072-2103) · PROGRAMACIÓN ORIENTADA A OBJETOS (072-2103) Unidad I: Introducción 1.1 Historia del Computador 1.2 Lenguajes de Programación 1.3

Programación Orientada a Objetos

9

1.2 Lenguajes de programación

Un programa es una secuencia de instrucciones mediante las cuales se ejecutan diferentes

acciones de acuerdo con los datos que se estén procesando, el cual está desarrollado para ser

utilizado por la computadora.

Por su parte, la programación es el proceso de diseñar, escribir, probar, depurar y

mantener el código fuente de programas computacionales. El código fuente es escrito en un

lenguaje de programación. El propósito de la programación es crear programas que exhiban

un comportamiento deseado. El proceso de escribir código requiere frecuentemente

conocimientos en varias áreas distintas, además del dominio del lenguaje a utilizar,

algoritmos especializados y lógica formal.

Programar no involucra necesariamente otras tareas tales como el análisis y diseño de

la aplicación (pero si el diseño del código), aunque si suelen estar fusionadas en el desarrollo

de pequeñas aplicaciones.

Obviamente, para llevar a cabo esta tarea se requiere de un lenguaje de programación,

el cual no es más que un sistema de símbolos y reglas que permite la construcción de

programas con los que la computadora puede operar así como resolver problemas de manera

eficaz. Estos contienen un conjunto de instrucciones que permiten realizar operaciones de

entrada / salida, calculo, manipulación de textos, lógica / comparación y almacenamiento /

recuperación.

1.2.1 Tipos de lenguajes

• Lenguaje Máquina: Son aquellos cuyas instrucciones son directamente entendibles por

la computadora y no necesitan traducción posterior para que la CPU pueda comprender

y ejecutar el programa. Las instrucciones en lenguaje maquina se expresan en términos

de la unidad de memoria más pequeña el bit (dígito binario 0 ó 1).

Page 10: PROGRAMACIÓN ORIENTADA A OBJETOS (072-2103) · PROGRAMACIÓN ORIENTADA A OBJETOS (072-2103) Unidad I: Introducción 1.1 Historia del Computador 1.2 Lenguajes de Programación 1.3

Programación Orientada a Objetos

10

• Lenguaje de Bajo Nivel (Ensamblador): En este lenguaje las instrucciones se escriben

en códigos alfabéticos conocidos como mnemotécnicos para las operaciones y

direcciones simbólicas. Los lenguajes de bajo nivel permiten crear programas muy

rápidos, pero que a menudo son difíciles de entender. Más importante es el hecho de que

los programas escritos en bajo nivel son prácticamente específicos para cada procesador.

• Lenguaje de Alto Nivel: Los lenguajes de programación de alto nivel (BASIC, pascal,

cobol, fortran, etc.) son aquellos en los que las instrucciones o sentencias a la

computadora son escritas con palabras similares a los lenguajes humanos (en general en

inglés), lo que facilita la escritura y comprensión del programa. Éstos son normalmente

fáciles de aprender porque están formados por objetos de lenguajes naturales, sin

embargo, para muchas personas esta forma de trabajar es un poco frustrante dado que, en

realidad, las computadoras suelen operar de forma rígida y sistemática.

1.2.2 Criterios del lenguaje

Son características interrelacionadas empleadas para considerar si un lenguaje tiene méritos,

es decir, si es eficiente, confiable y es capaz de proporcionar los mejores resultados.

• Sintaxis: Es la forma del lenguaje, es decir, una colección de instrucciones formadas al

seguir un conjunto de reglas que diferencian los programas válidos de nos no válidos.

• Semántica: Describe de manera precisa lo que significa una construcción particular, ya

que cada lenguaje de programación podría interpretar de manera distinta las instrucciones

escritas exactamente igual.

• Comprobabilidad:

o El programa cumple con la intención del programador.

o El compilador traduce de manera correcta a código de máquina la sintaxis y

semántica del programa en el lenguaje empleado.

o La máquina misma funciona correctamente.

Page 11: PROGRAMACIÓN ORIENTADA A OBJETOS (072-2103) · PROGRAMACIÓN ORIENTADA A OBJETOS (072-2103) Unidad I: Introducción 1.1 Historia del Computador 1.2 Lenguajes de Programación 1.3

Programación Orientada a Objetos

11

• Confiabilidad: El programa se considera confiable si se comporta como es anunciado y

produce los resultados que el usuario espera.

• Traducción Rápida: La traducción del código fuente a un lenguaje que la máquina

pueda reconocer, y luego a un código máquina que la misma pueda ejecutar, debe ser lo

más rápida y óptima posible.

• Corrección: Un programa es correcto si hace lo que debe hacer tal y como se estableció

en las fases previas a su desarrollo.

• Claridad: Es muy importante que el programa sea lo más claro y legible posible, para

facilitar así su desarrollo y posterior mantenimiento. Al elaborar un programa, se debe

intentar que su estructura sea sencilla y coherente, así como cuidar el estilo de la edición.

• Eficiencia: Se trata de que el programa, además de realizar aquello para lo que fue

creado, lo haga gestionando de la mejor forma los recursos que utiliza, para lo cual es

necesario que exista un balance comparativo entre el trabajo que el programador debe

hacer y el trabajo que el compilador puede hacer.

• Ortogonalidad: Las variables aleatorias se consideran ortogonales si son independientes

entre sí. De esta forma los componentes son independientes entre sí y se comportan de la

misma manera bajo cualquier circunstancia.

• Portabilidad: Cuando el programa puede compilarse y ejecutarse en una plataforma

(Hardware o Software) diferente a aquella en la cual se elaboró.

1.3 Compilación de programas

Un compilador es un programa que permite traducir el código fuente (conjunto de

instrucciones que describe el funcionamiento de un programa determinado), realizado en

lenguaje de alto nivel, a otro de nivel inferior (típicamente a lenguaje máquina). De esta

Page 12: PROGRAMACIÓN ORIENTADA A OBJETOS (072-2103) · PROGRAMACIÓN ORIENTADA A OBJETOS (072-2103) Unidad I: Introducción 1.1 Historia del Computador 1.2 Lenguajes de Programación 1.3

Programación Orientada a Objetos

12

manera, un programador puede diseñar un programa en un lenguaje mucho más cercano a

cómo piensa un ser humano, para luego compilarlo a un programa más manejable por una

computadora.

1.3.1 Tipos de compiladores

• Cruzados: Generan código para un sistema distinto del que están funcionando.

• Optimizadores: Realizan cambios en el código para mejorar su eficiencia, manteniendo

la funcionalidad del programa original.

• De una sola pasada: Generan el código máquina a partir de una única lectura del código

fuente.

• De varias pasadas: Necesitan leer el código fuente varias veces antes de poder producir

el código máquina.

• JIT (Just In Time): Forma parte de un intérprete y compilan muestras del código según

sus necesidades.

1.3.2 Proceso de compilación

Normalmente, la creación de un programa ejecutable conlleva dos pasos:

• Compilación: Traduce el código fuente escrito en un lenguaje de alto nivel a bajo nivel,

creando un código objeto que puede ser en lenguaje máquina o bytecode (es más

abstracto que el código máquina) y distribuirse en varios ficheros.

• Enlazado: Se enlaza el código de bajo nivel generado de todos los ficheros y

subprogramas que se han mandado a compilar, y se añade el código de las funciones que

hay en las bibliotecas del compilador, traduciendo así el código objeto a lenguaje

máquina, generando un módulo ejecutable.

Page 13: PROGRAMACIÓN ORIENTADA A OBJETOS (072-2103) · PROGRAMACIÓN ORIENTADA A OBJETOS (072-2103) Unidad I: Introducción 1.1 Historia del Computador 1.2 Lenguajes de Programación 1.3

Programación Orientada a Objetos

13

1.3.3 Etapas de la compilación

• Fase de Análisis:

o Análisis Léxico: Se lee el programa fuente de izquierda a derecha y se agrupa en

componentes léxicos llamados tokens (secuencias de caracteres que tienen un

significado determinado).

o Análisis Sintáctico: Los tokens se agrupan jerárquicamente en frases

gramaticales que el compilador utiliza para sintetizar la salida.

o Análisis Semántico: Se revisa el programa fuente para tratar de encontrar errores

semánticos, reuniendo la información sobre los tipos para la fase posterior de

generación de código.

• Fase de Síntesis: Consiste en generar el código objeto equivalente al programa fuente, y

sólo se realiza esta acción cuando el programa fuente está libre de errores de análisis

(aunque esto no implica que el programa corra bien).

o Generación de código intermedio: Algunos compiladores generan una

representación intermedia explícita del programa fuente, el cual debe ser fácil de

producir y fácil de traducir al programa objeto.

• Fase de Optimización del Código: Mejora el código intermedio, de modo que resulte

un código máquina más rápido de ejecutar.

1.3.4 Otras herramientas de programación

Además del compilador, existen otras herramientas de programación con funciones muy

similares, las cuales son:

• Ensamblador: Traduce un fichero fuente en lenguaje ensamblador (bajo nivel) a código

máquina.

• Enlazador: Toma los objetos generados en los primeros pasos de compilación y la

información de biblioteca, (salvo lo que no necesita), y crea un archivo ejecutable.

Page 14: PROGRAMACIÓN ORIENTADA A OBJETOS (072-2103) · PROGRAMACIÓN ORIENTADA A OBJETOS (072-2103) Unidad I: Introducción 1.1 Historia del Computador 1.2 Lenguajes de Programación 1.3

Programación Orientada a Objetos

14

• Intérprete: Es un programa informático capaz de analizar y ejecutar otros programas. Se

diferencia del compilador en que, mientras éste traduce un programa desde su descripción

en un lenguaje de programación al código máquina, los intérpretes sólo la traducción a

medida que sea necesaria, típicamente, instrucción por instrucción, por lo que

normalmente no guardan los resultados de dicha traducción, lo que los hace mucho más

lentos, pero a su vez menos susceptibles de provocar fallos.

1.4 Paradigmas de programación

Son colecciones de características abstractas que categorizan un grupo de lenguajes que son

aceptados y utilizados por un grupo de profesionales, representando un enfoque particular o

filosofía para diseñar soluciones. Éstos están delimitados en el tiempo en cuanto a aceptación

y uso, ya que nuevos paradigmas aportan nuevas o mejores soluciones que los sustituyen

parcial o totalmente.

Algunos tipos de paradigmas conocidos en la actualidad son:

• Imperativos: Facilitan cálculos por medio de cambios de estados, pues se basan en dar

instrucciones al ordenador de cómo hacer las cosas en forma de algoritmo. El ejemplo

principal de este tipo de paradigmas es el lenguaje de máquina.

• De Procedimientos: Constituidos por bloques de programas (secciones de código con

una o más declaraciones y sentencias), que forman un archivo plano, en donde cada

bloque sigue a su predecesor, constituyéndose así un programa lineal. Ejemplo:

FORTRAN.

• Estructurados en Bloques: Están constituidos por ámbitos anidados, es decir, los

bloques pueden estar dentro de otros bloques e incluso tener sus propias variables.

Ejemplo: Basic, Pascal, C.

• Basados en Objetos: Describen a los lenguajes que soportan objetos en interacción,

además de la abstracción, encapsulación y polimorfismo. Ejemplo: ADA, Modula,

SmallTalk.

Page 15: PROGRAMACIÓN ORIENTADA A OBJETOS (072-2103) · PROGRAMACIÓN ORIENTADA A OBJETOS (072-2103) Unidad I: Introducción 1.1 Historia del Computador 1.2 Lenguajes de Programación 1.3

Programación Orientada a Objetos

15

• Orientados a Objetos: Incluyen a los lenguajes que están basados en objetos y, además,

soportan clases de objetos y herencia de atributos. Ejemplo: C++, C#, Object Pascal

(Delphi) y Java.

• De Procedimiento en Paralelo: Describen los lenguajes que soportan el uso de

procesadores múltiples, la cooperación entre procesos y el potencial para falla parcial

(esto último implica que algún proceso puede fallar sin peligrar la ejecución de los

demás). Ejemplo: Concurrent C, Pascal S, C-Linda.

• De Programación Lógica: Están basados en un subconjunto del cálculo de predicados

o relación de elementos, proporcionando axiomas y reglas de inferencia que permiten

inferir nuevos hechos a partir de hechos conocidos. Ejemplo: Prolog.

• Funcionales: Es cuando el lenguaje opera solamente a través de funciones. Ejemplo:

Scheme y Haskell.

• Declarativos: Se basan en el desarrollo de programas declarando propiedades y reglas

que deben cumplirse, en lugar de instrucciones. Ejemplo: Maude y ML.

• Dirigidos por Eventos: Tanto la estructura como la ejecución de los programas son

determinados por los sucesos que ocurran en el sistema, ya sean definidos por el usuario

o provocados por ellos mismos. Ejemplo: Lexico y Visual Basic.

• Específicos del Dominio: Conocidos como DSL, se denomina así a los lenguajes

desarrollados para resolver un problema en específico. Puede pertenecer a cualquiera de

los paradigmas antes descritos. Ejemplo: SQL (declarativo) y LOGO (imperativo).

• Multiparadigma: Es el uso de dos o más paradigmas dentro de un programa. Ejemplo:

Lisp y Python.

Page 16: PROGRAMACIÓN ORIENTADA A OBJETOS (072-2103) · PROGRAMACIÓN ORIENTADA A OBJETOS (072-2103) Unidad I: Introducción 1.1 Historia del Computador 1.2 Lenguajes de Programación 1.3

Programación Orientada a Objetos

16

UNIDAD II: PARADIGMA ORIENTADO A OBJETOS

2.1 Generalidades

La programación orientada a objetos ha tomado las mejores ideas de la programación

estructurada y los ha combinado con varios conceptos nuevos y potentes que incitan a

contemplar las tareas de programación desde un nuevo punto de vista.

El término Programación Orientada a Objetos (POO), hoy en día ampliamente

utilizado, es difícil de definir debido a que no es un concepto nuevo, sino que ha sido el

desarrollo de técnicas de programación desde principios de la década de los 70’s, cuando ha

aumentado su difusión, uso y popularidad. No obstante, se puede definir como una técnica o

estilo de programación que utiliza objetos como bloque especial de construcción.

2.1.1 Conceptos dentro de la POO

• Objeto: Entidad de programa que consiste en datos, y todos aquellos procedimientos que

pueden manipularlos.

• Clase: Colección de objetos que poseen características comunes, la cual contiene toda la

información necesaria para crear nuevos objetos. En otras palabras, se definen las

características concretas de un determinado tipo de objetos, es decir, de cuáles son los

datos y los métodos de los que van a disponer todas las instancias de ese tipo.

• Encapsulación: Técnica que permite localizar y ocultar los detalles de un objeto,

previniendo que el mismo sea manipulado por operaciones distintas de las definidas. Ésta

se puede comparar con el funcionamiento de una caja negra.

• Abstracción: Representación concisa de una idea u objeto complicado, localizando y

ocultando los detalles de un modelo o diseño para generar y manipular objetos.

• Polimorfismo: Se refiere al hecho de que un nombre se puede utilizar para especificar

una clase genérica de acciones.

• Herencia: Proceso mediante el cual un objeto (hijo) puede adquirir las propiedades de

otro objeto (padre).

Page 17: PROGRAMACIÓN ORIENTADA A OBJETOS (072-2103) · PROGRAMACIÓN ORIENTADA A OBJETOS (072-2103) Unidad I: Introducción 1.1 Historia del Computador 1.2 Lenguajes de Programación 1.3

Programación Orientada a Objetos

17

2.1.2 Ventajas

• Uniformidad: La representación de los objetos implica tanto el análisis como el diseño

y la codificación de los mismos.

• Comprensión: Los datos y los procedimientos que los manipulan se pueden agrupar en

clases.

• Flexibilidad: Cualquier cambio en los datos (o sus respectivas funciones) quedará

reflejado automáticamente en cualquier lugar donde éstos aparezcan.

• Estabilidad: Permite aislar las partes del programa que permanecen inalterables con el

tiempo.

• Reusabilidad: Se pueden reutilizar las definiciones de objetos empleadas en otros

programas, o incluso los procedimientos que los manipulan.

2.2 Clases y objetos

Una clase es un tipo definido por el usuario que determina la estructura de los datos y las

operaciones asociadas a este tipo, es decir, son modelos o plantillas que describen cómo se

construyen ciertos tipos de objetos.

La sintaxis básica para definir una clase es la mostrada a continuación:

class nombre_clase {

miembros;

}

Donde los miembros son datos y funciones pertenecientes a la clase definida, las cuales

están a disposición de todos los objetos o instancias de la misma. Obviamente hay muchos

tipos de miembros distintos, pero por ahora sólo se considerarán los siguientes:

• Campo o Atributo: Es un dato común a todos los objetos de una determinada clase. Su

sintaxis es como sigue: <modificador_de_acceso> tipo_de_campo nombre_campo;

Page 18: PROGRAMACIÓN ORIENTADA A OBJETOS (072-2103) · PROGRAMACIÓN ORIENTADA A OBJETOS (072-2103) Unidad I: Introducción 1.1 Historia del Computador 1.2 Lenguajes de Programación 1.3

Programación Orientada a Objetos

18

o <modificador_de_acceso>: Es una palabra reservada que permite restringir el

acceso a un atributo o método de un objeto en particular, es decir, que con ella se

decide si un miembro perteneciente a una clase puede ser visto o no desde

cualquier punto del programa. Puede ser:

▪ Private: Implica que sólo permite el acceso a los miembros de la clase

donde está definido. En caso de omitirse el modificador de acceso, el

miembro es private por defecto.

▪ Protected: Sólo tienen acceso la clase donde está definido y sus

herederas.

▪ Public: Se puede acceder desde cualquier parte del programa.

o tipo_de_campo: Establece el tipo de formato (o categoría) del dato. Puede ser

definido dentro del sistema (int, float, string, etc.) o por el usuario.

• Método: Es un conjunto de instrucciones a las que se les asocia un nombre, con las cuales

se manipulan los datos asociados a la clase. Su sintaxis es como sigue:

<modificador_de_acceso> <tipo_de_retorno> nombre_método(parámetros) {

sentencias;

}

o tipo_de_retorno: Es el tipo del dato u objeto que se devuelve como resultado de

la ejecución de las sentencias (instrucciones) pertenecientes a dicho método: Si

no se indica nada, el retorno es de tipo void (vacío), y si se devuelve algo, se debe

terminar la ejecución de las sentencias con la instrucción return <objeto>

o parámetros: Son los objetos o atributos que recibe el método al ser invocado,

especificando allí el tipo de dato y el nombre con el que se referencia de manera

interna. Si no se recibe nada, sólo se colocan los paréntesis, asumiendo que los

parámetros son de tipo void.

Ejemplo 2.1: Cree una clase llamada empleado, cuyos atributos son nombre, edad,

departamento y salario. Incluya los métodos necesarios para agregar un empleado y

visualizar sus datos.

Page 19: PROGRAMACIÓN ORIENTADA A OBJETOS (072-2103) · PROGRAMACIÓN ORIENTADA A OBJETOS (072-2103) Unidad I: Introducción 1.1 Historia del Computador 1.2 Lenguajes de Programación 1.3

Programación Orientada a Objetos

19

En este ejemplo, se agregan además de los atributos señalados, un método que reciba

los datos, y otro para visualizarlos, quedando de la siguiente manera:

class empleado {

private string nombre, dpto;

private int edad;

private float salario;

public void agregar_datos() {

//Sentencias para agregar datos

}

public void mostrar_datos() {

//Sentencias para mostrar datos

}

}

Como se pudo observar en el ejemplo, los atributos o campos son private, mientras

ambos métodos son de tipo public, lo que indica que estos últimos podrán ser vistos desde

cualquier parte del programa. Esto es así debido al principio de encapsulación, ya que de

esta manera se puede proteger la información interno, evitando así una errónea manipulación

de los datos en cualquier parte del programa, Por supuesto se pueden usar otros

modificadores, con funciones privadas y atributos públicos, pero esta manera es la más

recomendada (sobre todo para los principiantes).

2.2.1 Acceso a los miembros de una clase

Ejemplo 2.2: Tratar de cargar los datos del empleado, usando el método definido en el

ejemplo anterior.

Aquí hay que llamar al método “cargar_datos”, el cual ha sido definido como public,

lo que indica que puede ser visto por el método Main (éste es el método principal, que se

encarga de ejecutar el programa). Obsérvese el siguiente código:

class Program {

static void Main(string[] args) {

cargar_datos();

}

}

Page 20: PROGRAMACIÓN ORIENTADA A OBJETOS (072-2103) · PROGRAMACIÓN ORIENTADA A OBJETOS (072-2103) Unidad I: Introducción 1.1 Historia del Computador 1.2 Lenguajes de Programación 1.3

Programación Orientada a Objetos

20

En este caso el programa da error, ya que “cargar_datos”, aun siendo visible en

cualquier parte del programa, no está definido dentro del método Main, sino dentro de la

clase empleado, lo que indica que hace falta algo para acceder a dicho método, un enlace

entre ambas clases. Por lo tanto… ¿Cómo se accede a un método de la clase? La respuesta:

Declarar un objeto.

Como se ha dicho, los objetos son instancias de una clase, es decir, cada objeto definido

trabaja con los mismos atributos y posee los mismos métodos de la clase a la que pertenece,

Éste se declara de la siguiente manera:

nombre_clase nombre_objeto = new nombre_clase();

Donde nombre_clase hace referencia a la clase definida por el usuario, es decir, es el

“tipo de dato” del objeto; new es un operador que reserva espacio de memoria para almacenar

un objeto de tipo clase, y nombre_clase( ) es el constructor, es decir, un método especial que

se encarga de inicializar dicho objeto.

Ejemplo 2.3: Cree un objeto de tipo empleado.

class Program {

static void Main(string[] args) {

empleado e = new empleado();

}

}

Con esto se ha creado un objeto llamado “e” el cual tiene todas las características de la

clase a la cual instancia (empleado), es decir, posee la capacidad de almacenar dentro de sí

un nombre de empleado, el departamento al cual pertenece, su edad y su salario, además de

tener la capacidad de invocar métodos para la carga e impresión de dichos datos.

Pero sigue la pregunta… ¿Cómo acceder a los miembros de una clase? Ahora que se

tiene el objeto definido, la manera de acceder a los mismos se realiza utilizando la siguiente

sintaxis:

nombre_objeto.miembro

Page 21: PROGRAMACIÓN ORIENTADA A OBJETOS (072-2103) · PROGRAMACIÓN ORIENTADA A OBJETOS (072-2103) Unidad I: Introducción 1.1 Historia del Computador 1.2 Lenguajes de Programación 1.3

Programación Orientada a Objetos

21

Aquí, el operador “.” (Punto) se utiliza como operador de acceso a los miembros de

una clase, los cuales pueden ser atributos o métodos, siempre y cuando su nivel de acceso lo

permita, es decir, este método no funciona, por ejemplo, para miembros de tipo private

porque se generaría un error, ya que el acceso a los mismos está restringido sólo y

exclusivamente para la clase donde son definidos.

A raíz de lo anteriormente dicho, para resolver el problema planteado en el Ejemplo 2

se procede de la siguiente manera:

class Program {

static void Main(string[] args) {

empleado e = new empleado();

e.cargar_datos();

}

}

2.2.2 Constructores y destructores

Como se mencionó, el constructor se trata de un método especial, cuya principal

característica es que tiene el mismo nombre de la clase. Se define de forma similar a un

método cualquiera, salvo que a éste se le omite el tipo de retorno (de hecho, muchos autores

ni siquiera emplean la palabra void). En cuanto a su acceso, aunque pueden ser private o

protected, éstos se recomiendan que sean de tipo public (por defecto).

Cuando el usuario no define ningún constructor, se emplea el constructor por defecto,

definido dentro del sistema con las operaciones básicas que éste necesita para la construcción

de cualquier objeto. Sin embargo, si el usuario define al menos un constructor, cada vez que

se crea el objeto su constructor debe coincidir con lo que definió dicho usuario.

Además de los constructores, también se tienen los destructores, los cuales se utilizan

para realizar ciertas operaciones que son necesarias cuando ya no se utiliza un objeto. Su

definición es similar a la de un constructor, sólo que se coloca el carácter “~” (virgulilla)

antes del nombre. Su uso es poco frecuente, y cuando no se define se suele utilizar un

destructor por defecto que se encarga de liberar el espacio en memoria.

Page 22: PROGRAMACIÓN ORIENTADA A OBJETOS (072-2103) · PROGRAMACIÓN ORIENTADA A OBJETOS (072-2103) Unidad I: Introducción 1.1 Historia del Computador 1.2 Lenguajes de Programación 1.3

Programación Orientada a Objetos

22

Ejemplo 2.4: Incluya un constructor y un destructor para la clase empleado.

class empleado {

//Atributos y métodos internos

public empleado() {

//Sentencias para construir el objeto

}

public ~empleado() {

//Sentencias para destruir el objeto

}

}

Ejemplo 2.5: Desarrolle un proyecto que posea una clase llamada empleado, cuyos atributos

son los siguientes: nombre, edad, departamento y salario; y posea los métodos necesarios

para agregar un nuevo empleado y mostrar sus datos.

Compilando todo lo desarrollado en los ejemplos anteriores, el programa queda de la

siguiente manera:

class empleado {

private string nombre, dpto;

private int edad;

private float salario;

public void agregar_datos() {

//Sentencias para agregar datos

}

public void mostrar_datos() {

//Sentencias para mostrar datos

}

public empleado() {

//Sentencias para construir el objeto

}

}

class Program {

static void Main(string[] args) {

empleado e = new empleado();

e.cargar_datos();

e.mostrar_datos();

}

}

Page 23: PROGRAMACIÓN ORIENTADA A OBJETOS (072-2103) · PROGRAMACIÓN ORIENTADA A OBJETOS (072-2103) Unidad I: Introducción 1.1 Historia del Computador 1.2 Lenguajes de Programación 1.3

Programación Orientada a Objetos

23

2.2.3 Ventajas del uso de clases

El programa del Ejemplo 5 muestra la misma salida que uno donde se trabaje sólo con el

método Main, así:

class Program {

static void Main(string[] args) {

string nombre, dpto;

int edad;

float salario;

// Instrucciones para cargar datos del empleado

// Instrucciones para mostrar datos del empleado

}

}

Ahora, imagínese por un momento que se desean cargar los datos de 3 empleados. Se

podría realizar con un ciclo, pero en este caso los datos no serían reutilizables, ya que los

mismos se reemplazarían en cada iteración (lo que impediría su uso en sentencias

posteriores); y si se hace de manera lineal resulta tedioso, puesto que se estarían declarando

muchas variables, con sus instrucciones de entrada y salida correspondientes, eso sin

mencionar que, al tener que escribir mucho código, se está más propenso a cometer errores.

En cambio, si la clase está adecuadamente definida, sólo harían falta 3 objetos, y pocas líneas

de código para llamar a los métodos correspondientes:

class Program {

static void Main(string[] args) {

empleado a = new empleado();

empleado b = new empleado();

empleado c = new empleado();

// Cargar datos de 3 empleados

a.cargar_datos();

b.cargar_datos();

c.cargar_datos();

// Mostrar datos de 3 empleados

a.mostrar_datos();

b.mostrar_datos();

c.mostrar_datos();

}

}

Page 24: PROGRAMACIÓN ORIENTADA A OBJETOS (072-2103) · PROGRAMACIÓN ORIENTADA A OBJETOS (072-2103) Unidad I: Introducción 1.1 Historia del Computador 1.2 Lenguajes de Programación 1.3

Programación Orientada a Objetos

24

2.3 Programación en consola

La consola es una ventana del Sistema Operativo en la cual los usuarios interactúan con el

S.O., o con una aplicación de consola basada en texto. Este tipo de aplicaciones utilizan como

entrada y salida líneas de comandos, lo que permite probar rápidamente las características

del lenguaje y escribir utilidades en modo carácter.

2.3.1 Buffer de pantalla y ventana de la consola

La consola posee dos características que están estrechamente relacionadas entre sí:

• Buffer de Pantalla: Atributo de la consola que está organizado como una cuadrícula

rectangular de filas y columnas. Cada intersección (llamada celda de carácter) puede

contener un carácter. Cada carácter tiene su propio color de primer plano y cada celda de

carácter tiene su propio color de fondo.

• Ventana de Consola: Es otro atributo de la consola, una ventana del Sistema Operativo

que también está organizada en filas y columnas. Su tamaño es menor o igual al Buffer

de Pantalla, se puede mover para permitir la visibilidad de secciones del buffer de

pantalla, y cuando su tamaño es menor a este último, crea automáticamente barras de

desplazamiento.

Ejemplo de Consola: El área negra es el Buffer de Pantalla, La Ventana de Consola es el marco que la rodea

Page 25: PROGRAMACIÓN ORIENTADA A OBJETOS (072-2103) · PROGRAMACIÓN ORIENTADA A OBJETOS (072-2103) Unidad I: Introducción 1.1 Historia del Computador 1.2 Lenguajes de Programación 1.3

Programación Orientada a Objetos

25

2.3.2 La clase console

La consola posee dos características que están estrechamente relacionadas entre sí:

• Representa las secuencias de entrada, salida y error estándar para las aplicaciones de

consola.

• No se puede heredar.

Su sintaxis se define de la siguiente forma: public static class Console; lo que

indica que esta clase es de dominio público (accesible por todos los objetos) y a su vez es

estática (lo que implica que, una vez definida, no se puede modificar). Nótese que luego de

la instrucción se coloca un “;” (punto y coma), el cual es el operador de fin de sentencia.

Cuando se inicia una aplicación de consola, el Sistema Operativo asocia

automáticamente a la misma tres secuencias de Entrada y Salida: Entrada Estándar, Salida

Estándar y Error Estándar, las cuales se representan a la aplicación como los valores de las

propiedades In (entrada), Out (salida) y Error. Éstas se encuentran contenidas en:

• System.IO.TextReader (entrada)

• System.IO.TextWriter (salida y error)

La clase Console contiene métodos de lectura y escritura de caracteres individuales o

líneas enteras de la consola; métodos de conversión de una instancia de un tipo de valor,

matriz de caracteres o conjunto de objetos en una cadena con o sin formato; métodos y

propiedades para cambiar la posición del cursor, los colores de primer plano y de fondo, para

reproducir un “bip”, entre otros.

2.3.3 Entrada y salida por consola

WriteLine

Es un método estándar para mostrar información a través del monitor de la consola donde se

esté ejecutando el programa en C#. Tiene 3 variantes fundamentales:

Page 26: PROGRAMACIÓN ORIENTADA A OBJETOS (072-2103) · PROGRAMACIÓN ORIENTADA A OBJETOS (072-2103) Unidad I: Introducción 1.1 Historia del Computador 1.2 Lenguajes de Programación 1.3

Programación Orientada a Objetos

26

• Mostrar mensaje: Es una de las formas más comunes de usar el método y consiste en

mostrar por pantalla una cadena de texto (escrita entre comillas dobles “0”). Sintaxis:

Console.WriteLine("Este es un mensaje");

• Mostrar el contenido de un atributo: Otra de las formas más comunes de usar el

método, y consiste en mostrar en pantalla el valor almacenado dentro de una variable.

Sintaxis: Console.WriteLine(atributo);

• Mostrar mensaje y el valor de 1 o más atributos y/u operaciones: La forma más

completa de usar el método, el cual permite mostrar no sólo un mensaje, sino que éste

puede ir acompañado de 1 o más valores. Una sintaxis puede ser como la siguiente:

Console.WriteLine("Texto "+ atributo);

Nótese el uso del operador “+”, el cual en este caso se emplea como concatenación

(unión) de cadenas de texto y atributos. Como ya se mencionó, el texto debe estar entre

comillas dobles “0”, los atributos no. Si por ejemplo se escribe esto:

Console.WriteLine(Texto + atributo);

Se muestra en pantalla el contenido de una variable Texto y de una variable atributo.

Si por el contrario se escribe esto: Console.WriteLine("Texto"+"atributo"); se muestra

en pantalla la palabra Textoatributo.

Otra manera de mostrar este tipo de salidas es la siguiente:

Console.WriteLine("La suma de {0} y {1} es {2}", a, b, a+b);

En este caso se escribe dentro del mensaje un identificador de posición de la variable.

En C#, la posición de una variable o atributo dentro del método WriteLine se cuenta de

izquierda a derecha a partir de la posición 0 (0 – 1 – 2 – 3 …). En el ejemplo, la variable a se

encuentra en la posición 0, por eso se escribe {0}, la variable b está en la posición 1, así que

es {1}, mientras que la operación a+b se encuentra en la posición, 2, entonces se coloca {2}.

Si se escribe algo como esto:

Page 27: PROGRAMACIÓN ORIENTADA A OBJETOS (072-2103) · PROGRAMACIÓN ORIENTADA A OBJETOS (072-2103) Unidad I: Introducción 1.1 Historia del Computador 1.2 Lenguajes de Programación 1.3

Programación Orientada a Objetos

27

Console.WriteLine("La suma de {0} y {0} es {2}", a, b, a+b);

Se mostraría el valor de a de manera duplicada, y el valor de a+b. En este caso, el valor

de b no se mostraría, dado que no está indicado en el método. Esta modalidad también

permite definir la cantidad de espacios previos a la impresión de algún valor, por ejemplo:

Console.WriteLine("Número {0,5}", num);

Imprime el valor de num predecedido por 5 espacios en blanco. Esto es muy útil

cuando se desea tabular la salida. Cabe destacar que si el valor a imprimir excede la cantidad

de caracteres señalada, símplemente se tratará como una impresión normal, y no lo truncará.

Por último, hay que señalar que cualquiera de las dos formas de mostrar la salida (con

cocatenación o indicador de posición) es totalmente válida. Incluso, una combinación de

ambas formas es igualmente aplicable:

Console.WriteLine("La suma de {0} y {1} es "+(a+b), a, b);

Write

Se trata de un método muy similar a WriteLine, con sintaxis casi idéntica y mismas

variantes:

Console.Write("Hola ");

Console.Write(a);

Console.Write("La suma de a+b es "+(a+b));

La única diferencia es que mientras WriteLine imprime una línea de texto y/o variable

y coloca el cursor en la siguiente línea, Write imprime la línea y coloca el cursor al final de

la misma.

ReadLine

Es el método estándar para leer información a través del teclado de la consola donde se esté

ejecutando el programa en C#. Es importante saber que cuando se emplea éste para la entrada

de datos, los mismos se leen en forma de cadena de caracteres, por lo que aunque se

Page 28: PROGRAMACIÓN ORIENTADA A OBJETOS (072-2103) · PROGRAMACIÓN ORIENTADA A OBJETOS (072-2103) Unidad I: Introducción 1.1 Historia del Computador 1.2 Lenguajes de Programación 1.3

Programación Orientada a Objetos

28

introduzca un valor numérico por teclado NO se podrá operar matemáticamente este valor

hasta tanto no se transforme adecuadamente al tipo indicado. Su sintaxis es como sigue:

lector = Console.ReadLine(); donde lector es una cadena de caracteres con capacidad

de almacenar cualquier cosa que el usuario introduzca por el teclado.

Si se desea emplear la información de entrada para realizar cálculos matemáticos, se

puede realizar una conversión de tipo, lo cual no es más que llevar el contenido de una

cadena a un tipo de dato específico. La sintaxis para tal conversión es como sigue:

variable_real = tipo_de_dato_a_convertir.Parse(cadena_a_transformar)

Por ejemplo, si se quiere transformar la entrada de datos a un número entero y

almacenarlo en una variable num, se realiza como sigue:

num = int.Parse(cadena);

Ahora, para transformar una variable de cualqueir tipo a cadena, existe el método

ToString, cuya sintaxis es: cadena = variable.ToString();

Al ejecutar un programa en C#, éste lo hace tán rápidamente que finaliza y se cierra

impidiendo ver los resultados. Para evitar esto, es recomendable escribir al final del código

la siguiente línea: Console.ReadLine(); ya que obliga al programa a esperar la entrada del

usuario, permitiendo ver la ejecución del mismo.

2.3.4 Métodos para personalizar la consola

Como ya se ha dicho, la clase Console no sólo permite la entrada y salida de datos, sino que

también permite la personalización de la pantalla. Dos de los métodos más populares son los

siguientes:

• BackgroundColor: Permite cambiar el color de fondo de las celdas de carácter. Su

sintaxis es como sigue:

Console.BackgroundColor = ConsoleColor.DarkBlue;

Page 29: PROGRAMACIÓN ORIENTADA A OBJETOS (072-2103) · PROGRAMACIÓN ORIENTADA A OBJETOS (072-2103) Unidad I: Introducción 1.1 Historia del Computador 1.2 Lenguajes de Programación 1.3

Programación Orientada a Objetos

29

De acuerdo al ejemplo, se asigna como color de fondo uno de los colores disponibles para

consola (en este caso el azul oscuro).

• ForegroundColor: Permite cambiar el color en primer plano, es decir, cambia el color

de las letras. Su sintaxis es muy parecida a la del método anterior:

Console.ForegroundColor = ConsoleColor.Yellow;

Para activar ambos métodos debe escribirse lo siguiente: Console.Clear(); la cual,

como su nombre lo indica, realiza una limpieza de pantalla. Cabe destacar que es

recomendable escribir estos métodos ANTES de escribir el resto del programa.

Ejemplo 2.6: Escriba un programa que lea 2 números enteros e imprima la suma:

using System;

using System.Collections.Generic;

using System.Text;

namespace Ejemplo2_6

{

class Sumador

{

private int a, b, suma;

private string temp;

public void ejercicio()

{

Console.WriteLine("Ingrese 2 números");

temp = Console.ReadLine(); // Lectura de una cadena de texto

a = int.Parse(temp); // Conversión a entero

// Lectura y conversión directa:

b = int.Parse(Console.ReadLine());

suma = a + b;

// Impresión de texto y variable:

Console.WriteLine("La suma es: " + suma);

}

}

class Program

{

static void Main(string[] args)

{

// Personalización de la Consola:

Console.BackgroundColor = ConsoleColor.DarkBlue;

Console.ForegroundColor = ConsoleColor.Yellow;

Console.Clear();

Page 30: PROGRAMACIÓN ORIENTADA A OBJETOS (072-2103) · PROGRAMACIÓN ORIENTADA A OBJETOS (072-2103) Unidad I: Introducción 1.1 Historia del Computador 1.2 Lenguajes de Programación 1.3

Programación Orientada a Objetos

30

// Aquí inicia el programa como tal:

Sumador sum = new Sumador(); // Declaración del objeto

sum.ejercicio() // Ejecución del método interno

Console.ReadLine();

}

}

}

Nótese las líneas precedidas por la doble barra “//”. Estos son los comentarios de una

línea, los cuales no son más que línea no ejecutables que se emplean para la documentación

del código fuente. Si se quieren usar comentarios de líneas múltiples, se emplea la

combinación de /* y */, así:

/* Este es un comentario de múltiples lineas

Y estará inactivo hasta el cierre del mismo */

La combinación anterior suele ser empleada para la inhabilitación de código ejecutable,

esto con el fin de facilitar la revisión y detección de errores de código, sin necesidad de borrar

el contenido.

2.4 Ejercicios propuestos

1) Escriba un programa que lea tres palabras e imprima una frase completa con ellas. Por

ejemplo, si se reciben las cadenas “Bienvenido”, “a” y “C#” se imprima la línea

“Bienvenido a C#”.

2) Modifique el programa anterior para imprimir texto adicional, el cual debe ir entre las

palabras recibidas desde el teclado. Por ejemplo, al recibir “Bienvenido”, “a” y “C#”, se

imprima algo como “Sean todos Bienvenidos a las clases de C#”.

3) Escriba un programa que lea un número entero e imprima su cuadrado.

4) Construya una clase que sea capaz de realizar las operaciones aritméticas fundamentales

entre dos números (suma, resta, producto y división).

Page 31: PROGRAMACIÓN ORIENTADA A OBJETOS (072-2103) · PROGRAMACIÓN ORIENTADA A OBJETOS (072-2103) Unidad I: Introducción 1.1 Historia del Computador 1.2 Lenguajes de Programación 1.3

Programación Orientada a Objetos

31

UNIDAD III: DATOS SIMPLES

3.1 Variables

La variable es una posición de memoria donde se puede almacenar un valor para uso de un

programa, ya sea entero, número real, carácter, entre otros. Este valor es temporal, pues puede

ser reemplazado por otro a medida que se van ejecutando las instrucciones. La manera de

informar a la computadora que se crea una variable es a través de una sentencia de

declaración, la cual ayuda a definir lo que se puede almacenar en un nombre de variable.

Por su parte están las constantes, cuyo valor es invariable durante la ejecución del

algoritmo. En ambos casos se requiere del uso de un identificador, el cual consiste en una

secuencia de caracteres alfanuméricos que permite asignar un nombre (preferiblemente

significativo) al referido espacio de memoria, ya que de no hacerlo se requeriría conocer la

dirección específica de la variable o constante, lo cual resulta muy complicado.

3.1.1 Reglas para asignar nombres de variables

La sintaxis del lenguaje de programación C# impone algunas reglas en la construcción de los

nombres de variables. Estos se listan a continuación:

• Puede ir formado por una o más letras, o en combinación con números.

• Puede tener cualquier longitud.

• No se permite el uso de caracteres especiales, excepto el underscope “_”.

• Siempre deberá comenzar con una letra o por “_”. Sin embargo, es buena práctica de

programación tener nombres de variables que empiecen con letras minúsculas (a - z).

• Preferiblemente, que sea mnemotécnico.

• Todas las variables deben declararse con un nombre y un tipo de datos. Por ejemplo,

string cad;

• La declaración de una variable se puede realizar en cualquier parte del programa, siempre

y cuando sea antes de su primer uso

Page 32: PROGRAMACIÓN ORIENTADA A OBJETOS (072-2103) · PROGRAMACIÓN ORIENTADA A OBJETOS (072-2103) Unidad I: Introducción 1.1 Historia del Computador 1.2 Lenguajes de Programación 1.3

Programación Orientada a Objetos

32

• No puede ser una palabra reservada del lenguaje (se trata en este caso de un

identificador predefinido que tiene un significado especial).

Algunas palabras reservadas por C#

bool break case char const

continue decimal default do double

else enum extern float for

goto if int long object

return short sizeof static string

struct switch void volatile while

3.1.2 Tipos de identificadores

Los identificadores (variables o constantes) pueden ser:

• Numéricos: Almacenan sólo números.

o Acumulador: Es aquel que se incrementa en forma no definida por la suma o

producto con otro valor a dicho campo. Su valor inicial suele ser 0 (suma) o 1

(producto).

• Alfanuméricos: Almacenan cualquier carácter.

• Lógicos: Almacenan los estados true (verdadero) y false (falso).

• Compuestos: Combinación de varios identificadores de uno o más tipos.

3.2 Tipos de datos

Se define como un conjunto de valores y operaciones definidas para las variables de ese tipo

en particular. Los tipos de datos básicos en C# son: Byte, Int, Single, Double, Decimal,

Boolean, Char, String y Object.

Por ejemplo, int es un tipo de dato y conjunto de valores que una variable de tipo int

puede almacenar, y también el conjunto de operaciones que se pueden usar con los operandos

enteros.

Page 33: PROGRAMACIÓN ORIENTADA A OBJETOS (072-2103) · PROGRAMACIÓN ORIENTADA A OBJETOS (072-2103) Unidad I: Introducción 1.1 Historia del Computador 1.2 Lenguajes de Programación 1.3

Programación Orientada a Objetos

33

Cada uno de los tipos de datos básicos se almacena en forma diferente en la memoria

de la computadora:

Tipo Descripción Bits Rango de Valores Alias

Sbyte Bytes con signo 8 -128 a 127 sbyte

Byte Bytes sin signo 8 0 a 255 byte

Int16 Enteros cortos con signo 16 -32.768 a 32.767 short

UInt16 Enteros cortos sin signo 16 0 a 65.535 ushort

Int32 Enteros normales con signo 32 -2.147.483.648 a 2.145.483.647 int

UInt32 Enteros normales sin signo 32 0 a 4.294.697.295 uint

Int64 Enteros largos con signo 64 -9.223.372.036.854.775.808 a

9.223.372.036.854.775.807 long

UInt64 Enteros largos sin signo 64 0 a 18.446.744.073.709.551.615 ulong

Single Reales con 7 dígitos de precisión 32 1,5x10-45 a 3,4x1018 float

Double Reales con 15-16 dígitos de precisión 64 1,0x10-28 a 7,9x1028 double

Decimal Reales con 28-29 dígitos de precisión 128 5,0x10-324 a 1,7x10308 decimal

Boolean Valores Lógicos 32 True, false bool

Char Caracteres Unicode 16 ‘\u0000’ a ‘\uFFFF’ char

String Cadenas de Caracteres Variable El permitido por la memoria string

Object Cualquier Objeto Variable Cualquier objeto object

Como se puede observar, además de los datos básicos existen los calificadores de

datos signed y unsigned, los cuales modifican las propiedades de los tipos (es decir,

determina si tienen o no tienen signo). También puede apreciarse un “alias” o nombre

alternativo en el que pueden ser declarados los tipos de datos.

Por ejemplo: long a = 123456789;

Int64 b = 987654321;

En ambos casos se declaran variables de tipo entero largo (o de 64 bits). Ambas

declaraciones son totalmente válidas.

3.3 Expresiones, operadores y asignaciones

El operador es el símbolo utilizado en matemáticas o computación para indicar la operación

que se realiza entre los elementos que une o la relación que existe entre ellos.

Page 34: PROGRAMACIÓN ORIENTADA A OBJETOS (072-2103) · PROGRAMACIÓN ORIENTADA A OBJETOS (072-2103) Unidad I: Introducción 1.1 Historia del Computador 1.2 Lenguajes de Programación 1.3

Programación Orientada a Objetos

34

3.3.1 Operadores aritméticos

Los operadores aritméticos de C# se muestran en la siguiente tabla:

Operación Operador Expresión Algebraica Expresión en C#

Suma + Z + 7 Z + 7

Resta – A – B A – B

Producto * XY X * Y

División / j/k ó j÷k j / k

Módulo % r mod s r % s

Advierta el uso de varios símbolos especiales, no utilizados en álgebra. El asterisco (*)

indica producto, y el signo de porcentaje (%) denota el operador módulo. Los operadores

aritméticos son operadores binarios. La combinación de operandos por medio de cualquiera

de estos operadores se llama expresión algebraica o aritmética.

La división de enteros da como resultado también un entero. Por ejemplo, la expresión

7/4 da como resultado 1, y la expresión 17/5 da como resultado 3. Se debe tener mucho

cuidado de asegurar que al realizar la división, el denominador sea distinto a 0. Si se intenta

dividir entre 0, el programa no funcionará.

C# tiene el operador de módulo %, que proporciona el residuo después de una división

de enteros, por lo tanto, 7%4 da como resultado 3, y 17%5 da como resultado 2. El módulo

es un operador entero, es decir, que sólo puede ser utilizado con operandos de tipo int.

Cuando uno de los operandos es negativo, el resultado de % no está definido.

Las expresiones aritméticas deben ser escritas en una línea continua para facilitar la

escritura de programas en la computadora. Entonces, expresiones tales como “a dividido

entre b” deben ser escritas como a/b, y no como 𝒂

𝒃. Por su parte, los paréntesis se utilizan en

las expresiones de C# de manera muy similar a como se usan en las expresiones algebraicas.

Por ejemplo, para multiplicar a por la cantidad b+c se escribe lo siguiente: a * (b + c).

Page 35: PROGRAMACIÓN ORIENTADA A OBJETOS (072-2103) · PROGRAMACIÓN ORIENTADA A OBJETOS (072-2103) Unidad I: Introducción 1.1 Historia del Computador 1.2 Lenguajes de Programación 1.3

Programación Orientada a Objetos

35

3.3.2 Expresiones y operadores relacionales

Las expresiones relacionales son aquellas que se forman con una combinación de

identificadores, constantes y expresiones aritméticas, todas enlazadas a través de un conjunto

de operadores relaciónales. Los siguientes, por ejemplo, son todas expresiones relacionales

válidas:

• 10

• (a-25) <= max

• b<=0

• (b*b -2*a) < (c*e)/2

Operadores relacionales

Algunos de los operadores relacionales son: < (menor que), <= (menor o igual que), > (mayor

que) y >= (mayor o igual que). La asociatividad de la evaluación es de izquierda a derecha.

Los operadores relacionales se usan para formar expresiones relacionales. Las expresiones

relacionales siempre producen un valor de verdadero o falso.

Operadores de igualdad

Los operadores de igualdad son: == (igual a) y != (diferente a). La asociatividad de los

operadores es de izquierda a derecha. Éstos se pueden usar en expresiones relacionales.

Algunos ejemplos válidos del uso de los operadores de igualdad se presentan a continuación:

a == b n != 10 b + c == c - d

3.3.3 Expresiones y operadores lógicos

Las expresiones relacionales conectadas por operadores lógicos se denominan expresiones

lógicas, ya que siempre producen un valor de verdadero o falso. El valor que retorna una

expresión lógica es de tipo Boolean, a saber: true y false. C# también provee operadores

lógicos, llamados conectores lógicos, los cuales se listan a continuación:

Page 36: PROGRAMACIÓN ORIENTADA A OBJETOS (072-2103) · PROGRAMACIÓN ORIENTADA A OBJETOS (072-2103) Unidad I: Introducción 1.1 Historia del Computador 1.2 Lenguajes de Programación 1.3

Programación Orientada a Objetos

36

• && Y (AND)

• | | O (OR)

• ! NO (NOT)

Se pueden usar los operadores lógicos para combinar expresiones lógicas. Algunos

ejemplos se dan a continuación:

(a + 2) == max && (n != 0)

(a == 3) && (max != -1) | | (i % 2 != 0)

El operador lógico && retorna el valor true sólo cuando ambos operandos son

verdaderos. El operador lógico | | retorna el valor false sólo si ambos operandos son falsos.

El operador lógico ! retorna el opuesto del operando, es decir, retorna true si el operando es

false, y viceversa.

3.3.4 Operadores incrementales y decrementales

C# también tiene el operador incremental unario (++) y el operador decremental unario (--),

los cuales permiten incrementar o decrementar en 1 el valor de una variable. Por ejemplo,

X++ es el equivalente de X = X + 1.

Operador Ejemplo Descripción

++ ++ a Se incrementa a en 1 y a continuación se utiliza el

nuevo valor de a en la expresión en la cual resida a

a ++ Utiliza el valor actual de a en la expresión en la cual

resida a, y después se incrementa a en 1

-- -- b Se decrementa b en 1 y a continuación se utiliza el

nuevo valor de b en la expresión en la cual resida b

b -- Utiliza el valor actual de b en la expresión en la cual

resida b, y después se decrementa b en 1

3.3.5 Operadores compuestos de asignación

C# proporciona operadores compuestos de asignación, los cuales pueden ser utilizados como

atajos al escribir las declaraciones de asignación.

Page 37: PROGRAMACIÓN ORIENTADA A OBJETOS (072-2103) · PROGRAMACIÓN ORIENTADA A OBJETOS (072-2103) Unidad I: Introducción 1.1 Historia del Computador 1.2 Lenguajes de Programación 1.3

Programación Orientada a Objetos

37

Un operador de asignación compuesto consiste generalmente de un operador aritmético

binario y un operador de asignación simple. Éste ejecuta la operación de un operador binario

en ambos operandos y da el resultado de esa operación al operando izquierdo. Por ejemplo,

la declaración: X = X + 2 es equivalente a: X += 2. Los operadores compuestos más usados

son: += (suma), –= (resta), *= (producto), /= (división) y %= (módulo).

3.3.6 Operador condicional

El operador condicional “?:” retorna uno de dos valores de una expresión booleana. Su

sintaxis es como sigue:

Condición ? instrucción1 : instrucción2;

Como se puede observar, se trata de un operador ternario, ya que involucra 3

operandos. Aquí la condición se evalúa y, si el resultado es true se lleva a cabo la primera

instrucción, si es false ejecuta la segunda.

3.3.7 Precedencia de operadores

Las reglas de precedencia de operadores son guías de acción que permiten a C# calcular

expresiones en una secuencia precisa, es decir, permite establecer qué operaciones se

ejecutan primero, qué otras operaciones se ejecutan posteriormente.

Categoría Operadores Ejemplo de Uso Asociatividad

Acceso a Datos ( ) [ ] . a * (b + c) De izquierda a derecha

Unarios ++ -- + - (signo) -5 De derecha a izquierda

NOT Lógico ! !(k>f) De izquierda a derecha

Aritméticos * / % x % y De izquierda a derecha

+ - 3 + 2 De izquierda a derecha

Relacionales < <= > >= rel1 < rel2 De izquierda a derecha

Igualdad == != rel3 != rel4 De izquierda a derecha

AND Lógico && b<c && d>e De izquierda a derecha

OR Lógico | | b<c || d>e De izquierda a derecha

Condicional ?: i>j ? k=1 : k=0 De izquierda a derecha

Asignación = += -= *= /= %= a += 5 De derecha a izquierda

Page 38: PROGRAMACIÓN ORIENTADA A OBJETOS (072-2103) · PROGRAMACIÓN ORIENTADA A OBJETOS (072-2103) Unidad I: Introducción 1.1 Historia del Computador 1.2 Lenguajes de Programación 1.3

Programación Orientada a Objetos

38

Ejemplo 3.1: Escriba un programa que entre 3 enteros diferentes del teclado, y a continuación

imprima la suma, el producto y el promedio de estos números.

using System;

using System.Collections.Generic;

using System.Text;

namespace Ejemplo3_1

{

class Operaciones

{

private int a, b, c, prod=1; // Declaración de variables

public void lector()

{

Console.WriteLine("Ingrese 3 números enteros:");

a = int.Parse(Console.ReadLine());

b = int.Parse(Console.ReadLine());

c = int.Parse(Console.ReadLine());

}

public void ejemplo()

{

/* Declaración y asignación de variable interna. Nótese que

se declara SIEMPRE antes de usarla por primera vez */

int suma = a + b + c;

// Ejemplo de uso de operador compuesto de asignación:

prod *= a * b * c; // Es lo mismo que prod = prod * a * b * c

/* Ejemplo de uso de ley de precedencia: Dado que la división

tiene precedencia mayor que la suma, se fuerza a realizar

la suma primero con el uso de paréntesis (de precedencia

mayor) */

int prom = (a + b + c) / 3;

Console.WriteLine("La suma de los números es: "+suma);

Console.WriteLine("El producto de los números es: " + prod);

Console.WriteLine("El promedio de los números es: " + prom);

}

}

class Program

{

static void Main(string[] args)

{

Operaciones Ope = new Operaciones();

Ope.lector();

Ope.ejemplo();

Console.ReadLine();

}

}

}

Page 39: PROGRAMACIÓN ORIENTADA A OBJETOS (072-2103) · PROGRAMACIÓN ORIENTADA A OBJETOS (072-2103) Unidad I: Introducción 1.1 Historia del Computador 1.2 Lenguajes de Programación 1.3

Programación Orientada a Objetos

39

3.4 Ejercicios propuestos

1) Escriba un programa que lea el radio de un círculo y que imprima el diámetro del mismo,

su circunsferencia y su área. Utilice el valor constante 3.14159 para Pi, y el tipo de

atributo double.

2) Escriba un programa que reciba un número de cinco dígitos, separe el número en sus

dígitos individuales e imprima los dígitos separados unos de otros mediante tres espacios.

Utilice los operadores / (división) y % (módulo).

Page 40: PROGRAMACIÓN ORIENTADA A OBJETOS (072-2103) · PROGRAMACIÓN ORIENTADA A OBJETOS (072-2103) Unidad I: Introducción 1.1 Historia del Computador 1.2 Lenguajes de Programación 1.3

Programación Orientada a Objetos

40

UNIDAD IV: ESTRUCTURAS DE CONTROL

En un programa, por lo general, los enunciados son ejecutados uno después del otro, en el

orden en que aparecen escritos. Esto se conoce como ejecución secuencial.

Sin embargo, hay ocasiones en que se requiere que ciertas condiciones se verifiquen y

se tomen decisiones de acuerdo a éstas, es decir, realizar acciones específicas que bien

pudieran cambiar la secuencia de ejecución de un programa. Esto se denomina transferencia

de control, la cual puede realizarse mediante el uso de estructuras de selección o iterativas.

4.1 Estructuras de control selectivas

El control de decisión abarca desde verificar condiciones muy simples hasta estructuras muy

complejas, tomando decisiones basadas en ellas. C# proporciona 3 estructuras de selección,

a saber:

• if simple: Estructura de una sola selección. Ejecuta una acción si una condición es

verdadera, de ser falsa la ignora.

• if/else: Ejecuta una acción si una condición es verdadera, de ser falsa ejecuta una

acción distinta.

• switch/case: Ejecuta una entre muchas acciones diferentes, dependiendo del valor de

una expresión.

4.1.1 La estructura de selección simple: if

IF significa SI (condicional) en español, y consiste en una estructura de selección empleada

para elegir entre cursos alternativos de acción. Su funcionamiento es simple: Se evalúa una

condición, si es verdadera ejecuta un código, si es falsa, continúa con la ejecución del

programa.

Page 41: PROGRAMACIÓN ORIENTADA A OBJETOS (072-2103) · PROGRAMACIÓN ORIENTADA A OBJETOS (072-2103) Unidad I: Introducción 1.1 Historia del Computador 1.2 Lenguajes de Programación 1.3

Programación Orientada a Objetos

41

Diagrama de Flujo Sintaxis

if(condición)

{

<instrucciones>;

}

Ejemplo 4.1: Escribir un método que tome como entrada la calificación de un alumno y

determinar si aprobó la asignatura.

void ejemplo4_1(int nota)

{

if(nota >= 5)

{ Console.WriteLine("Aprobado"); }

}

En este ejemplo, la condición que se verifica es nota >= 5, la cual es una expresión

relacional. Si el resultado es true, se imprime la palabra “Aprobado”, de lo contrario no

ejecuta ninguna acción. Nótese el uso de las llaves “{ }”: En este caso se emplearon

simplemente para evitar confusión, ya que al haber una única instrucción éstas pueden ser

omitidas. De haber 2 o más sentencias dentro del bloque if, dichas llaves son de uso

obligatorio.

4.1.2 La estructura de selección doble: if/else

ELSE significa SINO (condicional) en español. La estructura if/else se le llama estructura

de doble selección, porque elige entre dos opciones distintas: Ejecuta una acción si la

condición es verdadera o ejecuta una acción diferente si la condición es falsa.

Diagrama de Flujo Sintaxis

if(condición)

{ <instr_ni;> }

else

{ <instr_no;> }

instrucciones condición Sí

No

No Sí condición

instr_si instruc_no

Page 42: PROGRAMACIÓN ORIENTADA A OBJETOS (072-2103) · PROGRAMACIÓN ORIENTADA A OBJETOS (072-2103) Unidad I: Introducción 1.1 Historia del Computador 1.2 Lenguajes de Programación 1.3

Programación Orientada a Objetos

42

Ejemplo 4.2: Modificar el método anterior, de tal manera que indique si un alumno aprobó

o reprobó la asignatura.

void ejemplo4_2(int nota)

{

if(nota >= 5)

{

Console.WriteLine("Aprobado");

}

else

{

Console.WriteLine("Reprobado");

}

}

Como pudo observarse en el ejemplo, en esta oportunidad se realizan 2 acciones

distintas, dependiendo de la condición: Si el resultado es true, se imprime la palabra

“Aprobado”, de lo contrario se imprime Reprobado. Tal como en if simple, si hay una única

sentencia relacionada con if y/o con else, las llaves pueden ser omitidas. Es de resaltar que

ambas acciones son excluyentes entre sí, es decir, si se ejecuta una de ellas no puede

ejecutarse la otra.

Debe recordarse que el bloque else se ejecuta solamente si el resultado de la

condición es falso, en otras palabras, es una acción automática que no necesita de una nueva

verificación, por lo que una instrucción de tipo “else(nota < 5)” es totalmente incorrecta.

Las estructuras if/else anidadas

Las estructuras anidadas son aquellas que se encuentran dentro de otras estructuras

de control. En el caso de un if/else anidado, su forma es como sigue:

if(condicion)

sentencia1;

else

if(condicion)

sentencia2;

else

if(condicion)

sentencia3;

else ...

Page 43: PROGRAMACIÓN ORIENTADA A OBJETOS (072-2103) · PROGRAMACIÓN ORIENTADA A OBJETOS (072-2103) Unidad I: Introducción 1.1 Historia del Computador 1.2 Lenguajes de Programación 1.3

Programación Orientada a Objetos

43

Esto tipo de estructuras resulta útil cuando existen relaciones que involucren al menos

3 posibles respuestas, ya que los operadores en programación son de tipo binario (es decir,

de la forma operando1 – operador – operando2), lo que implica que solamente se puede elegir

entre 2 alternativas, pudiéndose de esta forma realizar el descarte entre pares de opciones.

Por supuesto, se debe tener cuidado con los niveles de anidamiento para no elaborar un

programa demasiado confuso.

Ejemplo 4.3: Modificar el método anterior, de tal manera que indique si un alumno aprobó

la asignatura, sino, que indique si tiene o no derecho a examen final o reparación.

void ejemplo4_3(int nota)

{

if(nota >= 5)

Console.WriteLine("Aprobado");

else

if(nota >= 3.5)

Console.WriteLine("Puede presentar examen final");

else

if(nota >= 2)

Console.WriteLine("Puede ir a reparación");

else

Console.WriteLine("Reprobado");

}

En este caso se estudian 3 condiciones: Si la nota es mayor o igual a 5, si es mayor o

igual a 3.5 y si es mayor o igual a 2. Si se cumple la primea condición, se imprime la palabra

Aprobado, de lo contrario se pasa a la siguiente sentencia if/else, hasta que se ejecute

cualquiera de las sentencias involucradas.

Problema del else colgante

El compilador de C# siempre asocia un else con el if anterior, a menos que se indique lo

contrario mediante el uso de las llaves { }. En vista de que a primera vista el programador no

estaría seguro de cuál if coincide con qué else, esto se conoce como el problema del else

colgante.

Page 44: PROGRAMACIÓN ORIENTADA A OBJETOS (072-2103) · PROGRAMACIÓN ORIENTADA A OBJETOS (072-2103) Unidad I: Introducción 1.1 Historia del Computador 1.2 Lenguajes de Programación 1.3

Programación Orientada a Objetos

44

Ejemplo 4.4: Determine la salida para el siguiente bloque de código, cuando a es 9 y b es 11;

y cuando a es 11 y b es 9.

if(a < 10)

if(b > 10)

Console.WriteLine("*****");

else

Console.WriteLine("#####");

Console.WriteLine("$$$$$");

Se puede observar que el código ni está tabulado, ni incluye llaves. Un programador

sin experiencia puede confundirse al tratar de resolver este problema, sobretodo porque surge

la pregunta: ¿A quién le pertenece el else?

En este caso se debe tomar en cuenta lo siguiente:

• Un else nunca puede estar sin su correspondiente if, por lo tanto, cada instrucción else

dentro del código estará automáticamente asociada con el if inmediatamente anterior.

• Recuérdese que, cuando la instrucción asociada a un if o else es única, las llaves pueden

ser omitidas, pues funcionará de la misma manera.

• Es recomendable aplicar la indentación (o tabulado) en el código, para una correcta

identificación de los bloques.

Entonces, para resolver esto, lo primero que hay que hacer es tabular el código,

quedando como sigue:

if(a < 10)

if(b > 10)

Console.WriteLine("*****");

else

Console.WriteLine("#####");

Console.WriteLine("$$$$$");

Nótese que la última instrucción queda al mismo nivel del primer if. Esto es así porque,

como ya se ha mencionado, al no haber llaves se toma como parte de la estructura la

instrucción inmediatamente inferior al if o else. Si se desea que esta línea pertenezca al else,

se deben encerrar ambas instrucciones entre llaves.

Page 45: PROGRAMACIÓN ORIENTADA A OBJETOS (072-2103) · PROGRAMACIÓN ORIENTADA A OBJETOS (072-2103) Unidad I: Introducción 1.1 Historia del Computador 1.2 Lenguajes de Programación 1.3

Programación Orientada a Objetos

45

Ahora que se tiene ordenado el código es visualmente más sencillo identificar la

secuencia de instrucciones, de acuerdo a las condiciones; por lo tanto, para a = 9 y b = 11 la

salida es:

*****

$$$$$

Por su parte, para a = 11 y b = 9, la salida es:

$$$$$

Hay que ser cuidadosos en el uso de las llaves, sobre todo cuando se desea agrupar

varias instrucciones en un mismo bloque, pues se podría encerrar a una instrucción else sin

su correspondiente if, lo que generaría un error de código. Esto se ilustra en el siguiente

ejemplo:

Ejemplo 4.5: Aplique la indentación y las llaves en el código que sigue para producir la salida

deseada. No puede hacer ningún otro cambio.

if(i == 5)

if(j == 8)

Console.WriteLine("@@@@@");

else

Console.WriteLine("#####");

Console.WriteLine("$$$$$");

Console.WriteLine("*****");

a) Suponiendo que i = 5 y j = 8, se genera la siguiente salida: @@@@@

*****

b) Suponiendo que i = 5 y j = 8, se genera la siguiente salida: @@@@@

Este tipo de ejercicios es un poco más complicado de resolver, pero con un análisis

detallado y cierta habilidad en el uso de una estructura doble se puede dar con una solución.

En el caso de la salida a, se nota que debe imprimirse la línea de arrobas. Al haber dos

instrucciones if consecutivas, es evidente que una está anidada dentro de la otra, y que ambas

se deben cumplir (y lo hacen, según los valores de i y j), para que dicha salida se ejecute.

Page 46: PROGRAMACIÓN ORIENTADA A OBJETOS (072-2103) · PROGRAMACIÓN ORIENTADA A OBJETOS (072-2103) Unidad I: Introducción 1.1 Historia del Computador 1.2 Lenguajes de Programación 1.3

Programación Orientada a Objetos

46

Con respecto a las dos siguientes líneas, éstas no deben ser impresas. Se observa que

ambas siguen a una instrucción else, y como se mencionó antes, los if deben ejecutarse, por

lo tanto, estas líneas deben ser agrupadas en el else, ya que el mismo no ejecuta según la

condición. Ahora, ¿a cuál if pertenece? A cualquiera de los dos, pues el resultado es el mismo.

En este caso se decide que éste pertenezca al if más interno.

La última línea (asteriscos) debe imprimirse, entonces la misma puede, bien pertenecer

al if externo, o ser una instrucción independiente, ay que da el mismo resultado. Para este

ejercicio se opta por incluirlo en dicho if. Entonces, el código queda como sigue:

if(a == 5)

{

if(b == 8)

Console.WriteLine("@@@@@");

else

{

Console.WriteLine("#####");

Console.WriteLine("$$$$$");

}

Console.WriteLine("*****");

}

En el caso de b, solamente se requiere que se imprima la línea de arrobas. Aquí se

procede igual que con a, solo que ahora las tres últimas líneas deben incluirse en el else, ya

que, según los valores de i y j, esta serie de instrucciones no se ejecuta, ya que ambas

condiciones se cumplen. Por lo tanto se tiene lo siguiente:

if(a == 5)

{

if(b == 8)

Console.WriteLine("@@@@@");

else

{

Console.WriteLine("#####");

Console.WriteLine("$$$$$");

Console.WriteLine("*****");

}

}

Recuérdese que, al trabajar con las llaves, no debe haber una instrucción de tipo

“if(condicion){ else }”, ya que allí hay un error de sintaxis.

Page 47: PROGRAMACIÓN ORIENTADA A OBJETOS (072-2103) · PROGRAMACIÓN ORIENTADA A OBJETOS (072-2103) Unidad I: Introducción 1.1 Historia del Computador 1.2 Lenguajes de Programación 1.3

Programación Orientada a Objetos

47

4.1.3 La estructura de selección múltiple: switch/case

Una construcción anidada if/else puede llegar a ser difícil de entender, sobre todo cuando un

número de condiciones alternas deben ser evaluadas. C# provee la estructura switch/case,

que prueba una variable o expresión por separado contra cada uno de los valores constantes

enteros que pude asumir, lo que conduce a tomar distintas acciones.

Diagrama de Flujo Sintaxis

switch(variable o expresión)

{

case resp1: <instr_1>;

break;

case resp2: <instr_2>;

break;

case respN: <instr_N>;

break;

[default : <instr_D>;

break;]

}

Aquí pueden observarse varios aspectos:

• La condición a evaluar puede ser una variable, constante o expresiones algebraicas.

Sin embargo, el uso de expresiones relacionales en una selección múltiple puede verse

limitado por el lenguaje (por ejemplo, en C# no está permitido, pero en Pascal sí).

• Cada case debe culminar en una sentencia break (ruptura); la cual evita que, por

lógica, las otras sentencias case se ejecuten, de hecho, si se omite esa instrucción C#

muestra ese error.

• Default es una sentencia por defecto, la cual se ejecuta si no se cumplen los case.

Ésta, sin embargo, puede ser omitida. Si se incluye, al igual que los case debe

culminar en una sentencia break.

resp1

var o exp

resp2 respN

Por defecto

instr_1 instr_D instr_2 instr_N

Page 48: PROGRAMACIÓN ORIENTADA A OBJETOS (072-2103) · PROGRAMACIÓN ORIENTADA A OBJETOS (072-2103) Unidad I: Introducción 1.1 Historia del Computador 1.2 Lenguajes de Programación 1.3

Programación Orientada a Objetos

48

Ejemplo 4.6: Escriba un método que tome como entrada un valor del 1 al 7 e imprima el día

de la semana que corresponde al número ingresado (Domingo = 1, Lunes = 2, etc.). Si la

entrada no es válida se debe mostrar un mensaje de error.

public void ejemplo4_6(int dia)

{

switch (dia)

{

case 1: Console.WriteLine("Domingo");

break;

case 2: Console.WriteLine("Lunes");

break;

case 3: Console.WriteLine("Martes");

break;

case 4: Console.WriteLine("Miércoles");

break;

case 5: Console.WriteLine("Jueves");

break;

case 6: Console.WriteLine("Viernes");

break;

case 7: Console.WriteLine("Sábado");

break;

default: Console.WriteLine("Error!");

break;

}

}

Se debe prestar atención en el uso de esta estructura de control. Ya se ha mencionado

que un error común es la omisión de la instrucción break, sin embargo, existe otro error

bastante frecuente, conocido como código inalcanzable, debido a que el mismo se coloca

entre un break y el case siguiente (o el default), así:

case x: <instrucción_x>

break;

<alguna_instrucción> // <- Este es un código inalcanzable

case y: <instrucción_y>

break;

4.2 Estructuras de control iterativas

Muchos problemas en la vida real son una ejecución repetida de un conjunto de tareas, es

decir, realiza una serie de iteraciones, ciclos o bucles (loops). En programación existen las

Page 49: PROGRAMACIÓN ORIENTADA A OBJETOS (072-2103) · PROGRAMACIÓN ORIENTADA A OBJETOS (072-2103) Unidad I: Introducción 1.1 Historia del Computador 1.2 Lenguajes de Programación 1.3

Programación Orientada a Objetos

49

estructuras de control iterativas, las cuales permiten repetir porciones de algoritmo un

determinado número de veces. Este tipo de estructuras involucra tres partes básicas, a saber:

• Inicialización de la variable de control: La variable de control es aquella que, como su

nombre lo indica, lleva el control de la ejecución de un ciclo. Ésta debe tener siempre un

valor inicial con el que inicia la ejecución del primer bucle.

• Condición de repetición: Es la expresión relacional (o variable lógica) que define en

qué momento va a finalizar el ciclo.

• Actualización de la variable de control: Instrucción que permite modificar el valor de

la variable de control, de forma tal que en algún momento alcance aquel que indique el

fin de ejecución de los bucles.

4.2.1 La estructura iterativa for

Un contador es una variable especial que incrementa o decrementa, contando el número de

veces que el proceso ha detectado una ocurrencia determinada. Esto es importante saberlo,

puesto que el ciclo for (en español “para”) maneja de manera automática todos los detalles

de la repetición controlada por contador, ya que incorpora los componentes del ciclo en

una misma instrucción, y se emplea cuando se conoce con certeza el número de iteraciones

que deben realizarse.

Diagrama de Flujo Sintaxis

for(inicio;condición;actualización)

{

<instrucciones>;

}

El funcionamiento es como sigue: Cuando la estructura for inicia su ejecución, la

variable de control se inicializa a un valor dado. A continuación, se verifica si cumple con la

condición. Si se satisface, se ejecuta el conjunto de instrucciones contenidas dentro del ciclo.

final_de_ciclo

ini; cond; act instrucciones

condición_cierta

Page 50: PROGRAMACIÓN ORIENTADA A OBJETOS (072-2103) · PROGRAMACIÓN ORIENTADA A OBJETOS (072-2103) Unidad I: Introducción 1.1 Historia del Computador 1.2 Lenguajes de Programación 1.3

Programación Orientada a Objetos

50

A continuación, la variable de control se actualiza en forma automática, y el ciclo inicia otra

vez hasta que la condición sea false. Es allí cuando se termina la ejecución del bucle y se

continúa ejecutando el resto del programa.

Observaciones:

1. Tanto la inicialización, como la condición de continuación de ciclo, y la actualización

pueden contener expresiones aritméticas.

2. Si la condición de continuación de ciclo resulta falsa al inicio, la porción del cuerpo del

bucle no se ejecutará. En vez de ello, la ejecución seguirá adelante con el enunciado que

siga a la estructura for.

3. La variable de control con frecuencia se imprime o se utiliza en cálculos en el cuerpo de

un ciclo, pero esto no es necesario. Es común utilizar dicha variable para controlar la

repetición, aunque jamás se mencione la misma dentro del bucle.

4. En la sentencia for, se puede omitir cualquiera de los tres componentes del ciclo,

(inicialización, condición o actualización). En este caso, éstos deben colocarse antes o

dentro del mismo ciclo. Sin embargo, se requiere mucho dominio del manejo de ciclos

para realizar este tipo de cambios (sobre todo la omisión de la condición, la cual no es

recomendada).

5. No todos los lenguajes permiten definir la manera en que se actualiza la variable de

control. Por ejemplo, esta opción es inexistente en Pascal, puesto que allí el incremento

(o decremento) es por unidad. Por fortuna, este no es el caso de C#, el cual ofrece esta

facilidad.

Ejemplo 4.7: Escriba un método que imprima los números del 1 al 10.

public void ejemplo4_7()

{

for(int n = 0; n <=10; n++)

{

Console.WriteLine(n);

}

} /* Nótese que "n" se ha inicializado dentro del ciclo FOR. Esto

es totalmente válido, ya que se declara antes de su uso.

Una vez que n > 10, se culmina el ciclo. */

Page 51: PROGRAMACIÓN ORIENTADA A OBJETOS (072-2103) · PROGRAMACIÓN ORIENTADA A OBJETOS (072-2103) Unidad I: Introducción 1.1 Historia del Computador 1.2 Lenguajes de Programación 1.3

Programación Orientada a Objetos

51

Esta estructura permite ahorrar muchas líneas de código, ya que engloba todos los

elementos de un ciclo en una sencilla sentencia. Esto es sumamente importante, dado que

esta estructura for, es muy usada al trabajar con los arreglos (los cuales serán explicados en

la unidad V).

4.2.2 La estructura iterativa while

La estructura while (en español “mientras”), permite al programador repetir una acción, en

tanto cierta condición se mantenga verdadera. En otras palabras, realiza básicamente la

misma función que el ciclo for, sólo que aquí los componentes del ciclo son instrucciones

separadas.

Diagrama de Flujo Sintaxis

<valor_inicial>;

while(condición)

{

<instrucciones>;

}

Aquí se muestra con claridad el flujo de control en la estructura de repetición mientras:

La línea de flujo que parte del bloque instrucciones retoma a la decisión misma, que es

probada cada vez dentro del ciclo, hasta que de forma eventual la decisión se convierte en

falsa. Llegado este momento, se sale de la estructura y el control pasa al siguiente enunciado

del algoritmo.

Ejemplo 4.8: Modifique el algoritmo anterior para que use la estructura while.

public void ejemplo4_8()

{

int n = 0;

while(n <=10)

{

Console.WriteLine(n);

n++;

}

Verdadero

Falso

valor_inicial

condición instrucciones

Page 52: PROGRAMACIÓN ORIENTADA A OBJETOS (072-2103) · PROGRAMACIÓN ORIENTADA A OBJETOS (072-2103) Unidad I: Introducción 1.1 Historia del Computador 1.2 Lenguajes de Programación 1.3

Programación Orientada a Objetos

52

}

Obsérvese que, entre las sentencias dentro del cuerpo debe haber una que actualice la

variable de control, de forma tal que modifique la condición de iteración del bucle,

asegurando así la ejecución finita del mismo. De no haberla, o de estar mal formulada, podría

generarse lo que se llama un bucle infinito. Igualmente, una incorrecta formulación de la

variable de control (valor inicial inadecuado, inicialización dentro del bucle) o su completa

omisión, puede derivar en un error de sintaxis o ejecución.

En ocasiones, no se conoce con certeza el número total de ciclos, por lo que se debe

llevar a cabo una repetición controlada por centinela, ya que usa una variable que, al recibir

un valor específico, determina el final del ciclo.

Ejemplo 4.9: Elabore un método que permita leer una serie de números enteros positivos y

calcule su promedio. Dicho conteo deberá terminar cuando se introduzca el 0.

public void ejemplo4_9()

{

int n=1, suma = 0, cont=0;

while(n > 0)

{

Console.Write("Ingrese un número: ");

n = int.Parse(Console.ReadLine());

if(n > 0)

{

suma += n; // <- Esta variable es un acumulador

cont++; // <- Y esta variable es un contador

}

}

// En este caso, "0" es el valor centinela

if(cont > 0) // Se verifica si se insertaron valores

{

double prom = suma/cont;

Console.WriteLine("El promedio es: " + prom);

}

}

Aquí se declara una variable n que, en este caso, es el controlador del ciclo de

repetición, de tal manera que el mismo se ejecute hasta que el usuario ingrese el 0, que es el

Page 53: PROGRAMACIÓN ORIENTADA A OBJETOS (072-2103) · PROGRAMACIÓN ORIENTADA A OBJETOS (072-2103) Unidad I: Introducción 1.1 Historia del Computador 1.2 Lenguajes de Programación 1.3

Programación Orientada a Objetos

53

valor centinela, ya que permite que la relación n > 0 de un resultado falso, lo que culmina

el ciclo.

Como se ha dicho, si no hay una sentencia de control de repetición del ciclo, o si la

misma está mal formulada, el programa generaría un error de sintaxis (por ejemplo, si n no

está inicializada) o incluso un ciclo infinito (si se elimina la lectura del valor de n).

4.2.3 La estructura iterativa do-while

La sentencia do-while (“hacer-mientras”) es otra construcción iterativa que se usa cuando el

cuerpo de un bucle se debe ejecutar al menos una vez. En los bucles for y while, el cuerpo

del bucle se ejecuta sólo cuando la condición es verdadera. En el do-while la condición es

verificada al final, de este modo el cuerpo del bucle se ejecuta al menos una vez. Cuando

termina do/while, la ejecución continuará con el enunciado que aparezca después de la

cláusula while.

Diagrama de Flujo Sintaxis

<valor_inicial>

do

{

<instrucciones>;

} while(condición);

En otros lenguajes existen variantes de este bucle, por ejemplo, en Pascal no existe el

do-while, sino el repeat-until (“repetir-hasta”), con una estructura idéntica a la mostrada en

la tabla, salvo que allí el ciclo se ejecuta mientras la condición sea falsa.

Ejemplo 4.10: Modifique el programa anterior para que utilice una estructura do-while.

Verdadero

Falso

condición

instrucciones

valor_inicial

Page 54: PROGRAMACIÓN ORIENTADA A OBJETOS (072-2103) · PROGRAMACIÓN ORIENTADA A OBJETOS (072-2103) Unidad I: Introducción 1.1 Historia del Computador 1.2 Lenguajes de Programación 1.3

Programación Orientada a Objetos

54

public void ejemplo4_10()

{

int n, suma = 0, cont=0;

do

{

Console.Write("Ingrese un número: ");

n = int.Parse(Console.ReadLine());

if(n > 0)

{

suma += n;

cont++;

}

}while(n > 0);

/* Como puede observarse, el valor inicial se puede

obtener incluso dentro del cuerpo del bucle */

if(cont > 0)

{

double prom = suma/cont;

Console.WriteLine("El promedio es: " + prom);

}

}

4.2.4 Sentencias break y continue

Las sentencias break (romper) y continue (continuar) se utilizan para modificar el flujo de

control. El enunciado break, al ser ejecutado en una estructura while, for, do/while, o

switch, causa la salida inmediata de la misma. La ejecución del programa continúa con la

primera instrucción después de la estructura. Los usos comunes de esta sentencia son para

escapar en forma prematura de un ciclo, o para saltar el resto de una estructura switch (ver

4.1.3).

Ejemplo 4.11: Modifique el método mostrado en el ejemplo 4.7, para que utilice la sentencia

break cuando n = 5.

public void ejemplo4_11()

{

for(int n = 0; n <=10; n++)

{

if (x == 5)

break;

Console.WriteLine(x);

}

Console.WriteLine("El ciclo se rompe cuando X = 5");

}

Page 55: PROGRAMACIÓN ORIENTADA A OBJETOS (072-2103) · PROGRAMACIÓN ORIENTADA A OBJETOS (072-2103) Unidad I: Introducción 1.1 Historia del Computador 1.2 Lenguajes de Programación 1.3

Programación Orientada a Objetos

55

La salida generada es la siguiente:

Por su parte, el enunciado continue, cuando se ejecuta dentro de un ciclo, salta los

enunciados restantes del cuerpo de dicha estructura, y ejecuta la siguiente iteración del bucle.

En estructuras while y do/while, la prueba de continuación de ciclo se valúa inmediatamente

después de que se haya ejecutado el enunciado continue. En la estructura for, se ejecuta la

actualización de la variable de control, y a continuación se valúa la prueba de continuación

de ciclo.

Ejemplo 4.12: Modifique el método anterior, para que utilice la sentencia continue cuando

n = 5.

public void ejemplo4_12()

{

for(int n = 0; n <=10; n++)

{

if (x == 5)

continue;

Console.WriteLine(x);

}

Console.WriteLine("El ciclo continúa cuando X = 5");

}

En este programa, la salida generada es la que sigue:

4.3 Ejercicios propuestos:

1) Escriba un programa que lea 3 valores enteros positivos (no ceros) y que determine e

imprima si pueden ser los lados de un triángulo rectángulo.

Page 56: PROGRAMACIÓN ORIENTADA A OBJETOS (072-2103) · PROGRAMACIÓN ORIENTADA A OBJETOS (072-2103) Unidad I: Introducción 1.1 Historia del Computador 1.2 Lenguajes de Programación 1.3

Programación Orientada a Objetos

56

2) Escriba un programa que lea 5 números enteros y a continuación determine e imprima

cuál es el mayor y cuál es el menor del grupo.

3) Realizar un programa que sume todos los números impares comprendidos entre 1 y 1000.

4) Escriba un programa que lea un valor y a continuación imprima la figura mostrada. Éste

debería poder funcionar para todos los tamaños entre 5 y 30. Por ejemplo, si se lee un

tamaño de 5, debería imprimir:

*****

*****

*****

*****

*****

5) Escriba un programa que imprima los siguientes patrones. Cada * deberá ser impreso con

un enunciado Console.Write( ) (o WriteLine). Utilice ciclos for:

(a) (b) (c) (d)

* ********** ********** **********

** ********* ********** **********

*** ******** ********** **********

**** ******* ********** **********

***** ****** ********** **********

****** ***** ********** **********

******* **** ********** **********

******** *** ********** **********

********* ** ********** **********

********** * ********** **********

Page 57: PROGRAMACIÓN ORIENTADA A OBJETOS (072-2103) · PROGRAMACIÓN ORIENTADA A OBJETOS (072-2103) Unidad I: Introducción 1.1 Historia del Computador 1.2 Lenguajes de Programación 1.3

Programación Orientada a Objetos

57

UNIDAD V: DATOS COMPUESTOS

5.1 Arreglos

Muchas aplicaciones requieren el uso de múltiples elementos de datos que tienen una

característica en común. Hasta ahora, el único método que conoce para almacenar los es en

una variable. Pero, ¿cómo se almacenan 100 elementos de un mismo dato? Una forma de

hacerlo es tener 100 variables, como por ejemplo: var1, var2, …, var100. Sin embargo, sería

más simple referirse a una colección de datos con un solo identificador (var), y aún ser capaz

de poder referirse a las cada uno de ellos.

Esto se hace usando una estructura llamada arreglo, la cual se define como un grupo de

posiciones en memoria relacionadas entre sí, por el hecho de que todas tienen el mismo

nombre y son del mismo tipo. Para referirse a una posición en particular o elemento dentro

del arreglo, especificamos el nombre del arreglo y el número de posición del elemento

particular dentro del mismo.

5.1.1 Arreglo unidimensional

En la siguiente figura se muestra un arreglo de enteros:

C[0] C[1] C[2] C[3] C[4] C[5] C[6] C[7] C[8] C[9]

20 62 125 -5 0 74 3 10 89 -36

Este tipo de arreglos se conoce como vector o arreglo unidimensional. La dimensión

también se denomina el orden de un arreglo.

En el arreglo del ejemplo el orden es 10, es decir, que contiene 10 elementos.

Cualquiera de estos elementos puede ser referenciado dándole el nombre del arreglo seguido

por el número de posición de dicho elemento en particular en paréntesis cuadrados o

corchetes ([ ]), el cual es llamado subíndice, el cual debe ser un entero o una expresión entera.

Page 58: PROGRAMACIÓN ORIENTADA A OBJETOS (072-2103) · PROGRAMACIÓN ORIENTADA A OBJETOS (072-2103) Unidad I: Introducción 1.1 Historia del Computador 1.2 Lenguajes de Programación 1.3

Programación Orientada a Objetos

58

El primer elemento de cualquier arreglo es el elemento cero. Entonces, el primer

elemento de un arreglo, por ejemplo el arreglo C, se conoce como C[0], el segundo como

C[1], el séptimo como C[6], y en general, el elemento de orden i del arreglo C se conoce

como C[i–1].

Si un programa utiliza una expresión como subíndice, entonces la expresión se evalúa

para determinar el subíndice. Por ejemplo, si a = 5 y b = 3, entonces el enunciado C[a + b]

+= 2; añade 2 al elemento del arreglo C[8].

Para imprimir la suma de los valores contenidos en los primeros tres elementos del

arreglo C, se escribe

Console.WriteLine(C[1]+C[2]+C[3]);

Es importante notar la diferencia entre el “séptimo elemento del arreglo” y el “elemento

7 del arreglo”. Dado que los subíndices de los arreglos empiezan en 0, “el séptimo elemento

del arreglo” tiene un subíndice de 6, en tanto que “el elemento 7 del arreglo” tiene un

subíndice de siete y, de hecho, es el octavo elemento del arreglo. Este es una fuente de error

por “diferencia de uno”.

Cómo declarar los arreglos

Los arreglos ocupan espacio en memoria. El programador especifica el tipo de cada elemento

y el número de elementos requerido por cada arreglo, de tal forma que la computadora pueda

reservar la cantidad apropiada de memoria. La sintaxis es como sigue:

tipo_datos[] nombre_arreglo = new tipo_datos[tamaño];

Por ejemplo, para indicarle a la computadora que reserve 12 elementos para el arreglo

entero C, se utiliza la siguiente declaración:

int[] C = new int[12];

Page 59: PROGRAMACIÓN ORIENTADA A OBJETOS (072-2103) · PROGRAMACIÓN ORIENTADA A OBJETOS (072-2103) Unidad I: Introducción 1.1 Historia del Computador 1.2 Lenguajes de Programación 1.3

Programación Orientada a Objetos

59

La memoria puede ser reservada para varios arreglos dentro de una sola declaración.

Por ejemplo, para reservar 100 elementos para el arreglo entero b y 27 elementos para el

arreglo entero x, se utiliza la siguiente declaración:

int[] b = new int[100], x = new int[27];

También se pueden declarar de forma separada, así:

int[] b, x;

b = new int[100];

x = new int[27];

Estos arreglos se pueden inicializar a través de asignación, tal como se hizo con las

variables:

int[] C = new int[12];

for (int i = 0; i < 12; i++)

C[i] = 0;

Ejemplo 5.1: Desarrolle un programa que reciba como entradas 10 números enteros y los

almacene en un arreglo, luego imprima sólo los números impares.

static void Main(string[] args)

{

int i;

int[] array = new int[10];

for (i = 0; i < 10; i++)

{

Console.Write("Ingrese el valor del elemento " + i + ": ");

array[i] = int.Parse(Console.ReadLine());

}

Console.WriteLine("La lista de los elementos impares es:");

for (i = 0; i < 10; i++)

if (array[i] % 2 != 0)

Console.Write(array[i] + " ");

Console.ReadLine();

}

Otra manera de declarar/inicializar los arreglos es incluyendo los elementos dentro de

la misma declaración, quedando la sintaxis como sigue:

tipo_datos[] nombre_arreglo = new tipo_datos[] {<valores>};

Page 60: PROGRAMACIÓN ORIENTADA A OBJETOS (072-2103) · PROGRAMACIÓN ORIENTADA A OBJETOS (072-2103) Unidad I: Introducción 1.1 Historia del Computador 1.2 Lenguajes de Programación 1.3

Programación Orientada a Objetos

60

Por ejemplo, si se desea crear un arreglo A con los valores enteros 1, 5, 6, 8, la

declaración queda así:

int[] A = new int[] {1, 5, 6, 8};

Incluso, se puede compactar declarando así:

int[] A = {1, 5, 6, 8};

Cómo ordenar arreglos

La ordenación de datos (es decir, colocar los datos en un orden particular, como orden

ascendente o descendente) es una de las aplicaciones más importantes de la computación. Un

banco clasifica todos los cheques por número de cuenta, de tal forma que al final de cada mes

pueda preparar estados bancarios individuales. Para facilitar la búsqueda de números

telefónicos, las empresas telefónicas clasifican sus listas de cuentas por apellido y dentro de

ello, por nombre. Virtualmente todas las organizaciones deben clasificar algún dato y en

muchos casos, cantidades masivas de información. La ordenación de datos es un problema

intrigante que ha atraído alguno de los esfuerzos más intensos de investigación en el campo

de la ciencia de la computación.

Una de las técnicas más comunes para la reorganización de arreglos es el ordenamiento

de burbuja o por hundimiento, debido a que los valores más pequeños “flotan” hacia la parte

superior del arreglo, como suben las burbujas de aire en el agua, en tanto que los valores más

grandes se hunden hacia el fondo del arreglo. La técnica consiste en llevar a cabo varias

pasadas a través del arreglo, en las cuales se comparan pares sucesivos de elementos y, al

cumplirse cierta condición, se intercambian de lugares, repitiéndose tal acción hasta tener

todo el arreglo ordenado.

Ejemplo 5.2: Llenar un arreglo de 5 elementos, imprimirlos en el orden original, y luego

imprimirlos ordenados en forma ascendente (usar el método de la burbuja).

static void Main(string[] args) {

int[] C = new int[5];

int i, vuelta, temp;

Page 61: PROGRAMACIÓN ORIENTADA A OBJETOS (072-2103) · PROGRAMACIÓN ORIENTADA A OBJETOS (072-2103) Unidad I: Introducción 1.1 Historia del Computador 1.2 Lenguajes de Programación 1.3

Programación Orientada a Objetos

61

for (i = 0; i < 5; i++) {

Console.Write("Ingrese el elemento {0}: ",i);

C[i] = int.Parse(Console.ReadLine());

}

// Se imprime en el orden original

for (i = 0; i < 5; i++)

Console.Write(" {0} ",C[i]);

Console.WriteLine();

// MÉTODO DE LA BURBUJA

// Se realiza el recorrido del arreglo un total de N-1 veces

for(vuelta = 0; vuelta < 4; vuelta++)

/* Se evalúan los elementos de 2 en dos, es decir,

se recorre el arreglo N-1 veces */

for(i = 0; i < 4; i++)

/* Al ser un ordenamiento de forma ascendente, se

deben colocar de menor a mayor. Si un elemento

i es uno mayor que el siguiente, se cambian */

if (C[i] > C[i + 1]) {

temp = C[i];

C[i] = C[i + 1];

C[i + 1] = temp;

}

// Se imprime el arreglo ordenado en forma ascendente

for (i = 0; i < 5; i++)

Console.Write(" {0} ",C[i]);

Console.ReadLine();

}

El programa mostrado ordena en orden ascendente los valores de los elementos de un

arreglo a de diez elementos. En cada pasada, se comparan pares sucesivos de elementos. Si

un par está en orden creciente (o son idénticos sus valores), dejamos los valores tal y como

están. Si un par aparece en orden decreciente, sus valores en el arreglo se intercambian de

lugar.

Primero el programa compara C[0] con C[1], después C[1] con C[2], a continuación

C[2] con C[3], y luego la última pasada, comparando C[n-2] con C[n-1]. Note que, aunque

existen N elementos, sólo se ejecutan N-1 comparaciones. En razón de la forma en que se

llevan a cabo las sucesivas comparaciones, en una pasada un valor grande puede pasar hacia

abajo en el arreglo muchas posiciones, pero un valor pequeño pudiera moverse hacia arriba

en una posición. En la primera pasada, el valor más grande está garantizado que se hundirá

Page 62: PROGRAMACIÓN ORIENTADA A OBJETOS (072-2103) · PROGRAMACIÓN ORIENTADA A OBJETOS (072-2103) Unidad I: Introducción 1.1 Historia del Computador 1.2 Lenguajes de Programación 1.3

Programación Orientada a Objetos

62

hasta el elemento más inferior del arreglo, C[N-1]. En la segunda pasada el segundo valor

más grande está garantizado que se hundirá a C[N-2]. En la N-1 pasada, el valor N-1 en

tamaño se hundirá a C[1]. Esto dejará el tamaño más pequeño en C[0], por lo que sólo se

necesitan de N-1 pasadas del arreglo para ordenarlo, aun cuando existan N elementos.

Gráficamente, este tipo de ordenamiento se observa así:

La ordenación se ejecuta mediante el ciclo for anidado. Si un intercambio es necesario,

es ejecutado mediante las tres asignaciones

temp = C[i];

C[i] = C[i + 1];

C[i + 1] = temp;

donde la variable adicional temp almacena en forma temporal uno de los dos valores en

intercambio. Éste no se puede ejecutar con sólo dos asignaciones:

C[i] = C[i + 1];

C[i + 1] = C[i];

Si, por ejemplo, C[i] es 7 y C[i + l] es 5, después de la primera asignación ambos

valores serán 5 y se perderá el valor 7. De ahí la necesidad de la variable adicional temp. La

virtud más importante de la ordenación tipo burbuja, es que es fácil de programar. Sin

embargo, la ordenación tipo burbuja es de lenta ejecución, lo que se hace aparente al ordenar

Page 63: PROGRAMACIÓN ORIENTADA A OBJETOS (072-2103) · PROGRAMACIÓN ORIENTADA A OBJETOS (072-2103) Unidad I: Introducción 1.1 Historia del Computador 1.2 Lenguajes de Programación 1.3

Programación Orientada a Objetos

63

arreglos extensos. Una manera de solucionar este problema es optimizar el código de forma

tal que evite hacer pasadas innecesarias.

Errores más comunes en el uso de arreglos

• Diferencia de 1: Cuando se hace referencia a un elemento N, en un arreglo de tamaño N.

• Uso de subíndices inadecuados: Negativos, fraccionarios o caracteres.

• Overflow y Underflow: Cuando se hace referencia a elementos que están fuera de los

límites del arreglo.

• Cuando se usan contadores, realizar la cuenta de 1 a N, en vez de 0 a N-1.

• No emplear los subíndices cuando se desea hacer referencia a un elemento único del

arreglo. Por ejemplo, arreglo = x en vez de arreglo[y] = x.

• Utilizar un arreglo antes de haberlo construido.

5.1.2 Arreglos anidados

Se trata de un arreglo cuyos elementos son a su vez arreglos, pudiéndose así anidar cualquier

número de arreglos. Su declaración requiere de una sintaxis muy similar a la de los arreglos

unidimensionales, sólo que en esta oportunidad se colocan tantos corchetes como nivel de

anidación se requiera. Por ejemplo, para un arreglo con 2 niveles de anidamiento, se tiene la

siguiente sintaxis:

tipo_datos[][] nombre = {new tipo_datos[tam1], new tipo_datos[tam2]};

También se puede declarar un arreglo dentado sin especificar la cantidad de elementos

del arreglo interno (en tal caso, tendría un valor inicial de null), quedando su declaración de

la siguiente forma:

tipo_datos[][] nombre = new tipo_datos[cantidad][];

O, por el contrario, se pueden asignar valores iniciales a los arreglos. Por ejemplo, para

crear un arreglo de enteros formado por 2 arreglos internos, donde el primero tenga los

valores 1 y 2, y el otro los valores 3, 4 y 5, se puede emplear la siguiente declaración:

int[][] dentado = new int[2][] {new int[]{1,2}, new int[]{3,4,5}};

Page 64: PROGRAMACIÓN ORIENTADA A OBJETOS (072-2103) · PROGRAMACIÓN ORIENTADA A OBJETOS (072-2103) Unidad I: Introducción 1.1 Historia del Computador 1.2 Lenguajes de Programación 1.3

Programación Orientada a Objetos

64

Como en este caso se especifican los elementos, no hace falta indicar el tamaño del

mismo, por lo que una declaración equivalente queda así:

int[][] dentado = new int[][] {new int[]{1,2}, new int[]{3,4,5}};

Incluso, al igual que un arreglo unidimensional, se puede declarar así:

int[][] dentado = {new int[]{1,2}, new int[]{3,4,5}};

Para accede a los elementos de un arreglo hay que indicar entre los corchetes cuál es el

elemento exacto de los arreglos componentes al que se desea acceder, indicándose un

elemento de cada nivel de anidación entre unos corchetes diferentes pero colocándose todas

las parejas de corchetes juntas y ordenadas del arreglo más externo al más interno. Por

ejemplo, para asignar el valor 10 al elemento cuarto del arreglo que es el elemento primero

del arreglo dentado declarado anteriormente sería:

dentado[0][3] = 10:

5.1.3 Arreglos multidimensionales

Asuma que se quiere almacenar la fecha de nacimiento de estudiantes de un salón de clases

en el formato día, mes y año. Una forma de lograrlo es teniendo tres arreglos

unidimensionales llamados dia, mes y anio. Se pueden declarar como sigue:

int[] dia = new int[100], mes = new int[100], anio = new int[100;

Sin embargo, este tipo de declaraciones podrían ser confusas y generar consumo de

recursos innecesarios. Para estos casos, C# proporciona la capacidad para crear arreglos con

múltiples subíndices, llamados arreglos multidimensionales, los cuales se usan en situaciones

donde varios arreglos unidimensionales, cada uno de ellos del mismo tipo, se usan para

denotar una entidad lógica y de significado completo. Por ejemplo, para el caso anterior, se

puede declarar un arreglo llamado ddn, con múltiples dimensiones como sigue:

int[,] ddn = new int[100,3];

Esto significa que la fecha de nacimiento de 100 estudiantes está registrada en filas, y

cada fila tiene el día, mes y año de nacimiento de un estudiante en particular en cada una de

Page 65: PROGRAMACIÓN ORIENTADA A OBJETOS (072-2103) · PROGRAMACIÓN ORIENTADA A OBJETOS (072-2103) Unidad I: Introducción 1.1 Historia del Computador 1.2 Lenguajes de Programación 1.3

Programación Orientada a Objetos

65

las tres columnas respectivamente. Tablas o arreglos que requieren dos subíndices para

identificar un elemento en particular se conocen como arreglos de doble subíndice,

bidimensionales o matrices.

0 1 2 3

0 X[0,0] X[0,1] X[0,2] X[0,3]

1 X[1,0] X[1,1] X[1,2] X[1,3]

2 X[2,0] X[2,1] X[2,2] X[2,3]

En la figura anterior se ilustra un arreglo de doble subíndice, X, el cual se declara de la

siguiente manera: int[,] X = new int[3,4];

El arreglo contiene tres filas (renglones) y cuatro columnas, por lo que se dice que se

trata de un arreglo de 3 por 4. En general, un arreglo con m renglones y n columnas se llama

un arreglo de m × n o matriz. En C# se pueden declarar matrices de hasta 12 dimensiones.

Al igual que los arreglos unidimensionales o dentados, existen declaraciones

alternativas para las matrices. Para el ejemplo anterior, quedan definidas así:

int[,] X = new int[3,4] {{<val_pos0>}, {<val_pos1>}, {<val_pos2>}};

int[,] X = new int[,] {{<val_pos0>}, {<val_pos1>}, {<val_pos2>}};

int[,] X = {{<val_pos0>}, {<val_pos1>}, {<val_pos2>}};

Cada uno de los elementos en el arreglo a está identificado en la figura por un nombre

de elemento de la forma X[i][j]; X es el nombre del arreglo, e i y j son los subíndices que

identifican en forma única a cada elemento dentro de X. Note que los nombres de los

elementos en el primer renglón, todos tienen un primer subíndice de 0; los nombres de los

elementos en la cuarta columna, todos tienen un segundo subíndice de 3.

Se puede inicializar una matriz de manera similar a un arreglo unidimensional:

for (int i = 0; i < 3; i++)

for (int j = 0; i < 4; j++)

X[i,j] = 0;

Nótese el uso de 2 sentencias for anidadas. La más externa recorre los renglones de la

matriz, mientras que la más interna hace un recorrido por columnas. Igualmente, nótese que

Page 66: PROGRAMACIÓN ORIENTADA A OBJETOS (072-2103) · PROGRAMACIÓN ORIENTADA A OBJETOS (072-2103) Unidad I: Introducción 1.1 Historia del Computador 1.2 Lenguajes de Programación 1.3

Programación Orientada a Objetos

66

para tener acceso a un elemento de la matriz se deben especificar cada una de las posiciones

(o coordenadas) dentro de la misma.

Ejemplo 5.3: Una matriz de orden n × n es simétrica si A[i,j] = A[j,i] para todos los valores

de i y j. Por ejemplo, la siguiente matriz es simétrica:

0 1 2

0 1 2 3

1 2 4 5

2 3 5 6

Desarrolle un programa que cree una matriz de orden N (entre 2 y 20), reciba por teclado

cada uno de los elementos y verifique si la misma es simétrica.

static void Main(string[] args)

{

int i, j, size, valido = 1;

int[,] a = new int[20, 20];

// Validación de la entrada

do

{

Console.Write("Ingrese el orden de la matriz (2 - 20): ");

size = int.Parse(Console.ReadLine());

if(size < 2 || size > 20)

Console.WriteLine("Número incorrecto");

} while (size < 2 || size > 20);

// Se reciben los valores de la matriz

for (i = 0; i < size; i++)

for (j = 0; j < size; j++)

{

Console.Write("Ingrese el elemento [{0},{1}]: ", i, j);

a[i, j] = int.Parse(Console.ReadLine());

}

// Se verifican los elementos de la matriz

for (i = 0; i < size; i++)

for (j = 0; j < size; j++)

if(i != j) // Si no es un elemento de la diagonal

if (a[i, j] != a[j, i])

valido = 0;

if (valido == 1)

Console.WriteLine("La matriz es simétrica");

else

Console.WriteLine("La matriz no es simétrica");

Console.ReadLine();

}

Page 67: PROGRAMACIÓN ORIENTADA A OBJETOS (072-2103) · PROGRAMACIÓN ORIENTADA A OBJETOS (072-2103) Unidad I: Introducción 1.1 Historia del Computador 1.2 Lenguajes de Programación 1.3

Programación Orientada a Objetos

67

5.1.4 La clase System.array

En esta clase se definen los métodos esenciales para el manejo de arreglos y matrices. Entre

los más usados están los siguientes:

Lenght

Campo de sólo lectura que informa el número total de elementos que contiene un arreglo.

Para ello, se coloca el nombre del arreglo o cadena, luego un punto (que es un operador de

acceso a los miembros de una clase) y luego el método Length. El mismo retorna un valor

entero positivo. Por ejemplo, si se desea obtener la dimensión de un arreglo X con los

elementos 1, 2, 3, 4, se realiza de la siguiente manera:

int tam = X.Lenght; // Aquí tam = 4

En el caso de arreglos multidimensionales, indica el total de elementos de todas sus

dimensiones y niveles.

Ejemplo 5.4: Desarrolle un programa que cree un arreglo dentado y una matriz, y devuelva

el tamaño de ambas estructuras.

static void Main(string[] args)

{

int[][] dentado = {new int[] {1,2}, new int[] {3,4,5}};

int[,] matriz = {{1,2}, {3,4,5,6}};

Console.WriteLine(dentado.Lenght); // Imprime 5

Console.WriteLine(matriz.Lenght); // Imprime 6

Console.ReadLine();

}

int GetLength(int dimensión)

Método que devuelve el número de elementos de la dimensión especificada. Las dimensiones

se indican empezando a contar desde cero, por lo que si se quiere obtener el número de

elementos de la primera dimensión habrá que usar GetLength(0), de la segunda

GetLength(1), etc.

Page 68: PROGRAMACIÓN ORIENTADA A OBJETOS (072-2103) · PROGRAMACIÓN ORIENTADA A OBJETOS (072-2103) Unidad I: Introducción 1.1 Historia del Computador 1.2 Lenguajes de Programación 1.3

Programación Orientada a Objetos

68

Ejemplo 5.5: Modifique el programa del ejemplo 5.4 para mostrar las dimensiones de los

elementos de la matriz.

static void Main(string[] args)

{

int[,] matriz = {{1,2}, {3,4,5,6}};

Console.WriteLine(matriz.GetLenght(0)); // Imprime 2

Console.WriteLine(matriz.GetLenght(1)); // Imprime 4

Console.ReadLine();

}

void CopyTo(array destino, int posición)

Copia todos los elementos del arreglo sobre la que aplica en el arreglo destino a partir de la

posición que está indicada.

Ejemplo 5.6: Elabore un programa que permita copiar un arreglo dentro de otro.

static void Main(string[] args)

{

int[] a = {1, 2, 3, 4};

int[] b = {5, 6, 7, 8, 9};

a.CopyTo(b,1);

/* A partir de ahora, el arreglo b tendrá los elementos

{1, 5, 6, 7, 8, 9} */

Console.ReadLine();

}

En este caso, ambos arreglos deben ser unidimensionales, el arreglo del destino ha de

ser de un tipo que pueda almacenar los objetos del arreglo origen, el índice especificado ha

de ser válido y no ha de haber un elemento null en ninguno de los arreglos.

5.2 Cadenas

Una cadena de texto no es más que una secuencia de caracteres. C# las representa

externamente como un tipo de dato string, es decir, un alias de la clase System.String.

Las cadenas de texto suelen crearse a partir de literales de cadenas o de otras cadenas

previamente creadas. Ejemplos de ambos casos se muestran a continuación:

Page 69: PROGRAMACIÓN ORIENTADA A OBJETOS (072-2103) · PROGRAMACIÓN ORIENTADA A OBJETOS (072-2103) Unidad I: Introducción 1.1 Historia del Computador 1.2 Lenguajes de Programación 1.3

Programación Orientada a Objetos

69

string cad1 = "Programación";

string cad2 = cad1;

En el primer caso se ha creado un objeto string que representa la cadena formada por

la secuencia de caracteres “Programación” indicada literalmente por las comillas dobles. En

el segundo caso, la variable cad2 se genera a partir de cad1 ya existente, por lo que ambas

variables apuntarán al mismo objeto en memoria.

En C#, las cadenas se pueden tratar como arreglos unidimensionales, donde cada

carácter ocupa una posición de dicho arreglo.

0 1 2 3 4

T e x t o

Sin embargo, las cadenas son inmutables, lo que indica que no es posible modificar los

caracteres que la forman. Esto se debe a que el compilador comparte en memoria las

referencias a literales de cadenas lexicográficamente equivalentes para ahorrar memoria, y si

se permitiese modificarlos los cambios que se hiciesen a través de una variable a una cadena

compartida afectarían al resto de las variables, causando errores que serían difíciles de

detectar. Por tanto, hacer esto es incorrecto:

string cad = "Hola";

cad[0] = "A"; // Error

Pero esto sí es válido: char letra = cad[0];

5.2.1 Operadores de igualdad y concatenación

En el lenguaje C#, se ha modificado el operador de igualdad = = para que, cuando se aplique

entre cadenas, se considere que sus operandos son iguales sólo si son lexicográficamente

equivalentes y no se referencian al mismo objeto de memoria. Además, esta comparación se

hace teniendo en cuenta la capitalización usada. Por ejemplo:

string cad1 = "Hola";

string cad2 = "hola";

string cad3 = cad2;

Console.WriteLine(cad1 == cad2);

Console.WriteLine(cad2 == cad3);

Page 70: PROGRAMACIÓN ORIENTADA A OBJETOS (072-2103) · PROGRAMACIÓN ORIENTADA A OBJETOS (072-2103) Unidad I: Introducción 1.1 Historia del Computador 1.2 Lenguajes de Programación 1.3

Programación Orientada a Objetos

70

En este caso, la primera instrucción (cad1 = = cad2) devolverá un valor false, debido a

la diferente capitalización de la letra H. La segunda instrucción devolverá true.

Al igual que el significado de = = ha sido especialmente modificado para trabajar con

cadenas, lo mismo ocurre con el operador binario +. En este caso, cuando se aplica entre 2

cadenas, o una cadena y un carácter, lo que hace es devolver una nueva cadena con el

resultado de concatenar sus operandos. Por ejemplo:

string cad1 = "Hola ";

string cad2 = "mundo";

Console.WriteLine(cad1 + cad2);

// La salida será Hola mundo

5.2.2 Métodos de manejo de cadenas

Al ser virtualmente tratada como arreglo, el método Length se puede utilizar para determinar

el tamaño de una cadena (en este caso, cuenta la cantidad de caracteres que la componen).

string cad = "Hola";

int letras = cad.Length; // letras = 4

Copy y Substring

El método Copy devuelve una copia del objeto que se le pasa como parámetro. Por su parte,

Substring(posición, cantidad) devuelve la subcadena de la cadena sobre la que se aplica,

desde la posición indicada y el número de caracteres especificados.

string cad1 = "Programación";

string cad2 = string.Copy(cad1);

string cad3 = cad1.Substring(3,5);

string cad4 = cad1.Substring(3);

En este caso, cad2 contiene la palabra “Programación”, y cad3 la palabra “grama”. Para

cad4, al no especificarse la cantidad de caracteres, se extrae la subcadena desde la posición

indicada hasta el final de la cadena original, por lo que en este caso cad4 contiene la palabra

“gramación”.

Page 71: PROGRAMACIÓN ORIENTADA A OBJETOS (072-2103) · PROGRAMACIÓN ORIENTADA A OBJETOS (072-2103) Unidad I: Introducción 1.1 Historia del Computador 1.2 Lenguajes de Programación 1.3

Programación Orientada a Objetos

71

Insert, Remove y Replace

Insert(posición, subcadena) devuelve la cadena resultante de insertar la subcadena en la

posición indicada de la cadena sobre la que se aplica. Ejemplo:

string cad1 = "Torta";

string cad2 = cad1.insert(4, "ug");

Console.WriteLine(cad2); // cad2 = Tortuga

Entretanto, Remove(posición, cantidad) elimina el número de caracteres indicado a

partir de la posición especificada. De no definir cantidad, se elimina hasta el final de la

cadena. Ejemplo:

string cad1 = "Programación";

string cad2 = cad1.Remove(8,3);

string cad3 = cad1.Remove(8);

Console.WriteLine(cad2); // cad2 = Programan

Console.WriteLine(cad3); // cad3 = Programa

Replace(original, sustituta) sustituye en la cadena sobre la que se aplica el método

todas las apariciones de la cadena “original” por la sustituta.

string cad1 = "Torta para el tarro";

string cad2 = cad1.Replace("ta", "pe");

// cad2 = Torta para el perro

Se debe recordar que existe una diferencia entre una letra mayúscula y minúscula, por

lo tanto si se tiene la palabra “Casa casa” y se reemplaza “ca” por “pa” el resultado sería

“Casa pasa” en vez de “Pasa pasa”.

IndexOf y LastIndexOf

int IndexOf(posición, cadena) indica cuál es el índice de la primera ocurrencia de la cadena

especificada en el método. De no encontrar ninguna ocurrencia, el resultado es -1. La

búsqueda inicia desde la posición 0, pero con parámetros adicionales se puede especificar

desde y hasta dónde se realiza la búsqueda. Por su parte, int LastIndexOf(posición, cadena)

realiza la misma función que IndexOf, pero devuelve la posición de la última ocurrencia de

la cadena especificada.

Page 72: PROGRAMACIÓN ORIENTADA A OBJETOS (072-2103) · PROGRAMACIÓN ORIENTADA A OBJETOS (072-2103) Unidad I: Introducción 1.1 Historia del Computador 1.2 Lenguajes de Programación 1.3

Programación Orientada a Objetos

72

string cad = "Cucurrucucu";

int i1 = cad.IndexOf("u");

int i2 = cad.IndexOf("u",4);

int i3 = cad.IndexOf("u",4,2);

int i4 = cad.LastIndexOf("u");

int i5 = cad.LastIndexOf("u",9);

/* Aquí los resultados serían:

i1 = 1

i2 = 6

i3 = -1

i4 = 10

i5 = 8*/

ToUpper y ToLower

ToUpper y ToLower convierten respectivamente la cadena que los invoca en mayúsculas o

minúsculas. Este método es muy útil para la simplificación de programas, ya que permite

convertir a cualquier frase colocada por el usuario a una versión mucho más genérica de la

misma.

string cad1 = "Hola";

string cad2 = cad1.ToUpper();

string cad3 = cad1.ToLower();

Console.WriteLine(cad2); // cad2 = HOLA

Console.WriteLine(cad3); // cad3 = hola

5.3 Estructuras y Enumeraciones

5.3.1 Estructuras

Una estructura (struct) es una colección de datos con un comportamiento bastante similar a

una clase, de hecho ésta puede tener constructores, métodos, propiedades, entre otros (en este

sentido, si se desea un tipo de datos de tal complejidad es mejor definirlo como clase). Se

emplea más que todo para coleccionar un grupo de datos sencillos que usualmente están

relacionados a determinado objeto.

Este tipo de datos se puede crear con o sin la palabra reservada new. Si ésta es usada,

al crear el objeto se llama a un constructor por defecto. Caso contrario, los datos permanecen

Page 73: PROGRAMACIÓN ORIENTADA A OBJETOS (072-2103) · PROGRAMACIÓN ORIENTADA A OBJETOS (072-2103) Unidad I: Introducción 1.1 Historia del Computador 1.2 Lenguajes de Programación 1.3

Programación Orientada a Objetos

73

sin asignar, por lo tanto, éstos deben ser asignados en cualquier punto del programa, antes de

su uso. El siguiente ejemplo ilustra esto:

struct Estructura

{

public int v1;

public int v2;

}

class Program

{

static void Main(string[] args)

{

Estructura e1 = new Estructura();

Estructura e2;

Console.WriteLine(e1.v1 + "-" + e1.v2);

e2.v1 = 5;

Console.WriteLine(e2.v1);

Console.ReadKey();

/* Aquí la salida sería:

0 - 0

5

*/

}

}

Como se puede observare, el acceso a los miembros se realiza de la misma manera que

en una clase. También es de destacar que, al crearse un constructor interno, éste no puede ser

sin parámetro de entrada, ya que, a diferencia de una clase, aún se conserva ese constructor

por defecto. Por ejemplo:

struct Estructura

{

public int v1;

public int v2;

public Estructura(int a, int b)

{

v1 = a;

v2 = b;

}

}

class Program

{

static void Main(string[] args)

Page 74: PROGRAMACIÓN ORIENTADA A OBJETOS (072-2103) · PROGRAMACIÓN ORIENTADA A OBJETOS (072-2103) Unidad I: Introducción 1.1 Historia del Computador 1.2 Lenguajes de Programación 1.3

Programación Orientada a Objetos

74

{

Estructura e1 = new Estructura();

Estructura e2 = new Estructura(1, 2);

Console.WriteLine(e1.v1 + "-" + e1.v2);

Console.WriteLine(e2.v1 + "-" + e2.v2);

Console.ReadKey();

/* Aquí la salida sería:

0 - 0

1 - 2

*/

}

}

5.3.2 Enumeraciones

La palabra clave enum se emplea para declarar una colección de constantes identificadas por

un valor (por defecto un entero, pero puede ser cualquier tipo de datos). Es recomendable

que ésta sea declarada en el espacio de nombres (namespace) para poder ser accedido por

cualquier clase o estructura dentro del programa, sin embargo, una enumeración puede

igualmente estar anidada en los mencionados tipos.

Obsérvese el siguiente ejemplo:

enum Enumeracion { A, B, C, D, E }

class Program

{

static void Main(string[] args)

{

int x = (int)Enumeracion.A;

Console.WriteLine(x + " " + Enumeracion.A);

Console.ReadKey();

// Salida: 0 - A

}

}

Nótese la presencia de (int). En este caso se está realizando una conversión de tipo para

obtener su valor equivalente. También es importante aclarar que, de no especificarse, la

enumeración empieza desde 0. Es decir, el valor B sería 1, C sería 2, y así sucesivamente.

Page 75: PROGRAMACIÓN ORIENTADA A OBJETOS (072-2103) · PROGRAMACIÓN ORIENTADA A OBJETOS (072-2103) Unidad I: Introducción 1.1 Historia del Computador 1.2 Lenguajes de Programación 1.3

Programación Orientada a Objetos

75

Al realizar esta acción:

enum Enumeracion { A=1, B, C, D, E }

se estaría forzando al sistema a enumerar desde 1, en vez de hacerlo desde 0 (en este sentido,

B = 2, C = 3, etc.). Incluso, se puede forzar la numeración así:

enum Enumeracion { A, B, C=10, D, E=20 }

por lo que A = 0, B = 1, C = 10, D = 11 y E = 20. Ahora, si lo que se desea es usar otro tipo

de datos para una enumeración, se puede especificar de la siguiente manera:

enum Enumeracion : long { A, B, C=10, D, E=20 }

Nota: Solamente se aceptan los siguientes tipos de datos para las enumeraciones: byte, sbyte,

short, ushort, int, uint, long o ulong .

Nota2: En ocasiones, al declarar Estructuras o Enumeraciones se coloca un punto y coma

luego de la llave final. Esto es completamente válido y no afecta la ejecución del programa.

5.4 Ejercicios propuestos

1) Escriba enunciados individuales que ejecuten cada una de las operaciones siguientes, de

arreglos de 1 subíndice:

a. Inicialice a 0 los 10 elementos del arreglo entero cero.

b. Añada 1 a cada uno de los 15 elementos del arreglo entero uno.

c. Lea desde el teclado 12 valores de punto flotante y almacénalos en el arreglo

flotante.

d. Imprima los 5 valores del arreglo entero imprimir en formato de columna.

2) Desarrolle un programa que reciba por teclado N elementos de un arreglo (N entre 5 y

20), muestre el arreglo original y ordenado, luego determine y muestre la mediana (la

mediana es el valor del elemento medio de un arreglo, por ejemplo, en el arreglo {1, 5,

7, 8, 10} la mediana es 7).

Page 76: PROGRAMACIÓN ORIENTADA A OBJETOS (072-2103) · PROGRAMACIÓN ORIENTADA A OBJETOS (072-2103) Unidad I: Introducción 1.1 Historia del Computador 1.2 Lenguajes de Programación 1.3

Programación Orientada a Objetos

76

3) Considere una matriz cuadrada de orden n × n. Escriba un programa que lea los datos de

dicha matriz (enteros) y encuentre la suma de todos los elementos del borde.

4) Realice un programa que reciba una oración e indique cuántas palabras existen. Además,

deberá indicar cuántas veces aparece la letra “a” (incluya las mayúsculas, considere que

no hay acentos)

5) Desarrolle un programa que reciba una frase y 3 palabras, y deberá realizar lo siguiente:

• Encontrar la primera ocurrencia de la primera palabra.

• Si lo anterior es cierto, deberá reemplazarla por la segunda palabra.

• De aparecer más de una vez, deberá reemplazar las demás ocurrencias por la tercera

palabra

6) Incluya en cualquiera de los ejercicios propuestos la declaración y uso de enumeraciones

y estructuras. Su contenido queda a elección.

7) Si desea hacer una enumeración con valores de tipo bool, ¿cómo lo haría?

Page 77: PROGRAMACIÓN ORIENTADA A OBJETOS (072-2103) · PROGRAMACIÓN ORIENTADA A OBJETOS (072-2103) Unidad I: Introducción 1.1 Historia del Computador 1.2 Lenguajes de Programación 1.3

Programación Orientada a Objetos

77

UNIDAD VI: FUNDAMENTOS AVANZADOS DE PROGRAMACIÓN

6.1 Propiedades de uso, modificadores de parámetros y regiones

En C# existen ciertas instrucciones o palabras reservadas que se emplean para fines

específicos, ya sea para la reorganización del código para mejor visibilidad, o el tratamiento

de determinados datos. Entre ellos se encuentran las sentencias get, set, ref, out y region.

6.1.1 Propiedades de uso: get y set

Las propiedades combinan aspectos tanto de los atributos como los métodos. Para el usuario

de un objeto, una propiedad aparece bajo la forma de un campo, cuyo acceso requiere de la

misma sintaxis. Para el implementador de la clase, una propiedad es uno o dos bloques de

código, representados por los modificadores de acceso get y/o set. El primero se ejecuta

durante un proceso de lectura de la propiedad, mientras el segundo lo hace durante la escritura

de la misma.

Una propiedad sin el modificador set se considera de sólo lectura, pero si el

modificador faltante es get se considera de sólo escritura. De estar presentes ambas, se trata

de una propiedad de lectura/escritura. Cabe destacar que una propiedad no se clasifica como

una variable. Las propiedades se declaran en el bloque de la clase especificando el nivel de

acceso del campo, seguido del tipo y el nombre de la propiedad, para luego añadir uno o dos

bloques de código que declara el modificador get y/o set. Por ejemplo:

public class EjemploGetSet

{

private int variable;

public int Variable

{

get { return this.variable; }

set { this.variable = value; }

}

}

Page 78: PROGRAMACIÓN ORIENTADA A OBJETOS (072-2103) · PROGRAMACIÓN ORIENTADA A OBJETOS (072-2103) Unidad I: Introducción 1.1 Historia del Computador 1.2 Lenguajes de Programación 1.3

Programación Orientada a Objetos

78

En este ejemplo, la propiedad Variable usa un campo privado para hacer seguimiento

del valor actual. Es recomendable hacerlo de esa forma ya que, aunque esta forma de usar a

Variable no daría error de sintaxis:

public class EjemploGetSet

{

public int Variable

{

get { return this.Variable; }

set { this.Variable = value; }

}

}

puede presentarse un error en tiempo de ejecución debido a que la llamada a set puede generar

un ciclo infinito de asignación de variable. Otra forma de solventar el problema es declarando

una “autopropiedad” (aplicable a partir de C# 3.0), de esta forma:

public class EjemploGetSet {

public int Variable { get; set; }

}

ya que aquí se estaría invocando al campo privado oculto.

Nota: El operador get, de ser definido, debe incluir una sentencia return o throw, mientras

el operador set tiene un retorno vacío, y usa la palabra reservada value cuyo tipo de dato es

el definido en la declaración de la propiedad.

Ejemplo 6.1: Elabore un programa que permita leer un valor e imprimirlo. Utilice los

operadores get y set para tal fin.

namespace GetSet

{

public class EjemploGetSet

{

private int variable = 0; // Como buena práctica de prog.,

public int Variable // se recomienda un valor inicial

{ // para la variable privada.

get { return this.variable; }

set { this.variable = value; }

}

}

Page 79: PROGRAMACIÓN ORIENTADA A OBJETOS (072-2103) · PROGRAMACIÓN ORIENTADA A OBJETOS (072-2103) Unidad I: Introducción 1.1 Historia del Computador 1.2 Lenguajes de Programación 1.3

Programación Orientada a Objetos

79

static void Main(string[] args)

{

EjemploGetSet ej = new EjemploGetSet();

ej.Variable = 10;

Console.WriteLine("Número: " + ej.Variable;);

Console.ReadKey();

}

}

6.1.2 Modificadores de parámetros: ref, in y out

Los modificadores de parámetros son aquellas palabras reservadas que permiten cambiar la

manera en que son tratados los parámetros dentro de un método.

El operador ref indica que una variable es pasada por referencia. Éste se usa en los

siguientes contextos:

• En la firma o llamada a un método, para pasar un argumento al método por referencia.

• En la firma de un método para retornar un valor en la llamada por referencia.

• En un miembro del cuerpo, para indicar que una variable es almacenada localmente como

referencia que el invocante pretende modificar o, en general, una variable local.

• En la declaración de una estructura para declarar una estructura de referencia, o una

estructura aleatoria.

Para usar un parámetro ref, tanto en la definición del método como el método de

llamada se debe emplear explícitamente esta palabra reservada. Además, éste debe ser

previamente inicializado. Por ejemplo:

void MetodoRef(ref int param)

{ param = param + 44; }

static void Main(string[] args)

{

int num = 1;

MetodoRef(ref num);

Console.WriteLine("Número: " + num);

Console.ReadKey();

}

Page 80: PROGRAMACIÓN ORIENTADA A OBJETOS (072-2103) · PROGRAMACIÓN ORIENTADA A OBJETOS (072-2103) Unidad I: Introducción 1.1 Historia del Computador 1.2 Lenguajes de Programación 1.3

Programación Orientada a Objetos

80

Los miembros de una clase no pueden tener firmas sobrecaregadas que difieran

solamente en el uso de la palabra reservada (ref, in u out). El siguiente código es un ejemplo

de ello, el cual no compliará:

class EjemploError

{

public void Metodo(out int i) { }

public void Metodo(ref int i) { }

}

Sin embargo, sí pueden existir sobrecargas si uno de los métodos tiene alguna de las

palabras reservadas, y el otro no. Por ejemplo:

class EjemploValido

{

public void Metodo(int i) { }

public void Metodo(ref int i) { }

}

Con respecto a la palabra reservada in, ésta también indica el paso de parámetros por

referencia, y al igual que ref, debe ser previamente inicializada antes de su uso. Su principal

diferencia es que en esta oportunidad el método invocante no puede modificar el valor del

atributo referenciado, cosa que es posible con ref. El parámetro in está disponible desde C#

7.2, por lo tanto, las versiones anteriores a éste generan el error de compilación CS8107.

void MetodoIn(in int param)

{ /* Instrucciones */ }

static void Main(string[] args)

{

int num = 44;

MetodoIn(num);

Console.WriteLine("Número: " + num);

Console.ReadKey();

}

Como se puede ver en el ejemplo anterior, el uso de in no es necesario en la llamada

del método. Sólo es necesario en su declaración.

Page 81: PROGRAMACIÓN ORIENTADA A OBJETOS (072-2103) · PROGRAMACIÓN ORIENTADA A OBJETOS (072-2103) Unidad I: Introducción 1.1 Historia del Computador 1.2 Lenguajes de Programación 1.3

Programación Orientada a Objetos

81

Este operador también puede ser utilizado dentro de una instrucción, al hacer referencia

a algún elemento de una variable inicialmente declarada como var o una estructura

compuesta.

string archivos = getArchivos();

foreach (string arch in archivos)

{ /* Instrucciones */ }

Nota: foreach es una palabra reservada que permite recorrer una estructura o lista de datos,

siendo equivalente al uso de la sentencia for.

Finalmente se tiene a out, el cual permite el paso de un parámetro por referencia sin

necesidad de éste ser inicializado. De hecho, su inicialización se realiza dentro del método

que recibe a dicho parámetro. Al igual que ref, esta palabra reservada debe estar presente

tanto en la llamada como en el método. Por ejemplo:

void MetodoOut(out int param)

{ param = 44; }

static void Main(string[] args)

{

int num;

MetodoOut(out num);

Console.WriteLine("Número: " + num);

Console.ReadKey();

}

La ventaja principal de out, es que se pueden crear métodos que, de alguna manera,

permiten obtener el valor de varias variables internas, en vez de crear un método para cada

retorno requerido (recuérdese que return sólo permite retornar un parámetro). El siguiente

ejemplo ilustra mejor este caso:

namespace NormalVsOut

{

public class Metodos

{

private int v1 = 0, v2 = 1, v3 = 10:

public int getV1() // Retorno individual de v1

{ return v1; }

public int getV2() // Retorno individual de v2

{ return v2; }

Page 82: PROGRAMACIÓN ORIENTADA A OBJETOS (072-2103) · PROGRAMACIÓN ORIENTADA A OBJETOS (072-2103) Unidad I: Introducción 1.1 Historia del Computador 1.2 Lenguajes de Programación 1.3

Programación Orientada a Objetos

82

public int getV3() // Retorno individual de v3

{ return v3; }

public int getAll(out int a, out int b) // Retorno de todas

{

a = v1;

b = v2;

return v3;

}

}

static void Main(string[] args)

{

Metodos m = new Metodos();

int a, b, c;

// Aquí se obtienen los valores por separado

a = m.getV1();

b = m.getV2();

c = m.getV3();

// Aquí se obtienen todos los valores juntos

c = m.getAll(out a, out b);

Console.ReadLine();

}

}

Como se pudo observar, es necesaria la declaración de la variable antes de ser empleada

con el operador out. Sin embargo, a partir de C# 7.0 dicha declaración se puede hacer en la

misma línea de su uso. Por ejemplo:

string param = "1640"; }

if(Int32.TryParse(num, out int n)

Console.WriteLine("Es un número");

else

Console.WriteLine("Error");

Incluso, se puede hacer la llamada en forma más genérica, reemplazando el tipo de dato

(en el ejemplo, int), por var:

if(Int32.TryParse(num, out var n)

{ /* Instrucciones */ }

Page 83: PROGRAMACIÓN ORIENTADA A OBJETOS (072-2103) · PROGRAMACIÓN ORIENTADA A OBJETOS (072-2103) Unidad I: Introducción 1.1 Historia del Computador 1.2 Lenguajes de Programación 1.3

Programación Orientada a Objetos

83

6.1.3 Regiones

Una región permite al programador especificar bloques de código delimitados por las

directivas #region y #endregion, que pueden ser fácilmente expandidos o colapsados dentro

del editor. No afecta la funcionalidad del programa, pero permite al desarrollador una mejor

organización del código, sobretodo si éste tiene demasiadas instrucciones, ya que esta

característica permite ocultar los bloques que en ese momento no están siendo utilizados,

para enfocarse en un bloque en particular.

El siguiente ejemplo muestra cómo se define una región, y cómo éstas se ven cuando

están colapsadas.

namespace ProbandoRegiones

{

class Program

{

#region Bloque de métodos principales

static void Main(string[] args)

{ /* Contenido */ }

static void MetodoP1()

{ /* Contenido */ }

#endregion

#region Bloque de métodos secundarios

static void MetodoS1()

{ /* Contenido */ }

static void MetodoS1(int x)

{ /* Contenido */ }

static void MetodoS2()

{

#region Bloque1 de MetodoS2

/* instrucciones */

#endregion

#region Bloque2 de MetodoS2

/* instrucciones */

#endregion

}

#endregion

}

}

Page 84: PROGRAMACIÓN ORIENTADA A OBJETOS (072-2103) · PROGRAMACIÓN ORIENTADA A OBJETOS (072-2103) Unidad I: Introducción 1.1 Historia del Computador 1.2 Lenguajes de Programación 1.3

Programación Orientada a Objetos

84

El texto escrito justo en la línea de #region sirve como identificador de la misma,

comportándose en este caso de la misma forma que un comentario (código no ejecutable).

Por eso esta línea, a pesar del evidente “error de sintaxis”, no genera error ya que ésta no

forma parte del código a compilar.

6.2 Recursividad

La recursividad es un concepto muy abstracto y complejo que tiene que ver tanto con la

lógica como también con la matemática y otras ciencias. Se trata de una forma de definir un

proceso a través del uso de premisas que dan más información que el método en sí mismo, o

que utilizan los mismos términos que ya aparecen en su nombre, por ejemplo, cuando se dice

que la definición de algo es ese algo mismo.

La recursividad tiene como característica principal la sensación de infinito, de algo que

es continuo y que por tanto no puede ser delimitado en el espacio o el tiempo porque se sigue

replicando y multiplicando de manera lógica y matemática. Así, es común encontrar casos

de recursividad por ejemplo en imágenes de espejos que hacen que la imagen sea replicada

al infinito, una dentro de otra hasta que deja de verse pero no por eso deja de existir. Otro

caso típico de recursividad en las imágenes es cuando hay una publicidad en la que el objeto

Page 85: PROGRAMACIÓN ORIENTADA A OBJETOS (072-2103) · PROGRAMACIÓN ORIENTADA A OBJETOS (072-2103) Unidad I: Introducción 1.1 Historia del Computador 1.2 Lenguajes de Programación 1.3

Programación Orientada a Objetos

85

tiene la propaganda de sí mismo en su etiqueta y así al infinito, o cuando una persona está

sosteniendo una caja de un producto en cuya etiqueta aparece esa misma persona sosteniendo

el mismo producto y así hasta el infinito. En estos casos, la recursividad pasa por el hecho de

que se busca definir algo con lo misma información que ya se tiene. Un ejemplo básico de

recursividad es el cálculo del factorial de un número:

n! = n × n-1 × n-2 × … × 2 × 1

Por ejemplo, 5! = 5 × 4 × 3 × 2 × 1. Nótese entonces que es igual decir que 5 multiplica

a 4!, ya que éste es 4 × 3 × 2 × 1; a su vez, se puede decir que el factorial de 4 es ese número

por el factorial de 3, y así sucesivamente. Esto permite obtener la siguiente representación

recursiva:

n! = n × (n – 1)!

cuya sucesión se detendrá cuando se alcance a 0 (ya que 0! = 1).

En programación, es una técnica que permite definir funciones que se llaman a sí

mismas en forma consecutiva, permitiendo resolver problemas a partir de casos más simples

de los mismos. La mayoría de los lenguajes de programación dan soporte a la recursión,

permitiendo a una función llamarse a sí misma desde el texto del programa.

Los lenguajes imperativos definen las estructuras de ciclos (como while y for) que son

usadas para realizar tareas repetitivas. Algunos lenguajes de programación funcionales no

definen estructuras de ciclos, sino que posibilitan la recursión llamando código de forma

repetitiva. La teoría de la computabilidad ha demostrado que estos dos tipos de lenguajes son

matemáticamente equivalentes, es decir que pueden resolver los mismos tipos de problemas,

aunque los lenguajes funcionales carezcan de las típicas estructuras while y for.

En C# sucede igual, existiendo la posibilidad de resolver operaciones tanto en forma

iterativa como recursiva. El siguiente ejemplo muestra el cálculo del factorial de un número

en ambas variantes:

Page 86: PROGRAMACIÓN ORIENTADA A OBJETOS (072-2103) · PROGRAMACIÓN ORIENTADA A OBJETOS (072-2103) Unidad I: Introducción 1.1 Historia del Computador 1.2 Lenguajes de Programación 1.3

Programación Orientada a Objetos

86

Ejemplo 6.2: Elabore un programa que calcule el factorial de un número. Incluya un método

iterativo y uno recursivo.

class Program

{

static void Main(string[] args)

{

Console.Write("Ingrese un valor: ");

int x = int.Parse(Console.ReadLine());

Factorial F = new Factorial(x);

Console.WriteLine("Iterativo: " + F.Iterativo());

Console.WriteLine("Recursivo: " + F.Recursivo());

Console.ReadKey();

}

}

class Factorial

{

public int n { get; private set; }

public Factorial(int n)

{ this.n = n; }

public int Iterativo()

{

if (n < 0)

return 0;

else

{

int f = 1;

if (n > 1)

for (int i = 2; i <= n; i++)

f *= i;

return f;

}

}

public int Recursivo()

{

if (n < 0) return 0;

else return Recursivo(n);

}

private int Recursivo(int m)

{

if (m == 0)

return 1;

else return m * Recursivo(m - 1);

}

}

Para entender el ejercicio, supóngase que n = 3. Entonces, el proceso de llamada sería

como sigue:

Page 87: PROGRAMACIÓN ORIENTADA A OBJETOS (072-2103) · PROGRAMACIÓN ORIENTADA A OBJETOS (072-2103) Unidad I: Introducción 1.1 Historia del Computador 1.2 Lenguajes de Programación 1.3

Programación Orientada a Objetos

87

Primera Llamada

• Recursivo(3)

• ¿ m == 0 ? NO

• Retorno = 3 × Recursivo(3-1)

Segunda llamada

o Recursivo(2)

o ¿ m == 0 ? NO

o Retorno = 2 × Recursivo(2-1)

Tercera llamada

▪ Recursivo(1)

▪ ¿ m == 0 ? NO

▪ Retorno = 1 × Recursivo(1-1)

Cuarta llamada

✓ Recursivo(0)

✓ ¿ m == 0 ? SI

✓ Retorno = 1

Regreso a la tercera llamada

▪ Retorno 1 × 1 = 1

Regreso a la segunda llamada

o Retorno 2 × 1 = 2

Regreso a la primera llamada

• Retorno 3 × 2 = 6

Como el programa no ha de continuar ejecutándose indefinidamente, un procedimiento

recursivo está bien definido si tiene las siguientes propiedades:

• Debe existir un cierto criterio, llamado criterio base, por el que el procedimiento no se

llama así mismo. Para el ejemplo 6.2, el caso base es m = 0.

• Cada vez que el procedimiento se llame a sí mismo (directa o indirectamente), debe estar

más cerca del criterio base. En el ejemplo, cada llamada corresponde a un valor de m

cada vez menor, acercándose a 0 (caso base).

Page 88: PROGRAMACIÓN ORIENTADA A OBJETOS (072-2103) · PROGRAMACIÓN ORIENTADA A OBJETOS (072-2103) Unidad I: Introducción 1.1 Historia del Computador 1.2 Lenguajes de Programación 1.3

Programación Orientada a Objetos

88

Existen dos tipos de recursividad:

• Directa: Cuando un subprograma se llama a sí mismo una o más veces directamente.

• Indirecta: Cuando se definen una serie de subprogramas usándose unos a otros. A este

tipo de recursividad también se le conoce como recursividad cruzada.

Un algoritmo recursivo consta de una parte recursiva, otra iterativa o no recursiva y

una condición de terminación. La parte recursiva y la condición de terminación siempre

existen. En cambio la parte no recursiva puede coincidir con la condición de terminación.

Algo muy importante a tener en cuenta cuando se use la recursividad es que es necesario

asegurarse que llega un momento en el que no deben hacerse más llamadas recursivas. Si no

se cumple esta condición el programa no parará nunca.

La principal ventaja es la simplicidad de comprensión y su gran potencia, favoreciendo

la resolución de problemas de manera natural, sencilla y elegante; y facilidad para comprobar

y convencerse de que la solución del problema es correcta. Su desventaja es la ineficiencia

tanto en tiempo como en memoria, dado que para permitir su uso es necesario transformar el

programa recursivo en otro iterativo, que utiliza bucles y pilas para almacenar las variables.

En el ejemplo 6.2, la implementación iterativa es probablemente más rápida en la

práctica que la recursiva. Este resultado es lógico, pues las funciones iterativas no tienen que

pagar el exceso de llamadas de funciones como en el caso de las funciones recursivas, y ese

exceso es relativamente alto en muchos lenguajes de programación. Hay otros tipos de

problemas cuyas soluciones son inherentemente recursivas, porque están al tanto del estado

anterior. Un ejemplo es el árbol transversal; otros incluyen la función de Ackermann y el

algoritmo divide y vencerás tales como Quicksort. Todos estos algoritmos pueden

implementarse iterativamente con la ayuda de una pila, pero la necesidad del mismo, puede

que anule las ventajas de la solución iterativa.

Es importante destacar que la recursividad permite resolver problemas de gran

complejidad, sin embargo, en ciertos casos puede añadir complicaciones innecesarias a los

programas. Además, los métodos recursivos deben ser diseñados con mucha cautela y

Page 89: PROGRAMACIÓN ORIENTADA A OBJETOS (072-2103) · PROGRAMACIÓN ORIENTADA A OBJETOS (072-2103) Unidad I: Introducción 1.1 Historia del Computador 1.2 Lenguajes de Programación 1.3

Programación Orientada a Objetos

89

precisión para no desembocar en un ciclo infinito, que conllevará a una

StackOverflowException, que no es más que una medida que el sistema adopta para advertir

al usuario de la recursividad infinita y para detener un programa que, de no aplicarse esta

medida, continuaría ejecutándose, malgastando tiempo y recursos del sistema.

6.3 Referencias internas

Para entender este punto, es necesario conocer los siguientes conceptos:

• Pila: Es una zona de memoria reservada para almacenar información de uso inmediato

por parte del hilo de ejecución actual del programa. Por ejemplo, cuando se llama a una

función se reserva un bloque en la parte superior de esta zona de memoria (de la pila)

para almacenar los parámetros y demás variables de ámbito local. Cuando se llama a la

siguiente función este espacio se “libera” (en el sentido de que ya no queda reservado) y

puede ser utilizado por la nueva función. Es por esto que si se realizan demasiadas

llamadas anidadas a funciones (en recursión, por ejemplo) en algún momento se agota el

espacio en la pila, obteniendo un “stack overflow”.

• Montón: Es una zona de memoria reservada para poder asignarla de manera dinámica.

A diferencia de la pila, aquí no existen “normas” para poder asignar o desasignar

información en el montón, pudiendo almacenar y eliminar datos en cualquier momento,

lo cual hace más complicada la gestión de la memoria en esta ubicación.

• Variables por valor: Son tipos sencillos que almacenan un dato concreto y que se

almacenan en la pila. Por ejemplo, los tipos primitivos de .NET como int o bool, las

estructuras o las enumeraciones. Se almacenan en la pila y se copian por completo cuando

se asignan a una función. Por eso cuando se pasa un tipo primitivo a una función, aunque

se cambie dentro de ésta, éste no se ve reflejado fuera de la misma.

Page 90: PROGRAMACIÓN ORIENTADA A OBJETOS (072-2103) · PROGRAMACIÓN ORIENTADA A OBJETOS (072-2103) Unidad I: Introducción 1.1 Historia del Computador 1.2 Lenguajes de Programación 1.3

Programación Orientada a Objetos

90

• Variable por referencia: Es aquella que contiene la dirección de la memoria del lugar

donde se encuentran los datos. En concreto, todas las clases de objetos en .NET, así como

algunos tipos primitivos que no tienen un tamaño determinado (como las cadenas). Estos

tipos de datos se alojan siempre en el montón, por lo que la gestión de la memoria que

ocupan es más compleja, y el uso de los datos es menos eficiente (y de menor

rendimiento) que con los tipos por valor.

Hasta este punto se han trabajado con ambos tipos de variables; sin embargo, es

importante establecer la diferencia entre ambas, y esto se logra con los siguientes ejemplos:

Ejemplo 6.3: Elabore un programa que use llamada por valor para la suma de números.

class Program

{

static void Main(string[] args)

{

int i = 5;

Console.WriteLine(Suma2(i)); // Salida: 7

Console.WriteLine(i); // Salida: 5

Console.ReadKey();

}

public int Suma2(int n)

{

n = n+2;

return n;

}

}

Al definir la variable i, ésta se almacena en la pila directamente ya que es un tipo por

valor. Al llamar a la función Suma2 pasándole i como argumento, lo que ocurre es que el

valor de la variable i se copia a la pila y se asigna al parámetro n de la función. De esta forma

se tienen dos copias del dato en la pila, por eso al modificar n no se afecta para nada al valor

original de i. En el montón, por cierto, no hay nada almacenado.

Page 91: PROGRAMACIÓN ORIENTADA A OBJETOS (072-2103) · PROGRAMACIÓN ORIENTADA A OBJETOS (072-2103) Unidad I: Introducción 1.1 Historia del Computador 1.2 Lenguajes de Programación 1.3

Programación Orientada a Objetos

91

Ejemplo 6.4: Elabore un programa que use llamada por referencia para cambiar un dato.

class Program

{

static void Main(string[] args)

{

Persona p = new Persona();

p.Nombre = "Pedro";

p.Apellidos = "Pérez";

p.Edad = 25;

CambiaNombre(p);

Console.WriteLine(p.Nombre); // Salida: Pablo

Console.ReadKey();

}

public static void CambiaNombre(Persona per) {

per.Nombre = "Pablo";

}

}

public class Persona

{

public string Nombre;

public string Apellidos;

public int Edad;

}

Al declarar una variable de tipo Persona se genera una instancia de la misma en el

montón, ya que es un tipo por referencia. Al asignar los valores de las diferentes propiedades,

esos datos se almacenan en el montón asociadas a la instancia de la clase Persona que se

acaba de crear. Lo que realmente almacena la variable p es una referencia a los datos de esa

persona que están en el montón.

Page 92: PROGRAMACIÓN ORIENTADA A OBJETOS (072-2103) · PROGRAMACIÓN ORIENTADA A OBJETOS (072-2103) Unidad I: Introducción 1.1 Historia del Computador 1.2 Lenguajes de Programación 1.3

Programación Orientada a Objetos

92

Es decir, ahora en la pila no se almacenan los datos en sí, sino tan solo un “puntero” a

los mismos. Es una forma indirecta de referirse a ellos, no como antes en los tipos por valor

que el dato se almacenaba directamente en la pila.

Al llamar a la función CambiaNombre, en la variable local per que constituye el

parámetro de la función, lo que se duplica ahora en la pila es la referencia al objeto, no el

objeto en sí. Es decir, al hacer la llamada se disponen de dos variables que apuntan al mismo

tiempo a los datos almacenados en el montón. Por eso, cuando se cambia una propiedad del

objeto, al estar ambas referencias apuntando a los mismos datos, los cambios se ven desde

los dos lados.

En realidad, el comportamiento de la pila es idéntico en ambos casos, lo que cambia es

la información que se almacena, que es el propio dato en el caso de los tipos por valor, y la

referencia al dato en el caso de los tipos por referencia. Este modo de funcionamiento es la

diferencia fundamental que existe entre los tipos por valor y los tipos por referencia, y es

muy importante tenerla clara pues tiene muchas implicaciones a la hora de escribir código.

6.3.1 Clases autoreferenciadas

Una clase autoreferenciada es aquella que, entre sus miembros, incluye una variable que

apunta a un objeto de su mismo tipo. Ejemplo:

class AutoRefer

{

public string nombre;

public AutoRefer siguiente;

}

Page 93: PROGRAMACIÓN ORIENTADA A OBJETOS (072-2103) · PROGRAMACIÓN ORIENTADA A OBJETOS (072-2103) Unidad I: Introducción 1.1 Historia del Computador 1.2 Lenguajes de Programación 1.3

Programación Orientada a Objetos

93

El miembro siguiente se conoce como un enlace o vínculo ya que sirve para vincular

una clase con otra del mismo tipo. Éstas pueden ser enlazadas juntas para formar útiles

estructuras de datos como son las listas, las colas de espera, las pilas y los árboles. La gráfica

es un ejemplo de ello:

6.3.2 Código inseguro y apuntadores

En C# existen las construcciones programáticas conocidas como punteros (o pointers), el

cual es una variable especial que almacena una dirección de memoria, pero, a diferencia de

las variables por referencia, este tipo de construcción opera en un contexto inseguro, lo que

quiere decir que la gestión automática de memoria de la CLR no está presente y es el

programador mismo quien debe encargarse de localizar (allocate) y deslocalizar (deallocate)

memoria para las estructuras de datos. Su sintaxis es como sigue:

type* identificador;

void* identificador; // Permitido, pero no recomendado

Los tipos permitidos para un puntero son:

• sbyte, byte, short, ushort, int, uint, long, ulong, char, float, float, double, decimal, o bool.

• Tipos enum (Enumeraciones en C#).

• Tipos struct definidos por el usuario (Structs en C#).

int* p; // puntero a un entero

int** p; // puntero a un puntero de un entero

int*[] p; // arreglo unidimensional de punteros de enteros

char* p; // puntero a un caracter

void* p; // puntero a un tipo no definido o desconocido

Page 94: PROGRAMACIÓN ORIENTADA A OBJETOS (072-2103) · PROGRAMACIÓN ORIENTADA A OBJETOS (072-2103) Unidad I: Introducción 1.1 Historia del Computador 1.2 Lenguajes de Programación 1.3

Programación Orientada a Objetos

94

Entre los operadores principales de punteros están:

• Dirección &: Apunta a la dirección de una memoria.

• Desreferencia *: Retorna la variable en la dirección apuntada.

• Apuntador a miembro –>: Versión comprimida de x–>, equivale a (*x).y

• Indexación [ ]: Indexa un apuntador.

Para poder usar los apuntadores, se debe delimitar el código con la palabra reservada

unsafe. Esto se puede observar en el siguiente ejemplo:

// Se declara un arreglo de ejemplo

int[] a = new int[5] { 10, 20, 30, 40, 50 };

// Se declara un bloque de código inseguro

unsafe

{

// Se debe fijar el objeto al montón para que no se mueva

fixed (int* p = &a[0])

{

// Como p está fijado, se crea otro apuntador

int* p2 = p;

Console.WriteLine(*p2);

// Al incrementar a p2 se desplaza por bytes (en este caso 4)

p2 += 1;

Console.WriteLine(*p2);

p2 += 1;

Console.WriteLine(*p2);

Console.WriteLine("--------");

Console.WriteLine(*p);

// Con la desreferencia, se cambia el valor de a[0]

*p += 1;

Console.WriteLine(*p);

*p += 1;

Console.WriteLine(*p);

}

}

Console.WriteLine("--------");

Console.WriteLine(a[0]);

/* Salida:

10

20

30

--------

10

11

12

--------

12 */

Page 95: PROGRAMACIÓN ORIENTADA A OBJETOS (072-2103) · PROGRAMACIÓN ORIENTADA A OBJETOS (072-2103) Unidad I: Introducción 1.1 Historia del Computador 1.2 Lenguajes de Programación 1.3

Programación Orientada a Objetos

95

6.4 Herencia

La herencia es una forma de reutilización del software, en la cual se crean clases nuevas a

partir de clases existentes mediante la absorción de sus atributos y métodos, y embelleciendo

éstos con capacidades que las clases nuevas requieren. Al crear una clase nueva, en vez de

escribir en su totalidad miembros de datos y métodos, el programador puede determinar que

la clase nueva puede heredar los miembros provenientes de una clase base (padre) ya

definida. La clase nueva se conoce como clase derivada (hija).

Cada objeto que instancia una clase derivada también hace referencia a la clase padre,

pero lo contrario no es cierto: Ningún objeto de la clase padre es objeto de clase derivada

alguna. Para declarar una clase derivada se utiliza la siguiente sintaxis:

class clase_derivada:clase_base

{

miembros

}

Hay que recordar que en este tipo de clases puede aplicarse el modificador de acceso

protected.

Ejemplo 6.5: Desarrolle un programa que calcule el área de las figuras cuadrangulares.

Las figuras cuadrangulares involucran los cuadrados, rectángulos, paralelogramos,

entre otras. En este ejemplo sólo se usarán las dos primeras. Para empezar, se declara la clase

padre de la siguiente manera:

class Cuadrangulares

{

private int S;

protected string tipo;

protected void area(int x, int y)

{ S = x * y; }

public void imprimir()

{

Page 96: PROGRAMACIÓN ORIENTADA A OBJETOS (072-2103) · PROGRAMACIÓN ORIENTADA A OBJETOS (072-2103) Unidad I: Introducción 1.1 Historia del Computador 1.2 Lenguajes de Programación 1.3

Programación Orientada a Objetos

96

Console.WriteLine("El área del {0} es {1}", tipo, S);

Console.ReadLine();

}

}

En esta clase se colocaron 2 métodos que son comunes a las figuras cuadrangulares.

Luego se tienen dos clases derivadas: Una para el cuadrado, y otra para el rectángulo.

class cuadrado : Cuadrangulares

{

public cuadrado()

{ tipo = "Cuadrado"; }

public string ejecutar(int L)

{

area(L, L);

return "Cálculo ejecutado con éxito";

}

}

class rectángulo : Cuadrangulares

{

public rectángulo()

{ tipo = "Rectángulo"; }

public string ejecutar(int B, int H)

{

area(B, H);

return "Cálculo ejecutado con éxito";

}

}

En ambas clases se puede observar que se usa el atributo tipo a pesar de no estar

definido en ellas. Esto obedece a que tipo es un atributo común a ambas, puesto que está

definido en la clase padre. Lo mismo ocurre con el método área. Ambos miembros están

definidos como protegidos, por lo tanto, si se intenta acceder a ellos desde cualquier método

externo, dará error de acceso.

Por último, se codifica el programa principal:

static void Main(string[] args)

{

cuadrado c = new cuadrado();

rectángulo r = new rectángulo();

Console.WriteLine("Ingrese el lado: ");

int L = int.Parse(Console.ReadLine());

Page 97: PROGRAMACIÓN ORIENTADA A OBJETOS (072-2103) · PROGRAMACIÓN ORIENTADA A OBJETOS (072-2103) Unidad I: Introducción 1.1 Historia del Computador 1.2 Lenguajes de Programación 1.3

Programación Orientada a Objetos

97

Console.WriteLine(c.ejecutar(L));

c.imprimir();

Console.WriteLine("Ingrese la base y altura: ");

int B = int.Parse(Console.ReadLine());

int H = int.Parse(Console.ReadLine());

Console.WriteLine(r.ejecutar(B,H));

r.imprimir();

}

Aquí se invoca directamente al método imprimir( ), el cual pertenece a la clase base

Cuadrangulares.

Como se pudo notar, la herencia representa uno de los pilares fundamentales de la

programación orientada a objetos, puesto que permite realizar una jerarquía de clases,

agrupando elementos comunes a varias clases en una clase principal (por ejemplo, personas),

para ser utilizadas con los atributos y métodos de las clases derivadas (por ejemplo,

estudiantes, obreros, profesores).

6.5 Interfaces

Una interfaz contiene definiciones para un grupo de funcionalidades relacionadas que pueden

ser implementadas por una clase o estructura. Con su uso el programador puede, por ejemplo,

implementar el comportamiento de múltiples fuentes dentro de una clase, ya que C# no

permite la herencia múltiple de las clases. Se puede igualmente usar la interfaz si se desea

simular la herencia de estructuras, ya que estas últimas, de por sí, no soportan la herencia.

Una interfaz se define empleando la palabra reservada Interface y, por convención /y

como recomendación), el nombre de la interfaz suele estar precedido por una I. Ejemplo:

public interface IAve {

void Volar(); void Comer();

}

Como se puede observar, en la interfaz se crean las funciones comunes para las clases

o estructuras, sin embargo no se implementan, pues las mismas deben ser implementadas

Page 98: PROGRAMACIÓN ORIENTADA A OBJETOS (072-2103) · PROGRAMACIÓN ORIENTADA A OBJETOS (072-2103) Unidad I: Introducción 1.1 Historia del Computador 1.2 Lenguajes de Programación 1.3

Programación Orientada a Objetos

98

dentro de las estructuras antes mencionadas. En otras palabras, una interfaz tiene un

comportamiento similar a una clase abstracta, salvo que la interfaz puede ser implementada

múltiples veces dentro de una clase o estructura, mientras una clase abstracta sólo una vez.

Las interfaces pueden contener métodos, propiedades, eventos, índices o una

combinación de ellos, mas no constantes, operadores, constructores, finalizadores o tipos.

Los miembros de una interfaz son automáticamente públicos, de hecho, éstos no pueden

incluir ningún modificador de acceso, ni tampoco pueden ser estáticos.

Para implementar un miembro de interfaz, el miembro correspondiente de la clase o

estructura que lo implementa debe ser público, no estático, y tener el mismo nombre y firma

del miembro de la interfaz. Además, la clase o estructura debe proveer la implementación a

todos los miembros definidos dentro de la interfaz. Dicha implementación se realiza una sola

vez y solamente si la clase declara a la interfaz como parte de la definición de la clase,

empleando el operador : (dos puntos).

public class AvePropiedades : IAve {

public int Patas=2; public int Alas=2; public int Cola=1; public string Nombre{ get; private set; }

public AvePropiedades(string nombre) { this.Nombre = nombre; } public void Volar() { Console.WriteLine ("Volar"); }

public void Comer() { Console.WriteLine ("Comer"); }

}

Hay que destacar que, si la interfaz es implementada por una clase base, todas las clases

hijas heredan esa implementación:

public class Ave : AvePropiedades { public Ave(string N) : base(N) { } }

Page 99: PROGRAMACIÓN ORIENTADA A OBJETOS (072-2103) · PROGRAMACIÓN ORIENTADA A OBJETOS (072-2103) Unidad I: Introducción 1.1 Historia del Computador 1.2 Lenguajes de Programación 1.3

Programación Orientada a Objetos

99

Ejemplo 6.6: Elabore un programa que implemente la interfaz IAve.

class MainClass

{

public static void Main(string[] args)

{

Ave canario = new Ave ("Canario");

Ave cuervo = new Ave ("Cuervo");

MainClass main = new MainClass();

main.imprimir(canario);

main.imprimir(cuervo);

Console.ReadKey();

}

public void imprimir(Ave ave)

{

Console.WriteLine("Soy un {0} tengo {1} Pata(s), {2} Ala(s) y {3}

Cola(s)", ave.Nombre, ave.Patas, ave.Alas, ave.Cola);

Console.WriteLine("Puedo " + ave.Comer());

Console.WriteLine("y tambien puedo " + ave.Volar());

}

}

¿Cuándo usar interfaces?

En general, siempre que se tengas o se prevea que se puede tener más de una clase para hacer

lo mismo: usar interfaces. Es mejor pecar de exceso que de defecto en este caso. No hay que

preocuparse por penalizaciones de rendimiento en la aplicación porque no las hay.

No significa que toda clase deba implementar una interfaz obligatoriamente, muchas

clases internas no lo implementarán, pero en el caso de las clases públicas (visibles desde el

exterior) es algo que debería tomarse en consideración. Además, pensar en la interfaz antes

que en la clase en sí, es pensar en lo que debe hacerse en lugar de pensar en cómo debe

hacerse. Usar interfaces permite a posteriori cambiar una clase por otra que implemente la

misma interfaz y poder integrar la nueva clase de forma mucho más fácil (sólo se debe

modificar donde instanciar los objetos, el resto de código queda igual).

6.6 Ejercicios propuestos

1) Elija algún ejercicio de las unidades VI o V y realice los siguientes cambios:

Page 100: PROGRAMACIÓN ORIENTADA A OBJETOS (072-2103) · PROGRAMACIÓN ORIENTADA A OBJETOS (072-2103) Unidad I: Introducción 1.1 Historia del Computador 1.2 Lenguajes de Programación 1.3

Programación Orientada a Objetos

100

a. Defina los atributos internos utilizando los operadores get y set.

b. Utilice los modificadores de parámetros en las llamadas a funciones.

c. Si un bloque de código supera las 10líneas, utilice la directiva #region.

2) Tome algún ejercicio iterativo de la unidad VI o V y conviértalo a su equivalente

iterativo.

3) Evalúe el método recursivo para resolver el juego Torres de Hanoi y escriba sus

conclusiones al respecto.

4) Elabore un programa a elección, donde utilice los conceptos de herencia e interfaz (puede

realizar 2 programas si lo desea).

5) Preparación para OAD: Lea sobre las Listas Enlazadas Simples (puede conseguir

material online) y evalúe la definición de su nodo y métodos de inserción/borrado.

Coloque sus conclusiones al respecto. Igualmente responda: ¿Ha sido ventajoso el uso de

una clase autoreferenciada? ¿Hay una forma más sencilla de implementar una lista

enlazada? ¿Por qué?. NOTA: No tomar en cuenta el método List ni sus variantes.