ER ICA ÁM
ET
CI
BE
RO
www.pdftron.com
Lección 1
Introducción a la programación Matriz de dominio de objetivos Descripción de dominio de objetivos
Comprender la programación de computadoras
Comprender el almacenamiento y los tipos de datos computacionales
1.1
Comprender las estructuras de decisión
Comprender estructuras de decisión computacionales
1.2
Comprender las estructuras de repetición
Identificar el método apropiado para el manejo de las repeticiones
1.3
Comprender el manejo de excepciones
Comprender el manejo de errores
1.4
ÁM
Términos clave
Número de dominio de objetivos
ER ICA
Habilidad tecnológica
www.pdftron.com • Diagrama de fujo • Ciclo for • Ciclo foreach • If • If-else • Operador
• Programa • Recursión • Switch • Try-catch-fnally • Variable • Ciclo while
BE
RO
• Algoritmo • Vector • Constante • Tabla de decisión • Ciclo do-while • Excepción
CI
Como desarrollador de software para corporación Northwind, parte de su trabajo es desarrollar programas de computadora que resuelvan problemas de la compañía. Algunos de estos ejemplos son: analizar órdenes de clientes y determinar descuentos, así como actualizar la información del almacén sobre los miles de productos en el inventario y elaborar un reporte interactivo que permita al usuario ordenar y fltrar los datos.
ET
Es de suma importancia asegurarse que sus programas se diseñen de acuerdo a las especifcaciones. También necesita asegurarse que todos los cálculos sean precisos y completos. Los programas que desarrolle deberán ser robustos y capaces de mostrar mensajes de error pero también de continuar con el procesamiento. El lenguaje de programación que utilice le proporcionará una variedad de herramientas y técnicas que le permitirán llevar a cabo las tareas. Con base en la tarea, seleccione el tipo de datos y las estructuras de control que mejor se adecuen para solucionar el problema.
2
Lección 1
Comprender la programación de computadoras È EN RESUMEN
Un programa de computadora es un conjunto de instrucciones precisas para llevar a cabo una tarea. En esta sección aprenderá a escribir algoritmos y programas de computadoras para solucionar un problema dado. Además de escribir su primer programa computacional utilizando el lenguaje de programación C#, también aprenderá la estructura básica de un programa, así como a compilarlo, ejecutarlo, ingresar datos y generar resultados de un programa.
ER ICA
Introducción a los Algoritmos
Un algoritmo es un conjunto de pasos ordenados y fnitos para resolver un problema dado.
El término algoritmo se refere a un método para solucionar problemas. Los algoritmos se pueden describir con palabras pero podrían suceder errores de comprensión relacionados con la complejidad y ambigüedad de un idioma natural.
ÁM
De ahí que los algoritmos generalmente se escriban en formatos más simples y precisos como diagramas de fujo, árboles de decisión y tablas de decisión que representen un algoritmo como un diagrama, tabla o gráfco. Estas técnicas se utilizan generalmente antes de escribir los programas para contar con una mejor comprensión de la solución.
www.pdftron.com RO
Estas herramientas para el desarrollo de algoritmos pueden ayudarlo a expresar la solución para un problema de manera fácil, pero no se pueden ingresar directamente en la computadora. Para que una computadora entienda su algoritmo, necesita escribir un programa de computadora de manera formal utilizando un lenguaje de programación como C# sobre el cual aprenderá en la siguiente sección.
BE
Esta sección se enfoca en dos técnicas para algoritmos, los diagramas de fujo y las tablas de decisión que son más precisas que un idioma natural pero menos formales y más fáciles de utilizar que un lenguaje de programación.
Introducción a los diagramas de flujo
CI
Un diagrama de fujo es una representación gráfca de un algoritmo. Un diagrama de fujo se realiza generalmente utilizando símbolos estandarizados para diagramas de fujo. Algunos de los símbolos comunes de diagramas de fujo aparecen en la tabla 1-1.
ET
Tabla 1-1
Símbolos de diagramas de flujo comunes
Símbolo del diagrama de flujo
Descripción Inicio o final de un algoritmo Un proceso u operación computacional Operación de entrada o salida Operación de toma de decisión
Especifica el flujo de control
Introducción a la programación
3
Por ejemplo, la fgura 1-1 muestra un diagrama de fujo que ingresa dos números, los compara y produce como salida el número mayor. Figura 1-1
ÁM
ER ICA
Un diagrama de flujo sencillo que compara dos números y da como resultado el mayor
Como puede ver, este diagrama de fujo muestra en el orden correcto todos los pasos necesarios para llevar a cabo la operación. El control inicia con el símbolo Inicio y termina con el símbolo Fin. El proceso y operaciones de entrada/salida siempre tienen una sola entrada pero varias salidas. Se puede evaluar un diagrama de fujo llevando a cabo una “dry run” (ejecución seca). En ella se traza de forma manual lo pasos en el diagrama de fujo para revisar si los datos siguen la ruta correcta.
RO
www.pdftron.com Introducción a las tablas de decisión
ET
CI
BE
Cuando se requiere de una gran cantidad de condiciones en un algoritmo, las tablas de decisión son un formato más compacto y legible para representarlo. La tabla 1-2 muestra una tabla de decisión para calcular un descuento. Esta tabla genera un porcentaje de descuento dependiendo de la cantidad de producto que se haya comprado. La línea en negrita en la tabla divide la tabla de decisión en cuatro cuadrantes. El primer cuadrante en la izquierda superior especifca las condiciones (Cantidad <10, etc.). El segundo cuadrante (superior derecha) especifca las reglas. Las reglas son las posibles combinaciones que resultan de cada condición. El tercer cuadrante (inferior izquierda) especifca la acción (en este caso el Descuento) y el último cuadrante especifca los elementos de la acción que corresponden a cada regla.
Tabla 1-2
Cantidad < 10
S
N
N
N
Una tabla de decisión que calcula descuentos
Cantidad < 50
S
S
N
N
Cantidad < 100
S
S
S
N
Descuento
5%
10%
15%
20%
****Note las líneas en negritas que dividen la tabla en cuadrantes***** Para descubrir cual acción se debe aplicar, se evalúa cada condición para encontrar la regla coincidente y seleccionar la acción especifcada en la columna con la regla coincidente. Por ejemplo, si el valor de la cantidad es 75 entonces la primera regla evalúa un No, la segunda regla evalúa un No y la tercera evalúa un Sí. Por lo que debe seleccionar el elemento de la acción de la columna (N, N, S) que establece un descuento de 15%.
4
Lección 1
Introducción a C# C# es un lenguaje de programación de alto nivel muy popular que le permite escribir programas de computadora en un formato legible para los humanos. C# es parte de .NET Framework y se benefcia del tiempo de ejecución y librerías de clase que se encuentran en .NET Framework. Como se mencionó en la sección anterior, las computadoras necesitan de instrucciones precisas y completas para llevar a cabo una tarea. Este conjunto de instrucciones se conocen como programas de computadora o simplemente programas.
ER ICA
En un nivel muy básico, las computadoras utilizan el sistema binario para representar información y código. En el sistema binario, cada valor se representa utilizando únicamente dos símbolos, 0 y 1. A un programa de computadora escrito en código binario se le conoce como código binario.
ÁM
Utilizar el código binario para programar una computadora es muy difícil para llevar a cabo cualquier tarea. Para simplifcar la programación, los científcos e ingenieros en computación desarrollaron varios niveles de abstracción entre la máquina y el humano. Estas abstracciones incluyen software, como los sistemas operativos, compiladores y varios sistemas en tiempo de ejecución, que asumen la responsabilidad de traducir un programa legible para los humanos en un programa legible para la máquina.
La mayoría de los programas modernos se encuentran escritos en un lenguaje de alto nivel como C#, Visual Basic y Java. Estos lenguajes le permiten escribir instrucciones precisas en un formato legible para los humanos. El compilador de lenguaje puede entonces traducir el lenguaje de alto nivel en un lenguaje de bajo nivel que pueda comprenderse en el sistema en tiempo de ejecución.
RO
www.pdftron.com BE
Cada lenguaje de programación cuenta con su propio conjunto de vocabulario y gramática (también conocido como sintaxis). En este curso, aprenderá a programar en C#, el cual es un lenguaje de programación en .NET Framework. .NET Framework cuenta con un ambiente en tiempo de ejecución para el programa C#. Framework también cuenta con librerías de clase que ofrecen una gran funcionalidad reutilizable que se puede utilizar directamente en su programa de C#. El .NET Framework
ET
CI
El .NET Framework cuenta con tres componentes principales: un ambiente en tiempo de ejecución, un conjunto de librerías de clase que ofrece una gran funcionalidad reutilizable y compiladores de lenguaje para C#, Visual Basic y Managed C++. El .NET Framework soporta diferentes lenguajes de programación así como lenguajes adicionales al sistema. Aun cuando la sintaxis y vocabulario de cada lenguaje pueda ser diferente, cada uno utiliza las librerías de clase base con las que cuenta el Framework.
En este curso utilizará un ambiente de desarrollo integrado (IDE) para desarrollar su código. Utilizará Visual Studio o la edición gratuita de Visual Studio Express para escribir su código. Cualquiera de estas herramientas le ofrece un ambiente altamente productivo para desarrollar y evaluar sus programas.
Introducción a la programación
5
Æ Escriba un programa en C# Tome Nota C# es un lenguaje de programación sensible a mayúsculas. Por ejemplo, si escribe Class en lugar de class, le resultará un error de sintaxis.
PREPÁRESE. Para escribir un programa en C#, realice lo siguiente: 1. Inicie Visual Studio. Seleccione Archivo y después Nuevo proyecto, Visual c#, Seleccione Aplicación de consola en Plantillas 2. Ingrese IntrodCS en el cuadro Nombre. Asegúrese que el cuadro de verificación Crear directorio para la solución se encuentre seleccionado e ingrese el nombre Lesson01 en el cuadro Nombre de la solución. Haga clic en Aceptar para crear el proyecto.
ER ICA
3. Después de crear el proyecto, notará que Visual Studio ha creado un archivo de nombre Program.cs y escrito una plantilla para usted. 4. Modifique la plantilla para que luzca como el siguiente código: using System; namespace Lesson01 { class Program {
ÁM
Otra Manera También puede ejecutar el programa si abre una ventana de línea de comandos (cmd.exe) y después navega a la carpeta de salida del proyecto, que de forma predeterminada es bin/debug bajo la ubicación del proyecto. Se puede iniciar el programa escribiendo el nombre del programa en la ventana de comandos y presionando Enter.
www.pdftron.com static void Main(string[] args) {
Console.WriteLine(“¡hola, mundo!”);
RO
}
}
}
BE
5. Seleccione Depurar, Iniciar sin depurar, o presione Ctrl+F5. 6. Observará el resultado del programa en una ventana de comandos, como aparece en la Figura 1-2.
Figura 1-2
ET
CI
Resultado del programa en una ventana
7. Presione una tecla para cerrar la ventana de línea de comandos. PAUSA. Deje el proyecto abierto para utilizarlo en el siguiente ejercicio.
Lección 1
Cuando seleccione la opción Depurar, Iniciar sin depurar y Visual Studio muestra automáticamente el mensaje “Presione una tecla para continuar…”. La ventana de línea de comandos permanece abierta para que pueda ver el resultado. Si selecciona la opción Depurar y después Iniciar depuración, la ventana de comandos se cierra tan pronto como se termina la ejecución del programa. Es importante saber que la opción Depurar e Iniciar depuración cuenta con capacidades de depuración como lo es la habilidad de pausar un programa en ejecución en un punto dado y revisar el valor de varias variables en memoria.
El programa que acaba de crear es muy sencillo pero resulta de utilidad para comprender la estructura de un programa, su construcción y ejecución. Primero comentemos sobre la parte de la construcción y ejecución. A continuación se menciona lo que sucede cuando selecciona la opción Depurar y posteriormente Iniciar sin depurar en el paso 5 del ejercicio anterior: 1. Visual Studio invoca el compilador de C# para traducir el código en un lenguaje de bajo nivel, en código de Lenguaje Intermedio Común (CIL). Este código de bajo nivel se almacena en un archivo ejecutable de nombre Lesson01.exe. El nombre del archivo resultante se puede cambiar al modificar las propiedades del proyecto. 2. A continuación, Visual Studio toma el resultado del proyecto y solicita al sistema operativo que lo ejecute. Aquí es cuando ve que la ventana de línea de comandos muestra el resultado.
ER ICA
Tome Nota
3. Cuando el programa termina, Visual Studio muestra el mensaje, “Presione una tecla para continuar…”. Observe que este mensaje sólo se genera cuando ejecuta el programa al utilizar la opción “Iniciar sin depurar”.
Si no utiliza un IDE como Visual Studio, puede compilar su programa de forma manual utilizando las herramientas en línea de comandos. Por supuesto, resulta mucho más fácil y rápido utilizar Visual Studio para evaluar sus programas.
ÁM
6
CI
BE
RO
www.pdftron.com Tome Nota
ET
Antes de que se pueda ejecutar el código en Lenguaje Intermedio Común (CIL), primero se debe traducir para la arquitectura de la máquina donde se ejecutará el código. El sistema en tiempo de ejecución de .NET Framework se encarga de esta traducción tras bambalinas utilizando un proceso llamado compilación just-intime.
Introducción a la programación
7
Comprender la estructura de un programa en C# En esta sección, aprenderá sobre los elementos fundamentales del programa en C# que creó en la sección anterior. La Figura 1-3 enlista el programa en el ejercicio anterior con números. Esta sección utiliza los números de línea para referirse a cada estructura del programa. Figura 1-3
ER ICA
Listado del programa con números de línea
Para habilitar la vista de los números de línea en Visual Studio, seleccione Herramientas y después Opciones. A continuación, expanda el nodo Editor de texto y seleccione C#. Finalmente, en la sección Mostrar, seleccione la opción Números de línea (active la opción Mostrar todas las configuraciones).
ÁM
Tome Nota
RO
www.pdftron.com BE
Un programa en C# está formado por una o más clases y otros tipos. Una clase es un conjunto de datos y métodos. El código en la Figura 1-3 defne una clase de nombre Program de las líneas 5 a la 11. Una clase se defne utilizando la palabra clave class seguida del nombre de la clase. El contenido de la clase se defne entre una llave de apertura ({) y una de cierre (}).
CI
La línea 3 defne un espacio de nombre, Lesson01. Los Espacios de nombres se utilizan para organizar clases e identifcarlas de forma única. El espacio de nombre y los nombres de las clases se combinan para crear un nombre de clase completamente calificado. Por ejemplo, el nombre de la clase completamente califcado para la clase Program es Lesson01. Program. C# requiere que el nombre de una clase completamente califcado sea único. Por lo tanto, no puede tener otro nombre de clase para Program con el nombre Lesson01, pero puede utilizar Program para otro nombre como Lesson02. La clase Program defnida en el nombre Lesson02 es identifcada de forma única utilizando su nombre de clase completamente califcado, Lesson02.Program.
Referencia cruzada
ET
Puede encontrar más información y otros tipos en la Lección 2.
El .NET Framework cuenta con una gran cantidad de clases organizadas en muchos espacios de nombres. El espacio de nombres System contiene algunas de las clases más comunes. Una de estas clases en el espacio de nombres System es Console. La clase Console ofrece funcionalidad de entrada y salida para la aplicación de consola. El código en la línea 9 se refere a la clase Console e invoca al método WriteLine. Para acceder al método WriteLine debe hacerlo de la siguiente manera: System.Console.WriteLine(“¡hola, mundo!”);
Lección 1
Tome Nota Todas las sentencias en C# deben terminar con un punto y coma (;). Tome Nota El método Main debe ser declarado como static. El método static es invocable en una clase aun cuando no se haya creado una instancia de la clase. Aprenderá más de este tema en la siguiente lección.
Puesto que los nombres de las clases aparecen con frecuencia en el código, escribir el nombre de la clase completamente califcados puede ser tedioso y hacer que los programas contengan exceso de palabras. Este problema se puede solucionar utilizando la directiva de C# using (vea el código en la línea 1). La directiva using le permite utilizar las clases en un espacio de nombres sin la necesidad de califcar completamente el nombre de la clase. La clase de Programa defne un solo método por el nombre Main (líneas 7 a la 10). Main es un método especial que también sirve como punto de entrada al programa. Cuando el tiempo de ejecución inicia un programa, siempre empieza en el método Main. Un programa puede tener muchas clases y cada clase puede tener muchos métodos, pero debería tener sólo un método Main. Un método puede a su vez llamar a otros métodos. En la línea 9, el método Main está llamando al método WriteLine de la clase System.Console para mostrar una cadena de caracteres en la ventana de línea de comandos. Esa es la forma en la cual aparece el mensaje.
ER ICA
8
Comprender las variables
ÁM
Las variables proporcionan almacenamiento temporal durante la ejecución de un programa.
www.pdftron.com int number = 10;
Cuando se declara una variable, se crea una ubicación en la memoria de la computadora lo sufcientemente grande para contener el valor de este tipo de dato. Por ejemplo, en una máquina de 32-bit, una variable de un tipo de datos int necesitará dos bytes de memoria. El valor de una variable se puede modifcar por otra asignación, como por ejemplo:
BE
El nombre de una variable debe empezar con una letra o un guión bajo y puede contener sólo letras, números y guiones bajos. El nombre de una variable no debe ser mayor a 255 caracteres. Una variable debe ser única dentro del ámbito en el cual se haya definido.
Las variables en C # son marcadores de posición utilizados para almacenar valores. Una variable tiene un nombre y un tipo de datos. El tipo de datos de la variable determina el valor que esta puede contener y el tipo de operaciones que se pueden desarrollar. Por ejemplo, la siguiente declaración crea una variable de nombre number del tipo de datos int y asigna un valor de 10 a la variable:
RO
Tome Nota
CI
number = 20;
Este código cambia el contenido de la ubicación en memoria identifcada por el nombre number.
ET
Comprender las constantes Las constantes son los campos de datos o variables locales cuyos valores no se pueden modifcar. Las constantes se declaran utilizando la palabra const. Una const se puede declarar de la siguiente forma: const int i = 10;
Aquí se declara una constante i del tipo de datos int y almacena un valor de 10. Una vez declarado, el valor de una constante no puede cambiar.
Introducción a la programación
9
Comprender los tipos de datos El tipo de datos especifca el tipo de valor con el cual se trabajará en el programa. El tipo de datos defne el tamaño en memoria necesario para almacenar la información y el tipo de operaciones que se pueden realizar con los datos.
Puede obtener más información sobre la creación de sus propios tipos de datos en la Lección 2.
Tabla 1-3
C# ofrece varios tipos de datos predefnidos que puede utilizar en sus programas. También puede defnir nuevos tipos al establecer una estructura de datos como una clase o un struct. Este capítulo se enfoca en algunos de los tipos de datos predefnidos más utilizados. La tabla 1-3 contiene algunos de los tipos de datos predefnidos más utilizados en C#. El tamaño mencionado en la tabla se refere a una computadora con longitudes de palabra de 32 bits. Para longitudes más grandes, como de 64 bits, los tamaños serán diferentes.
Tipo de dato byte
1 byte
char
2 byte
short
2 bytes
int
4 bytes
long
8 bytes
float
Rango de valores
0 a 255
U+0000 a U+ffff (caracteres Unicode)
-32,768 a 32,767
-2,147,483,648 a 2,147,483,647
-9,223,372,036,854,775,808 a 9,223,372,036,854,775,807
ÁM
Algunos tipos de datos predefinidos
Tamaño
ER ICA
Referencia cruzada
4 bytes
±1.5e−45 a ±3.4e38
www.pdftron.com Tome Nota
double
Las versiones sin signo de short, int y long son ushort, uint y ulong respectivamente. Los tipos sin signo tienen el mismo tamaño como las versiones con signo pero almacenan rangos mucho mayores sólo para valores positivos.
bool
±5.0e−324 a ±1.7e308
Verdadero o falso
-
Cero o más caracteres Unicode
RO
string
8 bytes
2 bytes
BE
Todos los tipos de datos mencionados en la tabla 1-3 son tipos de valores con excepción de string, el cual es un tipo de referencia. Las variables que se encuentran basadas directamente en los tipos de valores contienen el valor en sí. En el caso del tipo de referencia, la variable contiene la dirección de la ubicación en memoria donde se encuentran almacenados los datos. Aprenderá más sobre las diferencias entre los tipos de valores y referencias en la Lección 2.
CI
Comprender los Arreglos
ET
Un arreglo es un conjunto de elementos en donde cada uno de ellos se accede a través de un índice único. Un arreglo en C# se utiliza comúnmente para representar un conjunto de elementos de tipo similar. A continuación se incluye un ejemplo de una declaración de un arreglo: int[] numbers = { 1, 2, 3, 4, 5 };
Esta declaración crea un arreglo identifcado por el nombre numbers. Este arreglo puede almacenar un conjunto de cinco enteros. Esta declaración también inicializa cada uno de los elementos del arreglo del 1 al 5 respectivamente. Cualquier elemento del arreglo se puede acceder de forma directa utilizando un índice. En .NET Framework los índices de arreglo empiezan desde cero. Esto signifca que para acceder al primer elemento de un arreglo, se utiliza el índice 0, para acceder al segundo elemento se utiliza el índice 1 y así sucesivamente.
10
Lección 1
Tome Nota El tema de los arreglos se cubre a mayor detalle en la Lección 3, Comprender el desarrollo de software en general.
Para acceder a un elemento individual de un arreglo, se utiliza el nombre del arreglo seguido del índice dentro de corchetes. Por ejemplo, numbers[0] devuelve el valor 1 del arreglo declarado anteriormente y numbers[4] devuelve el valor 5. Es ilegal acceder a un arreglo fuera de sus límites defnidos. Por ejemplo, obtendrá un error si intenta acceder al elemento del arreglo numbers[5].
Comprender los operadores
ER ICA
Los operadores son símbolos que especifcan la operación a llevar a cabo con los operandos y regresar un resultado. Ejemplos de operadores incluyen +, -, *, /, etc., y los operandos pueden ser variables, constantes, literales, etc. Dependiendo de cuantos operandos se encuentren involucrados, hay varios tipos de operadores:
• •
Operadores unarios: Los operadores unarios trabajan sólo con un operando. Ejemplos incluyen ++x, x++, o isEven, donde x es de tipo de datos integer y isEven es un tipo de datos booleano. Operadores binarios: Los operadores binarios toman dos operandos. Por ejemplo, x + y o x > y. Operadores ternarios: Los operadores ternarios toman tres operandos. Sólo hay un operador ternario, ?:, en C#.
ÁM
•
www.pdftron.com RO
Frecuentemente las expresiones involucran más de un operador. En este caso, el compilador necesita determinar cuál operador toma precedencia sobre otro. La tabla 1-4 contiene los operadores en C# en orden de precedencia. Entre más arriba se encuentre el operador en la tabla, más alta es su precedencia. Los operadores con precedencia más alta son evaluados antes que los de baja. Los operadores que aparecen en la misma fla tienen la misma .
Tabla 1-4
Categoría
BE
Precedencia de operadores
Primario
ET
CI
Unario
Operadores
x.y f(x) a[x] x++ x-- new typeof checked unchecked + - ! ~ ++x --x (T)x
Multiplicativo
* / %
Aditivo
+ -
Desplazamiento
<< >>
Comprobación de tipos y relacionales
< > <= >= is as
Igualdad
== !=
AND lógico
&
XOR lógico
^
Logical OR
|
AND Condicional
&&
OR Condicional
||
Condicional
?:
Asignación
= *= /= %= += -= <<= >>= &= ^= |=
Introducción a la programación
11
El operador de incremento unario (++) agrega 1 al valor de un identifcador. De igual manera los operadores de decremento (--) substraen 1 al valor de un identifcador. Los operadores de incremento y decremento unario se pueden utilizar ya sea como prefjos o sufjos. Por ejemplo: int x = 10; x++; //valor de x es ahora 11 ++x; // valor de x es ahora 12
ER ICA
Sin embargo, la forma en la cual funcionan los operadores de incremento y decremento cuando se utilizan como parte de una asignación puede afectar los resultados. Cuando los operadores unarios de incremento y decremento se utilizan como prefjos, el valor actual del identifcador se regresa antes del incremento o decremento. Por el contrario, cuando se utilizan como sufjos, el valor del identifcador se regresa después del incremento o decremento. Para comprender lo anterior, considere el siguiente código: int y = x++; // el valor de y es 12
ÁM
int z = ++x; // el valor de z es 14
Aquí en la primera sentencia, el valor de x se regresa antes del incremento. Como resultado, después de que se ejecuta la sentencia, el valor de y es 12 y el valor de x es 13.
www.pdftron.com RO
En la segunda sentencia, el valor de x se incrementa antes de regresar su valor para la asignación. Por lo tanto, después de ejecutar la sentencia, el valor tanto de x como de z es 14.
Comprender los métodos
BE
Los métodos sonbloques de código que contienen series de sentencias. Los métodos pueden recibir entradas vía argumentos y pueden regresar un valor a quien los invoca.
CI
; ¿Listo para la certificación?
En la lista de código anterior, aprendió sobre el método Main. Los métodos se encuentran donde están las acciones en un programa. Un método es un conjunto de sentencias que se ejecutan cuando se invoca el método.
ET
¿Comprende los elementos básicos de la programación como las variables, tipos de datos, operadores y métodos? -1.1
El método Main no regresa un valor, lo cual se indica utilizando la palabra void. Si un método fuera a regresar un valor, se colocaría un tipo de datos apropiado del valor retornado en lugar de void.
Los miembros de la clase pueden tener modifcadores como static, public y private. Estos modifcadores especifcan cómo y dónde se pueden acceder los miembros de la clase. Aprenderá más sobre estos modifcadores en la Lección 2.
12
Lección 1
Comprender las estructura de decisión È EN RESUMEN
Las estructuras de decisión introducen la habilidad de toma de decisiones al programa, también le permiten diversifcarse a diferentes secciones del código dependiendo del valor verdadero de una expresión booleana.
ER ICA
Las estructuras de decisión en C# son if, if-else y switch. En las siguientes secciones veremos cada una de estas sentencias a detalle.
La sentencia if
La sentencia if ejecutará una secuencia de sentencias dada sólo si la expresión booleana correspondiente es verdadera.
A veces en su programa, querrá que una secuencia de sentencias se ejecute sólo si una condición es verdadera.
ÁM
En C# puede realizarlo al utilizar la sentencia if. Considere los siguientes pasos para crear un programa que utilice la sentencia if.
www.pdftron.com RO
Æ Uso de la sentencia if
PREPÁRESE. Para utilizar la sentencia if, realice lo siguiente:
1. Agregue un nuevo proyecto de aplicación de consola (de nombre if_Statement) a la solución Lesson01.
BE
2. Agregue el siguiente código al método Main de la clase Program.cs: int number1 = 10; int number2 = 20;
ET
CI
if (number2 > number1) {
Console.WriteLine(“number2 es mayor que number1”);
} 3. Seleccione Depurar, Iniciar sin depurar, o presione Ctrl+F5. 4. Verá el resultado del programa en la ventana de línea de comandos. 5. Presione una tecla para cerrar la ventana de consola. PAUSA. Deje el proyecto abierto para utilizarlo en el siguiente ejercicio.
Este código es funcionalmente equivalente al diagrama de fujo de la Figura 1-4.
Introducción a la programación
Figura 1-4
13
INICIO
El diagrama de flujo equivalente a la sentencia if
n1 = 10
n2 = 20
No
ER ICA
n2 > n1? Si
Salida “n2 es > n1”
ÁM
FIN
Aquí la sentencia de salida sólo se ejecutará si la expresión booleana en el paréntesis es verdadera. Si la expresión es falsa, el control pasa a la siguiente sentencia que sigue de la sentencia if.
www.pdftron.com RO
En C#, los paréntesis alrededor de la condición son obligatorios, no así las llaves, estas son opcionales si sólo hay una sentencia en el bloque de código. Por lo tanto, la sentencia if anterior equivale a: if (number2 > number1)
BE
Console.WriteLine(“number2 es mayor que number1”);
Por otro lado, observe este ejemplo:
ET
CI
if (number2 > number1) Console.WriteLine(“number2 es mayor que number1”);
Console.WriteLine(number2);
Aquí, sólo la primera sentencia Console.WriteLine es parte de la sentencia if. La segunda sentencia Console.WriteLine siempre se ejecutará no importando el valor de la expresión booleana. Para tener una mejor claridad, es mejor encerrar la sentencia que se vaya a ejecutar condicionalmente entre llaves. Las sentencias if también se pueden anidar dentro de otras sentencias if, como se muestra en el siguiente ejemplo: int number1 = 10;
14
Lección 1
if (number1 > 5) { Console.WriteLine(“number1 es mayor que 5”); if (number1 < 20) {
} }
ER ICA
Console.WriteLine(“number1 es menor que 20”);
Puesto que las dos condiciones se evalúan como verdadero, se generará el siguiente resultado: number1 es mayor que 5
ÁM
number1 es menor que 20
www.pdftron.com Pero ¿qué sucedería si el valor de number1 fuera 25 en lugar de 10 antes de la ejecución de la sentencia exterior? En este caso, la primera expresión booleana se evaluaría como verdadera pero la segunda se evaluaría como falsa y se generaría el siguiente resultado:
La sentencia if-else
RO
number1 es mayor que 5
BE
La sentencia if-else le permite a su programa llevar a cabo una acción si la expresión booleana se evalúa como verdadera y una acción diferente si la expresión se evalúa como falsa. Considere los siguientes pasos para crear un programa que utiliza una sentencia if-else.
ET
CI
Æ Uso de la sentencia if-else
PREPÁRESE. Para utilizar una sentencia if-else, realice lo siguiente:
1. Agregue un nuevo proyecto de aplicación de consola (de nombre ifelse_Statement) a la solución Lesson01. 2. Agregue el siguiente código al método Main de la clase Program.cs:
TestIfElse(10); 3. Agregue el siguiente método a la clase Program.cs: public static void TestIfElse(int n) { if (n < 10) {
Introducción a la programación
es menor que 10”);
es menor que 20”);
es menor que 30”);
ER ICA
Console.WriteLine(“n } else if (n < 20) { Console.WriteLine(“n } else if (n < 30) { Console.WriteLine(“n } else { Console.WriteLine(“n }
15
}
es mayor que o igual a 30”);
4. Seleccione Depurar, Iniciar sin depurar o presione Ctrl+F5.
5. Verá el resultado del programa en la ventana de comandos.
ÁM
6. Presione una tecla para cerrar la ventana.
www.pdftron.com 7. Modifique el código del método Main para invocar el método TestIfElse con valores diferentes. Observe cómo se ejecuta una bifurcación de la sentencia if-else como resultado de sus cambios.
RO
PAUSA. Deje el proyecto abierto para utilizarlo en el siguiente ejercicio.
BE
El código en el método TestIfElse combina varias sentencias if-else para evaluar varias condiciones. Si el valor de n es 25, entonces las primeras dos condiciones (n < 10 y n < 20) se evaluarán como falsas pero la tercera condición (n<30) se evaluará como verdadera. Por lo tanto, el método imprimirá el siguiente resultado: n es menor que 30
Este programa en C# equivale al diagrama de fujo en la Figura 1-5.
Figura 1-5
ET
CI
Diagrama de flujo equivalente a la sentencia if-else
INICIO
n < 10?
Si
Salida “n < 10”
Si
Salida “n < 20”
Si
Salida “n < 30”
No
n < 20? No
n < 30? No
Salida “n >= 30”
FIN
16
Lección 1
La sentencia switch La sentencia switch permite una bifurcación múltiple. En muchos casos, el uso de una sentencia switch puede simplifcar una combinación compleja de sentencias if-else.
La expresión que sigue a la sentencia case debe ser una expresión constante y debe ser del mismo tipo de datos de la expresión del switch.
ER ICA
Tome Nota
La sentencia switch consiste de la palabra reservada switch, seguida de una expresión en paréntesis, seguida de un bloque para el mismo. El bloque del switch puede incluir una o más sentencias case o una sentencia default. Cuando se ejecuta la sentencia switch, dependiendo del valor de la expresión del switch, se transfere el control a una sentencia case coincidente. Si la expresión no coincide con ninguna sentencia case, el control se transfere a la sentencia default. La expresión del switch debe ir entre paréntesis. Considere los siguientes pasos para crear un programa que utiliza una sentencia switch para evaluar expresiones simples.
Æ Uso de la sentencia switch
ÁM
PREPÁRESE. Para utilizar la sentencia switch, realice lo siguiente:
1. Agregue un nuevo proyecto de aplicación de consola (de nombre switch_Statement) a la solución Lesson01.
www.pdftron.com 2. Agregue el siguiente código al método Main de la clase Program.cs:
RO
TestSwitch(10, 20, ‘+’);
3. Agregue el siguiente método a la clase Program.cs:
public static void TestSwitch(int op1, int op2, char opr)
BE
{
int result;
ET
CI
switch (opr) {
case ‘+’: result = op1 + op2; break; case ‘-’: result = op1 - op2; break; case ‘*’:
Introducción a la programación
17
result = op1 * op2;
Tome Nota El método Console. Write puede utilizar cadenas de formato como “Resultados: {0}” para dar formato al resultado. Aquí la cadena {0} representa el primer argumento que sigue a la cadena de formato. En el método TestSwitch, la cadena de formato “{0}” se reemplaza con el valor del siguiente argumento, result.
break; case ‘/’: result = op1 / op2;
default:
ER ICA
break;
Console.WriteLine(“Operador desconocido”); return; }
Console.WriteLine(“Resultado: {0}”, result);
}
ÁM
return;
www.pdftron.com 4. Seleccione Depurar, Iniciar sin depurar, o presione Ctrl+F5.
5. Verá el resultado del programa en la ventana de comandos.
RO
6. Presione una tecla para cerrar la ventana.
7. Modifique el código del método Main para llamar al método TestSwitch con valores diferentes. Observe cómo se ejecuta una bifurcación diferente de la sentencia switch como resultado de sus cambios.
BE
PAUSA. Deje el proyecto abierto para utilizarlo en el siguiente ejercicio.
ET
CI
Aquí, el método TestSwitch acepta dos operandos (op1 y op2) y un operador (opr) y evalúa la expresión resultante. El valor de la expresión switch se compara con las sentencias case en el bloque del switch. Si existe una coincidencia, se ejecutan las sentencias del case correspondiente. Si no hay coincidencias, el control se transfere a la bifurcación opcional default.
Hay una sentencia break después de cada case. La sentencia break termina la sentencia switch y transfere el control a la siguiente sentencia fuera del bloque del switch. Al utilizar un break se asegura que sólo se ejecute una bifurcación y evita errores de programación. De hecho, si coloca código después de la sentencia case, debe incluir un break (u otra sentencia de transferencia de control como el return) para asegurarse que el control no se transfera de un case a otro.
Por el contrario, si no hay código en la sentencia case, está bien si el control pasa a la sentencia case subsecuente. El siguiente código demuestra que tan útil puede ser esto: public static void TestSwitchFallThrough() {
Lección 1
DateTime dt = DateTime.Today;
Tome Nota Puede decidir entre utilizar sentencias ifelse o una sentencia switch dependiendo de la naturaleza de comparación y legibilidad del código. Por ejemplo, el código del método TestIfElse toma decisiones con base en las condiciones que son más apropiadas de utilizar con las sentencias if-else. En el método TestSwitch, las decisiones se basan en valores constantes, por lo que el código es mucho más legible en una sentencia switch.
switch (dt.DayOfWeek) { case DayOfWeek.Monday: case DayOfWeek.Tuesday:
ER ICA
case DayOfWeek.Wednesday: case DayOfWeek.Thursday: case DayOfWeek.Friday:
Console.WriteLine(«Hoy es un día laboral»); break; default:
Console.WriteLine(«Hoy es un día de fn de semana»);
ÁM
18
www.pdftron.com break;
}
}
¿Comprende las estructuras de decisión computacionales como las bifurcaciones y la repetición? -1.2
Aquí si el valor de la expresión dt.DayofWeek es DayOfWeek.Monday, entonces existe una coincidencia con el primer case, pero puesto que no hay código (o una sentencia de transferencia de control, la ejecución continúa a la siguiente sentencia, resultando en la aparición del mensaje “Hoy es un día laboral” en la ventana de consola.
BE
RO
; ¿Listo para la certificación?
CI
Comprender las estructuras de repetición
ET
È EN RESUMEN
C# cuenta con cuatro estructuras de control diferentes que permite a los programas llevar a cabo tareas repetitivas: el ciclo while, el do-while, el for y el foreach. Estas sentencias de control de repetición se pueden utilizar para ejecutar las sentencias dentro el cuerpo del ciclo una cantidad de veces dependiendo de los criterios de terminación del ciclo. Un ciclo también puede interrumpirse utilizando una sentencia de transferencia de control que asigne el control fuera del ciclo. Estas sentencias son break, goto, return o throw. La sentencia continue se puede utilizar para pasar el control a la siguiente iteración del ciclo sin salir de este.
Introducción a la programación
19
Comprender el ciclo while El ciclo while ejecuta repetidamente un bloque de sentencias hasta que una expresión booleana se evalúe como falsa. La forma general de un ciclo while es while (boolean test) sentencia
Puesto que la evaluación booleana se lleva a cabo antes de la ejecución del ciclo, es posible que el cuerpo del while nunca se ejecute. Esto pasa si la evaluación resulta falsa desde la primera vez. Considere los siguientes pasos para crear un programa que utiliza la sentencia while.
ÁM
La evaluación booleana debe colocarse entre paréntesis. Si se ejecuta más de una sentencia como parte del ciclo while, se deben colocar entre llaves.
Aquí, se lleva a cabo una evaluación booleana al principio del ciclo. Si es verdadero, se ejecuta el cuerpo del ciclo y se realiza de nuevo la evaluación. Si la evaluación resulta en un valor falso, se termina el ciclo y el control se transfere a la siguiente sentencia después del ciclo.
ER ICA
Tome Nota
www.pdftron.com Æ Uso de la sentencia while
RO
PREPÁRESE. Para utilizar la sentencia while, lleve a cabo las siguientes tareas:
1. Agregue un nuevo proyecto de aplicación de consola (de nombre while_Statement) a la solución Lesson01.
2. Agregue el siguiente código al método Main de la clase Program.cs:
BE
WhileTest();
3. Agregue el siguiente método a la clase Program.cs:
CI
private static void WhileTest() {
ET
int i = 1; while (i <= 5) { Console.WriteLine(“El valor de i = {0}”, i); i++; }
}
20
Lección 1
4. Seleccione Depurar después Iniciar sin depurar, o presione Ctrl+F5. 5. Verá el resultado del programa en la ventana de línea de comandos. 6. Presione una tecla para cerrar la ventana. PAUSA. Deje el proyecto abierto para utilizarlo en el siguiente ejercicio.
El valor de i = 1 El valor de i = 2
ÁM
El valor de i = 3
ER ICA
En este ejercicio, a la variable i se le asigna el valor 1. A continuación, se evalúa la condición del ciclo while. Puesto que la condición es verdadera (1<=5), se ejecuta el código del bloque de sentencias while. El valor de i se escribe en la ventana de línea de comandos y el valor de i se incrementa en 1, por lo que ahora vale 3. El control pasa entonces de vuelta a la sentencia while y la condición se evalúa de nuevo. Puesto que la condición sigue siendo verdadera (2<=5), el bloque de sentencias se ejecuta de nuevo. El ciclo continua hasta que el valor de i sea 6 y la condición en el ciclo while sea falsa (6<=5). El método anterior, cuando se ejecuta, genera el siguiente resultado.
El valor de i = 4
www.pdftron.com El valor de i = 5
Figura 1-6
ET
CI
BE
Diagrama de flujo equivalente al ciclo while
RO
El diagrama de fujo equivalente a este ciclo while se encuentra en la Figura 1-6.
INICIO
i=1
i <= 5? Si Imprimir i
i=i+1
FIN
No
Introducción a la programación
Tome Nota Para evitar un ciclo infinito, debe asegurarse que este se haya diseñado de forma tal que lleve a una terminación.
21
La sentencia en el ciclo, el cual incrementa el valor de i, juega un papel crítico. Si omite esa sentencia, la conducción de terminación nunca se alcanzará y se tendrá un ciclo infnito. En la mayoría de los casos, para tener un ciclo while bien diseñado, debe contar con tres partes: 1. Inicialización: El inicializador establece el contador del ciclo en un valor inicial correcto. En el ejemplo anterior, la variable i se establece en 1 antes de que inicie el ciclo.
2. Evaluación del ciclo: La evaluación del ciclo especifca la condición de terminación para el ciclo. En el ejemplo anterior, la expresión (i>=5) es la expresión de condición.
ER ICA
3. Expresión de terminación: La expresión de terminación cambia el valor del contador del ciclo de forma tal que se alcance la condición de terminación. En el ejemplo anterior, la expresión i++ es la expresión de terminación.
Comprender el ciclo do-while
El ciclo do-while ejecuta repetidamente un bloque de sentencias hasta que una expresión booleana específca se evalúe como falsa. El ciclo do-while evalúa la condición al fnal del ciclo.
Tome Nota
ÁM
El ciclo do-while es similar al while, pero a diferencia de este, el cuerpo del ciclo do-while se ejecuta al menos una vez.
www.pdftron.com La forma general del ciclo do-while es do
RO
sentencia
while (evaluación booleana);
Considere los siguientes pasos para crear un programa que utilice la sentencia do-while.
BE
La evaluación booleana se debe colocar entre paréntesis. Si se necesita ejecutar más de una sentencia como parte del ciclo do-while, se deben colocar dentro de llaves.
ET
CI
Æ Uso de la sentencia do-while
PREPÁRESE. Para utilizar la sentencia do-while, realice lo siguiente: 1. Agregue un nuevo proyecto de aplicación de consola (de nombre dowhile_Statement) a la solución Lesson01.
2. Agregue el siguiente código al método Main de la clase Program.cs: DoWhileTest(); 3. Agregue el siguiente método a la clase Program.cs: private static void DoWhileTest() { int i = 1; do
22
Lección 1
{ Console.WriteLine(“El valor de i = {0}”, i); i++; } while (i <= 5);
ER ICA
}
4. Seleccione Depurar posteriormente Iniciar sin depurar, o presione Ctrl+F5. 5. Verá el resultado del programa en la ventana de línea de comandos. 6. Presione una tecla para cerrar la ventana.
PAUSA. Deje el proyecto abierto para utilizarlo en el siguiente ejercicio.
ÁM
En este ejercicio, después de que la variable i se asigna en 1, el control entra directamente en el ciclo. Se ejecuta el código dentro de la sentencia do-while. El valor de i se escribe en la ventana de línea de comandos y se incrementa en 1 por lo que el valor sube a 2. A continuación, se evalúa la condición del ciclo do-while. Como la condición aun es verdadera (2<=5), el control regresa a la sentencia do-while y el bloque de sentencias se ejecuta de nuevo. El ciclo continua hasta que el valor de i llega a 6 y la condición del do-while resulta falsa (6<=5). El método anterior, cuando se ejecuta, genera el mismo resultado que el método WhileTest.
www.pdftron.com RO
La elección entre un ciclo while y uno do-while depende de si se quiere o no que el ciclo se ejecute al menos una vez. Si quiere que el ciclo se ejecute cero o más veces, elija el ciclo while. Por el contrario, si desea que el ciclo se ejecute una o más veces, elija el ciclo dowhile.
BE
Comprender los ciclos
CI
El ciclo for combina los tres elementos de iteración: la expresión de inicialización, la expresión de condición de terminación y la expresión de conteo, de forma más legible.
ET
El ciclo for es similar al ciclo while; este permite que una o varias sentencias se ejecuten de forma repetida hasta que una expresión se evalúe como falsa. La forma general del ciclo for es:
Tome Nota
Las tres expresiones de control se deben colocar entre paréntesis. Si se necesita ejecutar más de una sentencia como parte del ciclo for, se deben colocar dentro de llaves.
for (init-expr; cond-expr; count-expr) sentencia
Como puede ver, el ciclo for combina las tres expresiones de control esenciales de la iteración, lo cual resulta en código más legible. El ciclo for es particularmente útil para crear iteraciones que se deben ejecutar una cantidad especifcada de veces. Considere los siguientes pasos para crear un programa que utilice la sentencia for.
Introducción a la programación
23
Æ Uso de la sentencia for PREPÁRESE. Para utilizar la sentencia for, realice las siguientes tareas: 1. Agregue un nuevo proyecto de aplicación de consola (de nombre for_Statement) a la solución Lesson01. 2. Agregue el siguiente código al método Main de la clase Program.cs: ForTest();
ER ICA
3. Agregue el siguiente método a la clase Program.cs: private static void ForTest() {
for(int i = 1; i<= 5; i++) {
}
ÁM
Console.WriteLine(“El valor de i = {0}”, i);
www.pdftron.com }
4. Seleccione Depurar y después Iniciar sin depurar o presione Ctrl+F5.
RO
5. Verá el resultado de su programa en la ventana de línea de comandos. 6. Presione una tecla para cerrar la ventana.
PAUSA. Deje el proyecto abierto para utilizarlo en el siguiente ejercicio.
BE
Cuando se ejecuta el método ForTest, se produce el mismo resultado que con el método WhileTest. Aquí, la variable i se crea dentro del ámbito del ciclo for y su valor se asigna en 1. El ciclo continúa mientras el valor de i sea menor o igual a 5. Después del cuerpo del ciclo, se evalúa count-expr y el control regresa a cond-expr,
CI
Todos las expresiones de control de un ciclo for son opcionales. Por ejemplo, se pueden omitir todas las expresiones para crear un ciclo infnito como el siguiente:
ET
for (; ;) {
//no hace nada }
Comprender los ciclos foreach El ciclo foreach es útil para la iteración a través de los elementos de un conjunto. El ciclo foreach puede concebirse como una versión mejorada del ciclo for para la
24
Lección 1
iteración a través de colecciones como arreglos y listas. La forma general de la sentencia foreach es la siguiente: foreach (TipoElemento elemento in colección) sentencia
ER ICA
Las expresiones de control para la sentencia foreach se deben colocar dentro de paréntesis. Si se tiene que ejecutar más de una sentencia como parte del ciclo foreach, se deben colocar dentro de llaves. Considere los siguientes pasos para crear un programa que muestre la manera en la cual el ciclo foreach proporciona una forma sencilla de realizar iteraciones en una colección.
Æ Uso de la sentencia foreach
PREPÁRESE. Para utilizar la sentencia foreach, realice lo siguiente:
1. Agregue un nuevo proyecto de aplicación de consola (de nombre foreach_Statement) a la solución Lesson01.
ÁM
2. Agregue el siguiente código al método Main de la clase Program.cs:
www.pdftron.com ForEachTest();
3. Agregue el siguiente método a la clase Program.cs:
RO
private static void ForEachTest() {
int[] numbers = { 1, 2, 3, 4, 5 };
BE
foreach (int i in numbers)
ET
CI
{
Console.WriteLine(“El valor de i = {0}”, i);
}
}
4. Seleccione Depurar y después Iniciar sin depurar o presione Ctrl+F5. 5. Verá el resultado de su programa en la ventana de línea de comandos. 6. Presione una tecla para cerrar la ventana. PAUSA. Deje el proyecto abierto para utilizarlo en el siguiente ejercicio.
En este ejercicio, el ciclo itera de forma secuencial a través de cada elemento de la colección y muestra el resultado en la ventana de línea de comandos. Este método genera el mismo resultado que el método ForTest.
Introducción a la programación
25
Comprender la recursividad La recursividad es una técnica de programación que causa que un método se invoque a sí mismo para computar un resultado.
ER ICA
La recursividad y la iteración se encuentran relacionadas. Se puede escribir un método que produzca los mismos resultados ya sea utilizando recursividad o iteraciones. Generalmente, la naturaleza del problema en sí, le ayudará a seleccionar entre una solución recursiva o iterativa. Por ejemplo, una solución recursiva es más elegante cuando puede defnir la solución de un problema en términos de una versión más compacta para el mismo problema. Para tener una mejor idea, tomemos el ejemplo de la operación factorial en matemáticas. La defnición recursiva general para el factorial de n (n!) es:
ÁM
De acuerdo con esta defnición, si el número es 0, el factorial es uno. Si el número es mayor a cero, el factorial es el número multiplicado por el factorial del siguiente número más pequeño. Por ejemplo, se puede desglosar 3! de la siguiente manera: 3! = 3 * 2! à 3 * 2 * 1! à 3 * 2 * 1 * 0! à 3 * 2 * 1 * 1 à 6.
www.pdftron.com RO
Considere los siguientes pasos para crear un programa que presente una solución recursiva para el problema factorial.
BE
Æ Uso del método recursivo
PREPÁRESE. Para utilizar el método recursivo, realice lo siguiente: 1. Agregue un nuevo proyecto de aplicación de consola (de nombre RecursiveFactorial) a la solución Lesson01.
ET
CI
2. Agregue el siguiente código al método Main de la clase Program.cs: Factorial(5);
3. Agregue el siguiente método a la clase Program.cs: public static int Factorial(int n) { if (n == 0) { return 1; }
//caso base
26
Lección 1
else { return n * Factorial(n - 1);
// caso recursivo
} } 4. Seleccione Depurar, Iniciar sin depurar, o presione Ctrl+F5.
ER ICA
5. Verá el resultado del programa en la ventana de línea de comandos. Presione una tecla para cerrar la ventana.
6. Modifique el método Main para pasar un valor diferente al método Factorial y observe los resultados. PAUSA. Deje el proyecto abierto para utilizarlo en el siguiente ejercicio.
Como se vio en el ejercicio anterior, una solución recursiva tiene dos partes principales: ; ¿Listo para la certificación?
El caso base: La parte que especifca la condición de terminación que no llama nuevamente al método. El caso base en el método Factorial es n == 0. Si no tiene un caso base en su algoritmo recursivo, se crea una recursión infnita. Una recursión infnita hará que su computadora se quede sin memoria y arrojará una excepción System.StackOverfowException. El caso recursivo: La parte que mueve el algoritmo hacia la clase base. El caso recursivo en el método Factorial es la parte del else, donde se llama nuevamente el método pero con un valor menor para progresar hacia el caso base.
ÁM
•
www.pdftron.com •
RO
¿Puede identificar apropiadamente los métodos para el manejo de las repeticiones? 1.3
È EN RESUMEN
BE
Comprender el manejo de excepciones
ET
CI
El .NET Framework soporta el manejo de excepciones para errores en tiempo de ejecución. En esta sección aprenderá a utilizar las excepciones try, catch, y fnally. Una excepción es una condición de error que ocurre durante la ejecución de un programa en C#. Cuando esto sucede, el tiempo de ejecución crea un objeto para representar el error y “lanzarlo”. A menos que “atrape” la excepción escribiendo el código correcto para manejar excepciones, la ejecución del programa terminará. Por ejemplo, si intenta dividir un entero entre cero, se lanzará una excepción DivideByZeroException. En el .NET Framework, una excepción se representa utilizando un objeto de la clase System.Exception o una de sus clases derivadas. Existen clases de excepción predefnidas que representan las situaciones de error más comunes como DivideByZeroException. Si se encuentra diseñando una aplicación que necesite lanzar excepciones específcas de aplicación, deberá crear clases de excepción personalizadas que se deriven de la clase System.Exception.
Introducción a la programación
27
Manejo de excepciones Para manejar excepciones, coloque el código que las lance dentro de un bloque try y coloque el código que maneje las excepciones dentro de un bloque catch. El siguiente ejercicio demuestra cómo utilizar un bloque try-catch para manejar una excepción. Este ejercicio utiliza el método File.OpenText para abrir un archivoarchioe en disco. Esta sentencia se ejecutará bien en un caso normal, pero si no se encuentra el archivo o permiso de lectura del mismo, se lanzará una excepción.
ER ICA
Æ Manejo de excepciones
PREPÁRESE. Para manejar excepciones, realice lo siguiente:
1. Agregue un nuevo proyecto de aplicación de consola (de nombre HandlingExceptions) a la solución Lesson01. 2. Agregue el siguiente código al método Main de la clase Program.cs: ExceptionTest();
Agregue el siguiente método a la clase Program.cs:
ÁM
3.
private static void ExceptionTest()
www.pdftron.com {
StreamReader sr = null;
RO
try {
Tome Nota
Console.WriteLine(sr.ReadToEnd());
CI
BE
La clase StreamReader es parte del espacio de nombres System. IO. Cuando este código se ejecuta, necesitará agregar una directiva using para el espacio de nombres System.IO.
sr = File.OpenText(@”c:\data.txt”);
}
catch (FileNotFoundException fnfe) { Console.WriteLine(fnfe.Message); } catch (Exception ex)
ET
{ Console.WriteLine(ex.Message); } }
4. Cree un archivo (“data.txt”) utilizando el Bloc de notas o Visual Studio en la unidad c:. Se puede crear el archivo en otra ubicación pero si lo hace, recuerde modificar la ubicación del archivo en el programa. Escriba algo de texto en el archivo. 5. Seleccione Depurar y después Iniciar sin depurar o presione Ctrl+F5. 6. Verá que el contenido del archivo de texto aparece en la ventana de línea de comandos.
28
Lección 1
Presione una tecla para cerrar la ventana.
Tome Nota En el método ExceptionTest, es incorrecto cambiar el orden de los dos bloques catch. Las excepciones más específicas necesitan enlistarse antes de las excepciones genéricas, de lo contrario ocurrirán errores de compilación.
7. Elimine el archivo data.txt y ejecute nuevamente el programa. Esta vez aparecerá una excepción a FileNotFoundException y aparecerá un mensaje en la ventana.
Tome Nota
La ejecución del código se detiene cuando ocurre una excepción. El tiempo de ejecución busca una sentencia catch que corresponda al tipo de excepción. Si el primer bloque catch no atrapa la excepción arrojada, el control se mueve al siguiente bloque catch y así sucesivamente. Si la excepción no se maneja en el método, el tiempo de ejecución revisa la sentencia catch en el código y continúa para el resto de la pila de llamadas.
ER ICA
Para manejar la excepción, se colocan la sentencias que pueden causar la excepción en un bloque try. Luego se agregan los bloques catch para manejar una o más excepciones. En este ejemplo, además de manejar la excepción FileNotFoundException, también utilizamos un bloque catch con más excepciones genéricas para obtener todas las otras excepciones. El nombre de la excepción para un bloque catch debe ir entre paréntesis. Las sentencias que se ejecutan cuando se obtiene una excepción deben ir entre llaves.
ÁM
Un bloque try debe tener al menos un bloque catch o un bloque finally asociado.
PAUSA. Deje el proyecto abierto para utilizarlo en el siguiente ejercicio.
Uso de try-catch-finally
www.pdftron.com RO
El bloque fnally se utiliza con el bloque try. El bloque fnally siempre se ejecuta sin importar si ocurre o no la excepción. El bloque fnally se utiliza con frecuencia para escribir código de limpieza.
BE
Cuando ocurre una excepción, con frecuencia signifca que algunas líneas de código no se ejecutaron luego de que ocurrió la excepción, lo cual puede dejar su programa en un estado inestable. Puede utilizar la sentencia fnally para garantizar que se ejecute código de limpieza. Esto puede involucrar el cerrar conexiones, liberar recursos o establecer variables a sus valores esperados. Observemos el código del siguiente ejercicio.
Æ Uso de try-catch-finally
ET
CI
PREPÁRESE. Para utilizar la sentencia try-catch-finally, realice lo siguiente:
1. Agregue un nuevo proyecto de aplicación de consola (de nombre trycatchfinally) a la solución Lesson01.
2. Agregue el siguiente código al método Main a la clase Program.cs: TryCatchFinallyTest(); 3.
Agregue el siguiente método a la clase Program.cs: private static void TryCatchFinallyTest() { StreamReader sr = null; try { sr = File.OpenText(@”c:\data.txt”);
Introducción a la programación
29
Console.WriteLine(sr.ReadToEnd()); } catch (FileNotFoundException fnfe) { Console.WriteLine(fnfe.Message); } {
ER ICA
catch (Exception ex) Console.WriteLine(ex.Message); } fnally {
if (sr != null) {
ÁM
sr.Close();
}
www.pdftron.com }
}
RO
4. Cree un archivo de texto (“data.txt”) utilizando el Bloc de notas o Visual Studio en la unidad c:. Se puede crear el archivo en otra ubicación pero recuerde modificar la ubicación del archivo en el programa. Escriba texto en el archivo. 5. Seleccione Depurar, Iniciar sin depurar o presione Ctrl+F5.
BE
6. Verá que el contenido del archivo de texto aparece en la ventana de línea de comandos. Presione una tecla para cerrar la ventana. 7. Elimine el archivo data.txt file y ejecute nuevamente el programa. Esta vez obtendrá un FileNotFoundException y aparecerá un mensaje en la ventana.
CI
; ¿Listo para la certificación?
ET
¿Comprende cómo manejar errores en sus programas? -1.4
En este ejercicio, el programa se asegura que el objeto StreamReader se cierre y que se liberen los recursos cuando se complete la operación. El código en el bloque fnally se ejecuta sin importar si aparece una excepción o no.
30
Lección 1
Matriz de resumen de habilidades En esta lección aprendió:
• •
•
ER ICA
•
Un algoritmo es un conjunto de pasos ordenado y fnito para solucionar un problema dado. Puede encontrar de utilidad expresar un algoritmo a través de un diagrama de fujo o de una tabla de decisión antes de desarrollar un programa de manera formal. El lenguaje de programación C# es parte del .NET Framework y se benefcia tanto del soporte de tiempo de ejecución y las librerías de clase incluidas en .NET Framework. Main es un método especial que también sirve como punto de entrada al programa. Cuando el tiempo de ejecución corre un programa, siempre inicia en el método Main. Las variables en C# son marcadores de posición utilizadas para almacenar valores. Una variable tiene un nombre y un tipo de datos. El tipo de datos de la variable determina el valor que esta puede contener y el tipo de operaciones en las cuales se puede utilizar. El tipo de datos determina el tamaño de memoria necesario para almacenar los datos el tipo de operaciones que se pueden llevar a cabo con la información. Los operadores son símbolos como +, -, *, /, que especifcan cual operación llevar a cabo con los operandos y regresar un resultado. Las sentencias if-else le permiten a su programa llevar a cabo una acción si la expresión booleana se evalúa como verdadera o una acción diferente si la expresión resulta ser falsa. La sentencia switch le permite contar con varias ramifcaciones. En la mayoría de los casos, una sentencia switch puede simplifcar una combinación compleja de sentencias if-else. C# tiene cuatro estructuras de control diferentes que le permite a sus programas llevar a cabo tareas repetitivas: el ciclo while, el do-while, el for y el foreach. El while y el do-while ejecutan de forma repetida un bloque de sentencias hasta que una expresión booleana específca se evalúe como falsa. El ciclo do-while evalúa la condición al fnal del ciclo. El ciclo for combina los tres elementos de iteración: la sentencia de inicialización, la condición de terminación y la sentencia de incremento/decremento en un código más legible. El ciclo foreach es útil para iterar los elementos de una colección. La recursión es una técnica de programación que hace que un método se llame a sí mismo para computar un resultado. El .NET Framework soporta el manejo de excepciones estándar y maneja errores en tiempo de ejecución. Para manejar las excepciones, se coloca código que arroja excepciones dentro de un bloque try y se coloca código que maneja las excepciones en un bloque catch. El bloque fnally se utiliza con el bloque try. El bloque fnally siempre se ejecuta sin importar si se arroja o no una excepción. El bloque fnally se utiliza con frecuencia para escribir código de limpieza.
ÁM
•
• •
BE
•
RO
www.pdftron.com •
ET
CI
• • • • •
•
Comprender los conceptos básicos de bases de datos
31
» Evaluación de conocimiento Complete los espacios en blanco Complete los siguientes enunciados escribiendo la palabra o palabras correctas en los espacios en blanco proporcionados. 1. La sentencia ______ selecciona la ejecución de una lista de sentencias teniendo una etiqueta asociada que corresponda al valor de una expresión.
ER ICA
2. El ciclo ______ evalúa la condición al fnal en lugar de hacerlo al principio del ciclo. 3. El único operador que toma tres argumentos es el operador ______.
4. El ciclo ______ representa la forma más compacta para iterar los elementos de una colección. 5. En una computadora de 32-bit, una variable del tipo de datos int ocupa ______ bytes de memoria. 6. Par acceder al primer elemento de un arreglo, se utilice un índice de _____.
ÁM
7. La ______ es una técnica de programación que causa que un método se llame a sí mismo para poder computar un resultado.
www.pdftron.com 8. Las ______ son los campos de datos o variables locales cuyos valores no se modifcan.
9. Cuando un algoritmo involucra grandes cantidades de condiciones, una ______ es un formato compacto y más legible para presentar el algoritmo.
RO
10. Un ______ es una representación gráfca de un algoritmo.
BE
Opción múltiple
Encierre la letra que corresponda a la respuesta correcta. 1. Si escribe el siguiente código:
ET
CI
int n = 20; int d = n++ + 5;
2. ¿Cuál será el valor de d después de ejecutar el código? a. b. c. d.
25 26 27 28
3. Si escribe el siguiente código: private static void WhileTest() { int i = 1;
32
Lección 1
while (i < 5) { Console.WriteLine(“El valor de i = {0}”, i); i++; }
ER ICA
}
4. ¿Cuántas veces se ejecutará el ciclo while en este código? a. b. c. d.
0 1 4 5
5. Si escribe el siguiente código: int number1 = 10;
ÁM
int number2 = 20;
www.pdftron.com if (number2 > number1)
Console.WriteLine(“number1”);
RO
Console.WriteLine(“number2”);
6. ¿Cuál resultado aparecerá después de ejecutar este código? number1 number2 number1 number2 number2 number1
BE
a. b. c. d.
ET
CI
7. En una sentencia switch, si ninguno de las sentencias case coincide con la expresión del switch, ¿a cuál sentencia se transfere el control? a. b. c. d.
break continue default return
8. Necesita escribir código que cierre una conexión a una base de datos. Necesita asegurarse que este código se ejecute siempre sin importar si ocurre o no una excepción. ¿Dónde debería escribir este código? a. b. c. d.
Dentro de un bloque try Dentro de un bloque catch Dentro de un bloque fnally Dentro de un método Main
9. Necesita almacenar valores con un rango de 0 a 255. Necesita también asegurarse que el programa minimice el uso de memoria. ¿Cuál tipo de datos debería utilizar
Comprender los conceptos básicos de bases de datos
33
para almacenar estos valores? a. b. c. d.
Byte Char Short Int
10. Si no tiene una clase base en su algoritmo recursivo, crea una recursión infnita. Una recursión infnita causará que su programa arroje una excepción. ¿Cuál excepción será esta? OutOfMemoryException StackOverfowException DivideByZeroException InvalidOperationException
ER ICA
a. b. c. d.
11. Se encuentra aprendiendo cómo desarrollar algoritmos repetitivos en C#: Escribe el siguiente método: private static void ForTest() {
ÁM
for(int i = 1; i < 5;)
www.pdftron.com {
Console.WriteLine(“El valor de i = {0}”, i);
RO
}
}
12. ¿Cuántas repeticiones llevará cabo este ciclo for? 0 4 5 infnito
BE
a. b. c. d.
ET
CI
13. ¿Cuál de las siguientes características de C# utilizaría para organizar el código y crear tipos globalmente únicos? a. b. c. d.
Assemblies Espacio de nombres Clase Tipo de datos
14. Al escribir el siguiente código: int[] numbers = {1, 2, 3, 4}; int val = numbers[1];
15. También crea una variable del tipo RectangleHandler como se muestra a continuación: RectangleHandler handler;
34
Lección 1
16. a. b. c. d.
¿Cuál es el valor de la variable val después de ejecutar el código? 1 2 3 4
» Evaluación de destreza
ER ICA
Escenario 1-1: Convierta una tabla de decisión en un Programa de C#
Se encuentra desarrollando una aplicación de facturación que calcula los porcentajes de descuento con base en la cantidad de productos adquiridos. La lógica para calcular descuentos se encuentra en la siguiente tabla de decisión. Necesita escribir un método en C# que utilice la misma lógica para calcular el descuento. ¿Cómo escribiría su programa? S S
Cantidad < 100
S
Descuento
N
N
N
S
N
N
S
S
N
ÁM
Cantidad < 10 Cantidad < 50
5%
10%
15%
20%
www.pdftron.com Escenario 1-2: Convierta un diagrama de flujo en un programa de C#
ET
CI
BE
RO
Se encuentra desarrollando una librería de funciones matemáticas. Antes desarrolló el siguiente diagrama de fujo para describir el algoritmo para calcular el factorial de un número. Necesita escribir un equivalente en C# para este diagrama de fujo. ¿Cómo escribiría el programa? INICIO
Ingresar n
fact = 1
No
n > 1? Si fact = fact * n
n=n-1
Salida de fact
FIN
Comprender los conceptos básicos de bases de datos
35
» Evaluación de aptitud Proyecto 1-3: Maneje excepciones
ER ICA
Se encuentra escribiendo código para una librería aritmética simple. Decide crear un método de nombre Divide que toma dos argumentos, x y y, y regresa el valor de x/y. Necesita obtener cualquier excepción aritmética que pueda resultar de los errores en aritmética, casting o conversiones de tipos de datos. También necesita obtener cualquier otra excepción que pueda resultar del código. Necesita crear el código para manejar excepciones estructurándolo de forma correcta para cubrir este requerimiento. ¿Cómo escribiría un programa con estas características? Proyecto 1-4: Cree un algoritmo recursivo
ÁM
Se encuentra desarrollando una librería de funciones de utilidad para su aplicación. Necesita escribir un método que tome un entero y cuente la cantidad de dígitos signifcativos en el mismo. Necesita crear un programa recursivo para solucionar este problema. ¿Cómo escribiría un programa con estas características?
ET
CI
BE
RO
www.pdftron.com
Lección 1
ÁM
ER ICA
36
ET
CI
BE
RO
www.pdftron.com
Lección 2
Introducción a la programación orientada a objetos Matriz de dominio de objetivos Descripción de dominio de objetivo
Número del dominio del objetivo
Comprender los objetos
Comprender los principios básicos de las clases
2.1
Comprender los valores y las referencias
Comprender el almacenamiento y los tipos de datos
1.1
Comprender el encapsulamiento
Comprender el encapsulamiento
2.4
Comprender la herencia
Comprender la herencia
2.2
Comprender el polimorfismo
Comprender el polimorfismo
2.3
Comprender las interfaces
Comprender las interfaces
2.4
ÁM
ER ICA
Habilidad tecnológica
www.pdftron.com Términos clave
• Evento • Herencia • Interfaz • Espacio de nombres • Polimorfsmo
• Propiedad • Tipo de referencia • Tipo de valor
CI
BE
RO
• Accessors • Clase abstracta • Constructor • Delegado • Encapsulamiento
ET
Como desarrollador de software para la corporación Northwind, forma parte de un equipo de desarrollo de programas de computadora que resuelven problemas de la empresa. Cualquier programa que escriba debe ser fácil de entender y mantener por un largo periodo de tiempo. Necesita desarrollar programas utilizando técnicas que impulsen el reciclado de código, la extensibilidad y la colaboración.
En lugar de pensar en un programa como una lista de métodos, incorpore en sus programas conceptos de negocios del mundo real como clientes, productos, proveedores y las interacciones entre los mismos.
38
Lección 2
Comprender objetos È EN RESUMEN
Pensar de forma orientada a objetos
ER ICA
La programación orientada a objetos es una técnica de programación que utiliza objetos. Los objetos son estructuras de datos auto contenidas que consisten de propiedades, métodos y eventos. Las propiedades especifcan los datos representados por el objeto, los métodos especifcan el comportamiento de un objeto y los eventos proporcionan la comunicación entre los objetos.
Un objeto de software es conceptualmente similar a un objeto en el mundo real.
ÁM
Una buena manera de empezar a pensar de forma orientada a objetos es observando el mundo real por ejemplo, un coche, un teléfono, un reproductor de música, etc. Notará que todos tienen un estado y un comportamiento. Por ejemplo, los coches tienen un estado (nombre del modelo, color, velocidad, cantidad de gasolina) y un comportamiento (acelerar, frenar, cambiar velocidades). También notará que algunos objetos son más simples y otros más complejos. Algunos objetos complejos como los coches están hechos de objetos más pequeños que a su vez tienen su propio estado y comportamiento. También se dará cuenta que aunque un coche es un objeto complejo, sólo necesita saber algunas cuantas cosas para poder interactuar con uno. Cuando conduce un auto, simplemente invoca un comportamiento como acelerar o frenar y desconoce muchos miles de detalles internos sobre su funcionamiento.
www.pdftron.com BE
RO
Un objeto de software es conceptualmente similar a uno del mundo real. Un objeto almacena su estado en campos y expone su comportamiento a través de métodos. Cuando se invoca un método en el objeto, obtendrá una funcionalidad bien defnida sin la necesidad de preocuparse sobre la complejidad interna del objeto o del método en sí. Este concepto de ocultar complejidad se conoce como encapsulamiento y es una de las muchas características de la programación orientada a objetos que aprenderá en esta lección.
Comprender las clases
ET
CI
Una clase es una plantilla de la cual se crean los objetos individuales. Los objetos en el mundo real necesitan de una plantilla que defna la forma en la que se construirán. Todos los objetos que se crean a partir de la misma plantilla se ven y comportan de forma similar. Por ejemplo, piense en un modelo específco de un coche. En el mundo del software, una clase es la plantilla de la cual se crean objetos individuales. A un objeto se le conoce también como instancia de una clase.
Æ Crear una clase PREPÁRESE. Antes de realizar estos pasos, asegúrese de abrir Microsoft Visual Studio y abrir un nuevo proyecto de aplicación de consola de nombre Lesson02. 1. Agregue una nueva clase de Visual C# de nombre Rectangle al proyecto.
Introducción a la programación orientada a objetos
39
2. Reemplace el código de la clase Rectangle con el siguiente: class Rectangle { private double length; private double width; public Rectangle(double l, double w) length = l; width = w; }
ER ICA
{
public double GetArea() { }
ÁM
return length * width;
www.pdftron.com }
• Genere el proyecto y asegúrese de que no tenga errores.
RO
PAUSA. Deje el proyecto abierto para utilizarlo en el siguiente ejercicio.
BE
Acaba de crear una nueva clase de C de nombre Rectangle. Para defnir una nueva clase se utiliza la palabra reservada class. La clase Rectangle tiene dos campos de datos, length y width. Estos campos se defnen utilizando el modificador de acceso private. Un modifcador de acceso especifca a cual región de código tendrá acceso el campo. Por ejemplo, un modifcador de acceso public no limita el acceso pero el modifcador de acceso private limita el acceso dentro de la clase en la cual se defna el campo. La clase también defne un método de nombre GetArea.
CI
Tome Nota
ET
Cada clase es una definición de un nuevo tipo de datos. Por lo tanto, una definición de una clase se le relaciona con un tipo.
Comprender los métodos Un método es un bloque de código contiene una serie de sentencias. Un método defne las acciones y operaciones soportadas por una clase. Un método se defne al especifcar el nivel de acceso, el tipo de retorno, el tipo de método y una lista opcional de parámetros en paréntesis seguido de un bloque de código dentro de llaves. La clase Rectangle defne un solo método de nombre GetArea. Para GetArea, el nivel de acceso
40
Lección 2
es público, el tipo de retorno es double, el nombre del método es GetArea, la lista de parámetros está vacía y el bloque de código es una sentencia return sencilla. Un método puede regresar un valor al código invocador. Si un método no regresa ningún valor, su tipo de retorno se especifca con la palabra reservada void. El método debe utilizar una sentencia return para poder regresar un valor. La sentencia return fnaliza la ejecución de un método y regresa el valor específco al código invocador. El tipo de dato del valor retornado de un método debe coincidir con el tipo de retorno especifcado en la línea de declaración de un método.
ER ICA
El tipo de retorno del método GetArea es double, lo que signifca que el método GetArea debe retornar un valor del tipo doble. El método GetArea satisface este requerimiento al retornar la expresión length * width, el cual es un valor double. El siguiente código defne un método InitFields que toma dos parámetros de tipo doble y regresa un void: public void InitFields(double l, double w) {
El nombre del método, su lista de parámetros y el orden de los tipos de datos de los parámetros se reconocen en conjunto como la firma del método. Una firma de método debe ser única en la clase.
length = l; width = w;
ÁM
Tome Nota
}
www.pdftron.com RO
El método InitFields toma dos parámetros y utiliza los valores de los mismos para asignar de forma respectiva lo campos de datos length y width. Cuando el tipo de retorno de un método es void, se puede utilizar una sentencia return sin valor. Si no se utiliza una sentencia return, como en el método InitFields, el método dejará de ejecutarse cuando llegue al fnal del bloque de código. El método InitFields se puede utilizar para inicializar de forma apropiada el valor de los campos de datos, pero como lo aprenderá en la siguiente sección, los constructores de hecho le dan una forma de inicializar una clase.
BE
Comprender los constructores
Los constructores se utilizan para inicializar los miembros de datos del objeto.
ET
CI
Los constructores son métodos de clase especiales que se ejecutan cuando se crea una nueva instancia de la clase. Los constructores se utilizan para inicializar los miembros de datos del objeto. Los constructores deben tener exactamente el mismo nombre de la clase y no tienen un tipo de retorno. Se pueden defnir constructores múltiples, cada uno con una frma única, para una clase.
Un constructor que no toma argumentos se conoce como el constructor default. Si se defne una clase sin ningún constructor, se genera automáticamente un constructor default invisible que no hace nada. Con frecuencia es útil tener constructores adicionales para contar con más formas con la cuales inicializar un objeto. La clase Rectangle, defnida con anterioridad, es sólo una forma de crear e inicializar su objeto: llamando al constructor que acepta dos parámetros, ambos del tipo de datos default.
Introducción a la programación orientada a objetos
41
Crear objetos Los objetos se crean a partir de plantillas defnidas por clases.
Æ Crear un objeto UTILICE el proyecto de consola de aplicación, Lesson02, que creó en el ejercicio anterior. class Program {
ER ICA
1. Modifique el código de la clase Program de la siguiente forma:
static void Main(string[] args) {
Rectangle rect = new Rectangle(10.0, 20.0); double area = rect.GetArea();
Console.WriteLine(“Área del Rectángulo: {0}”, }
ÁM
area);
www.pdftron.com }
2. Seleccione Depurar y después Iniciar sin depurar. Aparecerá una ventana de consola mostrando el área del rectángulo.
RO
3. GUARDE su proyecto.
PAUSA. Deje el proyecto abierto para utilizarlo en el siguiente ejercicio.
Tome Nota
La clase Rectangle cuenta con solo una forma de construir una instancia de la clase: invocando un constructor con dos argumentos del tipo de datos double. Se crea un objeto utilizando la palabra reservada new seguida de la invocación al constructor de clase apropiado.
BE
Las clases y los objetos son diferentes. Una clase define la plantilla de un objeto pero no al objeto en sí. Por otro lado, un objeto es una instancia concreta de una clase pero no la clase en sí.
ET
CI
Cuando se ejecuta el código, un objeto de tipo Rectangle se crea en la memoria heap. Una referencia a esta memoria se almacena dentro de la variable rect. La variable rect se almacena en la pila. Posteriormente, en este bloque de código, puede utilizar rect para hacer referencia y manipular el objeto que se acaba de crear.
Utilizando la referencia del objeto, puede acceder a los miembros de la clase. Por ejemplo, el código llama al método GetArea en el objeto y el valor retornado por el método se almacena en la variable área. Los campos de datos, length y width, del objeto rect no están accesibles aquí debido a que están marcados como private en la defnición de la clase.
Comprender las propiedades Las propiedades le permiten accede a los datos de una clase de una forma segura y fexible. Las propiedades son miembros de la clase que se pueden acceder como los campos de
Lección 2
Tome Nota A las propiedades, generalmente se les conoce como campos “inteligentes” ya que pueden contener código para la verificación de consistencia o validez de datos.
datos pero que puede contener código como un método. Las propiedades se utilizan con frecuencia para exponer los campos de datos de una clase de una forma más controlada. Por ejemplo, un campo privado se puede exponer utilizando una propiedad pública, pero no es necesario utilizar las propiedades de esta manera. Una propiedad tiene dos accessors, get y set. El accessor get se utiliza para retornar el valor de la propiedad y el accessor set se utiliza para asignar un nuevo valor a la propiedad. A una propiedad frecuentemente se le defne como public y siempre tiene un nombre que comienza con una letra mayúscula. Por el contrario. Al asignar nombres a los campos de datos privados se utiliza siempre al principio una letra minúscula.
Æ Crear propiedades
ER ICA
42
UTILICE el proyecto que guardó en el ejercicio anterior.
1. Modifique el código de la clase Rectangle como se muestra a continuación. En este código, el constructor se elimina y se insertan dos propiedades: class Rectangle {
private double length;
ÁM
private double width;
www.pdftron.com public double Length {
RO
get {
return length;
BE
}
set {
ET
CI
if ( value > 0.0) length = value;
}
}
public double Width { get { return width; } set
Introducción a la programación orientada a objetos
43
{ if (value > 0.0 ) width = value; }
}
public double GetArea()
}
return length * width;
}
ER ICA
{
2. Modifique el código de la clase Program como se muestra a continuación: class Program {
static void Main(string[] args) {
ÁM
Rectangle rect = new Rectangle(); rect.Length = 10.0;
www.pdftron.com rect.Width = 20.0;
double area = rect.GetArea();
RO
Console.WriteLine(
“Área del rectángulo: {0}”, area);
}
}
BE
3. Seleccione Depurar, Iniciar sin depurar. Aparecerá una ventana de consola mostrando el área del rectángulo.
4. GUARDE su proyecto.
CI
PAUSA. Deje el proyecto abierto para utilizarlo en el siguiente ejercicio.
Tome Nota
ET
El patrón de programación general es que todos los campos de datos de una clase deben declararse como private y que el acceso a estos campos privados debe ser vía propiedades públicas y revisar los valores de datos para su validación.
En este ejercicio, modifcó la clase Rectangle para ingresar dos propiedades, Length y Width. Las propiedades generalmente se defnen con un modifcador de acceso público. En el código para la propiedad Length, el accessor get simplemente retorna el valor del campo de datos length. Sin embargo, el accessor set revisa el valor signado (utilizando la palabra reservada value) a la propiedad y modifca el campo de datos length sólo si el valor es positivo. Los campos privados length y width también se conocen como campos de respaldo por las propiedades que los exponen. Además, la clase Rectangle no declara ningún contructor explícito. En este caso, los usuarios de la clase (el método Main) necesita utilizar el constructor predefnido y confar en las propiedades para inicializar los datos de la clase. El método Main utiliza las propiedades Length y Width para establecer los datos para el objeto rect. Se ignorará si se trata de establecer Length o Width como un valor negativo y en ese caso los campos de datos seguirán conservando su valor original de 60.
44
Lección 2
Cuando se defnen propiedades se pueden excluir cualquiera de los accessors get o set. Si no incluye el accessor set, no proporciona una forma de establecer el valor de la propiedad y por lo tanto tendrá una propiedad de sólo lectura. Por otro lado, si no incluye el accessor get, no se proporciona una forma de obtener el valor de la propiedad y por lo tanto tendrá una propiedad de sólo escritura.
Comprender las propiedades auto-implementadas Las propiedades auto-implementadas simplifcan las declaraciones de las propiedades.
ER ICA
C# introdujo las propiedades auto-implementadas con la versión 3 para simplifcar la declaración de propiedades donde no hay lógica adicional especifcada en los accessors get y set. Por ejemplo, sin la revisión de validación, las propiedades Length y Width se defnen de la siguiente manera: private double length; private double width;
{ get
ÁM
public double Length
www.pdftron.com {
return length;
}
RO
set {
length = value;
BE
}
}
public double Width
CI
{
get
ET
{ return width;
} set { width = value; } }
Con las propiedades auto-implementadas de C#, la sintaxis simplifcada para la declaración de la propiedad inicia de la siguiente forma:
Introducción a la programación orientada a objetos
45
public double Length { get; set; } public double Width { get; set; }
En este caso, los campos de respaldo para las propiedades se defnen tras bambalinas y no son accesibles de forma directa por el código. Las propiedades auto-implementadas utilizadas con los constructores predefnidos también simplifcan la creación e inicialización de los objetos. Por ejemplo, ahora se puede crear e inicializar un objeto de la siguiente manera: {
ER ICA
static void Main(string[] args)
Rectangle rect = new Rectangle
{ Length = 10.0, Width = 20.0 };
Console.WriteLine(
“Area of Rectangle: {0}”, rect.GetArea());
}
Uso de la palabra reservada this
ÁM
La palabra reservada this se puede utilizar para acceder a miembros desde dentro de los constructores, métodos de instancia y accessors de propiedades de instancia.
www.pdftron.com RO
La palabra reservada this es una referencia a la instancia actual de la clase. Se puede utilizar la palabra this para referirse a cualquier miembro del objeto actual. Por ejemplo, anteriormente en este capítulo, la clase Rectangle se escribió como se indica a continuación: class Rectangle
private double length;
BE
{
ET
CI
private double width;
public Rectangle(double l, double w) {
}
length = l; width = w;
public double GetArea() { }
return length * width;
}
Pero se pudo haber escrito de la siguiente manera: class Rectangle
46
Lección 2
{ private double length; private double width; public Rectangle(double l, double w) { this.length = l; this.width = w;
ER ICA
}
public double GetArea() { }
return this.length * this.width;
}
En C#, los caracteres // se utilizan para agregar comentarios en una sola línea en el código. El texto después de los caracteres // se ignora por el compilador. Los comentarios en varias líneas comienzan con los caracteres/* y terminan con */.
Como puede ver, la palabra this se utilizó dentro del constructor y del método GetArea para referirlo a los campos de datos del objeto actual de la clase Rectangle. Aun cuando no era necesario utilizar la palabra this en este caso, utilizarla proporciona mayor fexibilidad al nombrar los parámetros del método. Por ejemplo, podría defnir el constructor como se muestra a continuación:
ÁM
Tome Nota
www.pdftron.com BE
RO
public Rectangle(double length, double width) { // los nombres de parámetro length y width // opacan los miembros de clase length y // width en este ámbito this.length = length; this.width = width; }
CI
Dentro del ámbito de la defnición del constructor Rectangle, los nombres length y width ahora se referirán al parámetro que se esté pasando. El nombre de los campos de datos se ha opacado y sólo se pueden acceder utilizando la palabra this.
Comprender los delegados
ET
Los delegados son tipos especiales que se utilizan para encapsular un método dentro de una frma específca. Los delegados son objetos especiales que pueden contener une referencia a un método con una frma específca. Un delegado se defne utilizando la palabra reservada delegate. Se puede defnir un delegado como se indica a continuación: public delegate void RectangleHandler(Rectangle rect);
Le defnición delegate especifca la frma del método cuya referencia se pueda contener por un objeto delegate. Por ejemplo, en el código anterior se defne un delegado RectangleHandler que puede contener referencias a un método que regresa un void y acepta un solo parámetro del tipo Rectangle.
Introducción a la programación orientada a objetos
47
Por lo tanto, si tiene un método con una frma similar, resulta un candidato ideal para la asignación a una instancia delegate. Por ejemplo: public void DisplayArea(Rectangle rect) { }
Console.WriteLine(rect.GetArea());
ER ICA
El tipo delegate se puede utilizar para declarar una variable que se puede referir a cualquier método con la misma frma que el delegado. Por ejemplo, puede decir: RectangleHandler handler;
Y puede asignar el método al delegado utilizando la siguiente sintaxis: handler += new Rectanglehandler(DisplayArea);
Como alternativa, puede utilizar la siguiente sintaxis: handler += DisplayArea;m
ÁM
Note que la sintaxis utiliza la operación de adición. Esto signifca que puede asociar más de un método (de frma compatible), creando una lista de invocación de uno o más métodos.
www.pdftron.com Finalmente, se puede llamar a un delegado se puede realizar a través de una sintaxis de invocación de métodos como la siguiente: Rectangle rect = new Rectangle (10, 20);
RO
handler(rect);
BE
Cuando se llama un delegado de esta forma, se invocan todos los métodos en esta lista de invocación. En este ejemplo, el objeto handler se refere sólo a un método DisplayArea por lo que el método DisplayArea se invocará con el objeto rect como un parámetro.
Entre otras muchas aplicaciones, los delegados forman la base para las declaraciones de eventos, como se comentará en la siguiente sección.
CI
Comprender los eventos
ET
Los eventos son una forma por la cual una clase notifca a otras clases u objetos que sucedió algo de interés. La clase que envía la notifcación se conoce como editor. La clase que recibe la notifcación se conoce como suscriptor del evento. Los eventos son fáciles de comprender en el contexto de una interfaz gráfca de usuario (GUI). Por ejemplo, cuando un usuario da clic en un botón, ocurre un evento Click. Los elementos en una interfaz de usuarios múltiples se pueden suscribir a este evento y cambiar su estado visual (por ejemplo, algunos controles se habilitan o deshabilitan). En este tipo de comunicación de eventos, los editores de eventos no necesitan saber cuáles objetos se suscriben a los eventos que se están llevando a cabo. Los eventos no se limitan a la programación en GUI. De hecho, los eventos tienen un papel importante en las librerías de clase del .NET Framework para que los objetos hagan notar cualquier cambio en sus estados. Trabajará con eventos en prácticamente todos los programas.
48
Lección 2
Al defnir los eventos, generalmente necesita dos tipos de información:
• •
Un delegado que conecta al evento con su controlador(es) de evento(s). Una clase que contiene los datos del evento. Esta clase generalmente se deriva de la clase EventArgs.
Para defnir un evento, puede utilizar un delegado personalizado. Sin embargo, en la mayoría de los casos si el evento no contiene información específca del mismo, no será sufciente con utilizar el delegado predefnido EventHandler. El delegado EventHanler se defne de la siguiente manera:
ER ICA
public delegate void EventHandler(Object sender, EventArgs e);
Aquí, el parámetro sender es una referencia al objeto que provoca el evento y el parámetro es una referencia a un objeto de datos del evento que no contiene datos del mismo.
La clase EventArgs se utiliza por los eventos que no pasan ninguna información relacionada con los mismos a un controlador de eventos cuando se ocasiona un evento. Si el controlador de eventos requiere de información relacionada a los mismos, la aplicación debe derivar una clase desde la clase EventArgs para recibir los datos relacionados con los eventos.
ÁM
Æ Publicar y suscribirse a eventos
www.pdftron.com UTILICE el proyecto que guardó en el ejercicio anterior.
1. Modifique el código de la clase Rectangle de la siguiente forma: {
RO
class Rectangle
public event EventHandler Changed; private double length;
Tome Nota
BE
public double Length {
El campo EventArgs. Empty representa un evento sin datos. El campo equivale a tener una instancia de sólo lectura de la clase EventArgs.
get
CI
{
return length;
}
ET
set { length = value; Changed(this, EventArgs.Empty); }
} } 2. Modifique el código de la clase Program con lo siguiente: class Program
Introducción a la programación orientada a objetos
{
49
static void Main(string[] args) {
Rectangle r = new Rectangle();
r.Changed += new EventHandler(r_Changed); r.Length = 10; } static void r_Changed(object sender, EventArgs e)
ER ICA
{
Rectangle r = (Rectangle)sender; Console.WriteLine(
“Value Changed: Length = {0}”,
Tome Nota
r.Length); } }
3. Seleccione Depurar, Iniciar sin depurar. Aparecerá una ventana de consola para mostrar que el valor de la propiedad Length cambió.
ÁM
El código en el método r_Changed utiliza un operador cast para convertir un tipo de datos de objeto en el tipo de datos Rectangle. El casting se explicará más adelante en esta lección en la sección “Casting entre tipos”.
www.pdftron.com 4. GUARDE su proyecto.
RO
PAUSA. Deje su proyecto abierto para utilizarlo en el siguiente ejercicio.
BE
Aquí la clase Rectangle defne un evento Changed que se invoca cuando la propiedad Length del objeto Rectangle cambia. El delegado del evento Changed es del tipo EventHandler. En la clase Rectangle, el evento Changed se invoca cuando se llama el accessor set de la propiedad Length.
ET
CI
Se puede suscribir al evento Changed dentro del método Main al adjuntar el método r_Changed como un controlador de evento para el evento utilizando el siguiente código: r.Changed += new EventHandler(r_Changed);
La frma del método r_Changed coincide con los requerimientos del delegado EventHandler. El método r_Changed se invoca tan pronto se establece el valor de la propiedad Length en el método Main.
El código anterior utiliza el operador += en lugar del operador de asignación simple (=) para adjuntar el controlador de eventos. Al utilizar el operador +=, se asegura que este controlador de eventos se agregue a la lista de controladores que ya se encuentra adjunta al evento. Esta técnica le permite tener varios controladores de eventos que puedan responder a un evento. Si utiliza el operador de asignación (=) para asignar el nuevo controlador de evento, se anulará cualquier controlador de eventos existente que se encuentre adjunto al evento y el nuevo evento será el detonado cuando se invoque el evento.
50
Lección 2
Comprender los espacios de nombres Un espacio de nombres le permite organizar el código y crear nombres de clase únicos. Un espacio de nombres es un elemento del lenguaje que le permite organizar código y crear nombres de clase globalmente únicas. Digamos que crea una clase del nombre Widget. Existe la posibilidad de que otro grupo adjunte código que también contenga una clase del mismo nombre. En ese caso, ¿cómo maneja la ambigüedad de nombres? La solución es organizar el código en un espacio de nombres. Una metodología común es utilizar el nombre de la compañía en el espacio de nombres. Por ejemplo, puede decir:
ÁM
}
ER ICA
namespace CompanyA { public class Widget { … } } and namespace CompanyB { public class Widget { … }
www.pdftron.com La clase del espacio de nombres CompanyA puede ser referida de forma única por su nombre de clase completamente califcada CompanyA.Widget, mientras que el otro Widget se puede identifcar como CompanyB.Widget.
RO
El .NET Framework utiliza espacios de nombres para organizar todas sus clases. Por ejemplo, el espacio de nombres System agrupa todas las clases básicas. El espacio de nombres System.Data organiza las clases para el acceso a datos. El espacio de nombres System.Web se utiliza para clases relacionadas con la Web.
BE
Con el uso de espacios de nombres puede terminar con nombres de clase completamente califcados muy largos que ocasionaría un exceso de texto y necesidad de teclear. C# soluciona este inconveniente a través de la directiva using. Puede utilizar la directiva using en la parte superior del archivo de la clase como se muestra a continuación.
CI
using System.Text;
ET
Una vez que haya incluido la directiva using para un espacio de nombres, no necesitará califcar de forma completa las clases de ese espacio de nombres en el archivo. using System.Text;
Comprender los miembros estáticos Los miembros estáticos pertenecen a la clase en sí en lugar de a objetos individuales. Los miembros de la clase como los campos de datos, métodos y propiedades que se han comentado hasta ahora en esta sección, todos operan sobre objetos individuales. Tales miembros se llaman como miembros de instancia porque se pueden utilizar sólo después de que una instancia de la clase es creada. En contraste, la palabra reservada static se utiliza para declarar miembros que no pertenecen a objetos individuales sino a la clase en sí. Tales miembros de clase se llaman como miembros estáticos. Un ejemplo común de un miembro estático es el método Main que sirve como punto de entrada en su programa.
Introducción a la programación orientada a objetos
51
Æ Crear miembros estáticos UTILICE el proyecto que guardó en el ejercicio anterior. 1. Modifique el código de la clase Rectangle como se muestra a continuación: class Rectangle public static string ShapeName { }
get { return “Rectángulo”; }
ER ICA
{
public double Length { get; set; } public double Width { get; set; } public double GetArea()
}
}
return this.Length * this.Width;
ÁM
{
2. Modifique el código de la clase Program a lo siguiente: class Program
www.pdftron.com {
static void Main(string[] args)
RO
{
Rectangle rect = new Rectangle
{ Length = 10.0, Width = 20.0 };
Console.WriteLine(“Nombre de la forma: {0}, Area:
BE
{1}”,
CI
}
}
Rectangle.ShapeName, rect.GetArea());
ET
3. Seleccione Depurar, Iniciar sin depurar. Aparecerá una ventana de consola para mostrar el nombre y área de la forma.
; ¿Listo para la certificación? ¿Comprende los conceptos básicos de las clases? -2.1
4. GUARDE su proyecto. PAUSA. Deje el proyecto abierto para utilizarlo en el siguiente ejercicio.
Cuando se crea una instancia de una clase, se crea una copia separada para cada campo de instancia pero solo una copia del campo estático se comparte por todas las instancias. Un miembro estático no se puede referenciar a través de un objeto de instancia. En su lugar, un miembro estático se referencia a través del nombre de la clase (como Rectangle. ShapeName en el ejercicio anterior). No se puede utilizar la palabra reservada this con un método estático o una propiedad debido a que sólo se puede utilizar para acceder a objetos de instancia.
52
Lección 2
Comprender los valores y las referencias È EN RESUMEN
Los tipos de valores almacenan directamente los valores mientras que los tipos de referencia sólo almacenan una referencia al valor real.
ER ICA
Un tipo de valor almacena directamente los datos en su memoria. Los tipos de referencia, por otro lado, sólo almacenan una referencia a la ubicación en memoria. Los datos se encuentran almacenados en la ubicación en memoria a la cual se hace referencia. La mayoría de los tipos de datos básicos como bool, int, char, double, etc., son tipos de valores. Los tipos de datos defnidos por el usuario, creados utilizando la palabra reservada struct también son tipos de valores. Los tipos de referencia incluyen los tipos creados utilizando las palabras reservadas object, string, interface, delegate, y class.
Comprender las estructuras
ÁM
La palabra reservara struct se utiliza para crear tipos defnidos por el usuario que consisten en grupos pequeños de campos relacionados. Las estructuras son tipos de valores opuestos a las clases que son tipos de referencias.
Las estructuras se defnen utilizando la palabra reservada struct como se muestra a continuación:
www.pdftron.com public struct Point
public double X, Y;
}
Las estructuras pueden contener la mayoría de los elementos que puede contener una clase, como constructores, métodos, propiedades, etc. Sin embargo, como aprenderá en la siguiente sección, las estructuras son tipos de valores mientras que las clases son tipos de referencias. A diferencia de una clase, una estructura no puede heredar de otra clase o estructura.
CI
BE
Las estructuras se utilizan generalmente para crear tipos simples. Si se encuentra creando una estructura muy compleja, considere mejor utilizar una clase.
RO
{
Tome Nota
Comprender la asignación de memoria
ET
Después de introducir un valor o texto en una celda, puede modifcarla de varias formas. Puede eliminar el contenido por completo, introducir un valor diferente para reemplazar el que estaba o alterar lo que ingresó. Una buena forma de comprender cómo los valores se diferencian de los tipos de referencia es visualizar cómo se representa cada uno de ellos en memoria. La Figura 2-1 muestra cómo se crean los tipos de valor en memoria. Cuando crea una variable de tipo int, se crea una ubicación en memoria que puede utilizar para almacenar un valor del tipo int. Inicialmente, cuando no asigna un valor de forma explícita, el valor predeterminado del tipo de datos (para un int el valor predeterminado es 0) se almacena en la ubicación en memoria. Cuando se realiza una asignación, la dirección de memoria identifcada por el nombre de la variable se actualiza con el nuevo valor (10 en el caso de la asignación en la Figura 2-1).
Introducción a la programación orientada a objetos
Figura 2-1 Visualización de un tipo de valor en memoria
53
Production note: This figure should be redrawn on a smaller scale. Please also make the arrows as straight lines when you redraw it.
número
int number;
0
number = 10;
número
ER ICA
10
La Figura 2-2 muestra un tipo de referencia, el tipo de datos string. Cuando crea una variable de tipo string, se crea una ubicación en memoria que se identifcará por este nombre. Sin embargo, esta ubicación en memoria no va a albergar el contenido del string. Esta variable almacenará la dirección en memoria (una referencia) de la ubicación donde de hecho se almacenará el string. Figura 2-2
Vista de Memoria
ÁM
Vista de Código
Visualización de un tipo de referencia en memoria
www.pdftron.com string name;
RO
name = "Northwind";
nombre
null
nombre
dirección
m100
datos
"Northwind"
m100
BE
Inicialmente, cuando no se asigna un valor, la variable tendrá el valor de null (una referencia null, en otras palabras, esta variable no hace referencia a una dirección en memoria válida). En la siguiente sentencia, cuando dice:
name = “Northwind”;
ET
CI
la cadena “Northwind” se crea en una ubicación de memoria en particular (para simplifcar, digamos que la dirección en memoria es m100) y esa dirección de memoria se almacena en el nombre de la variable. Cuando es hora de recuperar el valor del nombre de la variable, el tiempo de ejecución sabrá que su contenido no se encuentra almacenado en la variable en si sino en la ubicación en memoria a la cual apunta la variable.
Æ Copiar valores y tipos de referencia UTILICE el proyecto que guardó en el ejercicio anterior. 1. Agregue el siguiente código después de la definición de la clase Rectangle para crear una estructura Point: struct Point { public double X, Y; }
54
Lección 2
2. Modifique el código del método Main como se muestra a continuación: static void Main(string[] args) { Point p1 = new Point();
Es posible crear un struct sin utilizar el operador new. Puede simplemente decir Point p1; para crear una variable del tipo struct.
p1.X = 10; p1.Y = 20; Point p2 = p1; p2.X = 100;
ER ICA
Tome Nota
Console.WriteLine(“p1.X = {0}”, p1.X); Rectangle rect1 = new Rectangle
{ Length = 10.0, Width = 20.0 }; Rectangle rect2 = rect1;
ÁM
rect2.Length = 100.0;
www.pdftron.com Console.WriteLine(“rect1.Length = {0}”,
}
RO
rect1.Length);
3. Seleccione Depurar y después Iniciar sin depurar. Aparecerá una ventana de consola para mostrar los valores para p1.X y rect1.Length.
Tome Nota
4. GUARDE su proyecto.
PAUSA. Deje el proyecto abierto para utilizarlo en el siguiente eje
BE
Cuando copia una variable de tipo de referencia a otra variable del mismo tipo, sólo se copian las referencias. Como resultado, después de la copia, las dos variables apuntan al mismo proyecto.
ET
CI
La primera parte del programa crea una copia del tipo de valor Point y la segunda mitad del programa crea una copia del tipo de referencia Rectangle. Analicemos como se realiza la copia del tipo de valor. Cuando se ejecuta la siguiente sentencia, se crea una nueva variable p2 en memoria y su contenido se copia desde la variable p1:
Point p2 = p1;
Después de ejecutar esta sentencia, se crea la variable p2 y el contenido de la variable p1 se copia a la variable p2. Tanto p1 como p2 tienen su propio conjunto de valores disponibles en sus ubicaciones en memoria respectivas. Por lo que, cuando se ejecuta la siguiente sentencia: p2.X = 100;
sólo se afecta el valor de X correspondiente a la ubicación en memoria de la variable p2. El valor de X para la variable p1 permanece sin cambios.
Introducción a la programación orientada a objetos
55
Ahora, analicemos cómo funciona la copia entre los tipos de referencia. Cuando se ejecuta la siguiente sentencia, se crea una nueva variable rect2, igual que antes, el contenido de rect1 se copia a la ubicación en memoria de rect2: Rectangle rect2 = rect1;
rect2.Length = 100.0;
; ¿Listo para la certificación?
Esta sentencia hace referencia a la ubicación en memoria apuntada por rect2 (la cual resulta ser la misma ubicación en memoria apuntada por rect1) y modifca Length del objeto Rectangle. Ahora, si intenta hacer referencia a la misma ubicación en memoria vía el objeto rect1, obtendrá el objeto modifcado y aparecerá el siguiente código mostrando el valor “rect1.Length = 100”. Console.WriteLine(“rect1.Length = {0}”,
ÁM
¿Comprende los tipos de datos y l asignación de memoria? -1.1
ER ICA
Pero puesto que la clase Rectangle es un tipo de referencia, el contenido de la variable rect1 es de hecho una referencia a la ubicación en memoria que contiene un objeto de Rectangle. Así que, después de la inicialización anterior, tanto rect1 y rect2 apuntan a la misma ubicación en memoria y al mismo objeto de Rectangle. Sólo hay un objeto de rectangle en memoria y tanto rect1 como rect2 se referen a él. La siguiente sentencia modifca Length del objeto de rectangle:
rect1.Length);
www.pdftron.com RO
Comprender la memoria heap y la pila call
CI
BE
Los objetos son siempre memoria asignada en el heap. El heap es la memoria disponible para el programa en tiempo de ejecución para la asignación dinámica de memoria. En contraste, algunos elementos de datos se pueden crear en la pila de ejecución o en la pila call. Los elementos creados en la pila son los parámetros de método y las variables locales declaradas dentro de un método. La memoria de pila se reclama cuando por ejemplo se retorna un método. La memoria asignada en el heap se reclama automáticamente por el recolector de basura cuando los objetos ya no se utilizan (ya no hay objetos que hacen referencia a ellos).
Comprender el encapsulamiento
ET
È EN RESUMEN
El encapsulamiento es un mecanismo para ocultar información que hace que el código sea fácil de mantener y entender. El encapsulamiento es un mecanismo para restringir el acceso a una clase o miembros clase para ocultar decisiones en el diseño que pueden cambiar. El encapsulamiento les da a los diseñadores de las clases la fexibilidad para cambiar el código cuando sea necesario sin cambiar todo el código que hace uso de ese código. Además, cuando oculta información, también oculta la complejidad asociada a la misma. Como resultado, con la ayuda del encapsulamiento, puede escribir código que sea más fácil de comprender y mantener.
Lección 2
Tome Nota
En los ejercicios anteriores, vio el encapsulamiento cuando:
Cuando el código en C# se compila, el código ejecutable de salida contenido dentro de un archivo .dll o .exe también se llama como una asamblea. Una asamblea es una unidad de código ejecutable que puede instalar de forma independiente.
•
• • •
Declaró los miembros de datos como private y reforzó la inicialización de campos de datos vía un constructor. Como los miembros de datos se encuentran ocultos de los usuarios de la clase, el desarrollador de la clase Rectangle puede cambiar los nombres de los campos de datos sin la necesidad de cambiar el código invocador. Las propiedades ofrecen una excelente manera de encapsular los campos de datos junto con cualquier otro tipo de lógica. Los modifcadores de acceso como private y public le permiten controlar el nivel de acceso que quiera tener para un miembro de la clase o para la clase en sí. En esta sección aprenderá más sobre los modifcadores de acceso.
Comprender los modificadores de acceso
ER ICA
56
Los modifcadores de acceso controlan dónde se puede utilizar un tipo o miembro de tipo.
Las partes que conforman al elemento
Todos los tipos y miembros de tipo tienen un nivel de acceso que especifca donde esa clase o sus miembros se pueden utilizar en su código. El nivel de acceso se puede establecer utilizando uno de los modifcadores de acceso especifcados en la Tabla 2-1.
ÁM
Tabla 7-2
www.pdftron.com Descripción
public
El acceso no se restringe.
private
El acceso se restringe a la clase contenedora.
protected
El acceso se restringe a la clase contenedora y a cualquier clase que se derive directa o indirectamente de la clase contenedora. Aprenderá más sobre las clases derivadas en la sección “Comprender la herencia” más adelante en esta lección.
BE
internal
RO
Modificador de acceso
El acceso se restringe al código en la misma asamblea. Este modificador de acceso es una combinación de protected OR internal. Es decir, el acceso está restringido a cualquier código en la misma asamblea y sólo a las clases derivadas en otra asamblea.
CI
protected internal
Tome Nota
ET
Debería utilizar el nivel de acceso más restrictivo que tenga sentido para un miembro de tipo.
; ¿Listo para la certificación? ¿Comprende el encapsulamiento? -2.4
Los modifcadores de acceso no están permitidos en las declaraciones de espacio de nombres pero se implica un acceso público para los espacios de nombre. Las clases de alto nivel (declaradas directamente bajo un espacio de nombres) sólo pueden ser public o internal. El modifcador de acceso internal es el predeterminado para una clase si no se especifca ningún modifcador de acceso. La clase Rectangle defnió en el ejercicio anterior elementos predeterminados para tener un acceso interno. La accesibilidad de una clase anidada puede no ser menos restrictiva que la accesibilidad de una clase contenedora.
Introducción a la programación orientada a objetos
57
Comprender la herencia È EN RESUMEN
Después de haber introducido un valor o texto en una celda, lo puede modifcar de varias maneras. Puede eliminar el contenido por completo, ingresar un valor diferente para reemplazar el que estaba o alterar lo que ingresó.
Tome Nota
Digamos que queremos crear un conjunto de clases que describa polígonos como rectángulos o triángulos. Estas clases tendrán algunas propiedades en común como anchura y longitud. Para este caso, se puede crear una clase base Polygon con las propiedades Width y Length, y las clases derivadas Rectangle y Triangle heredarán estas propiedades a la vez que cuentan con su propia funcionalidad. El siguiente ejercicio explica lo anterior de forma más detallada.
ÁM
A diferencia de las clases, las estructuras no soportan la herencia.
ER ICA
La herencia le permite crear clases nuevas que reutilizan, extienden y modifcan la funcionalidad defnida en las clases existentes. La clase que hereda la funcionalidad se conoce como clase derivada y la clase cuya funcionalidad es heredada se conoce como clase base. La clase derivada hereda toda la funcionalidad de la clase base y puede contener características adicionales que la hace diferente de la clase base.
Æ Crear clases derivadas
www.pdftron.com UTILICE el proyecto que guardó en el ejercicio anterior.
1. Agregue una nueva clase Polygon como se muestra a continuación:
RO
class Polygon {
public double Length { get; protected set; }
BE
public double Width { get; protected set; }
}
2. Modifique la clase Rectangle como se muestra a continuación: class Rectangle : Polygon
ET
CI
{
public Rectangle(double length, double width) { Length = length; Width = width; } public double GetArea() { return Width * Length; }
}
58
Lección 2
3. Modifique el código del método Main como se muestra a continuación: static void Main(string[] args) { Rectangle rect = new Rectangle(10, 20); Console.WriteLine( “Width={0}, Length={1}, Area = {2}”, }
ER ICA
rect.Width, rect.Length, rect.GetArea()); 4. Seleccione Depurar y después Iniciar sin depurar. Aparecerá una ventana de consola para mostrar la anchura, longitud y área del rectángulo. 5. GUARDE su proyecto.
PAUSA. Deje el proyecto abierto para utilizarlo en el siguiente ejercicio.
ÁM
Para defnir una clase derivada, coloque dos puntos después del nombre de la clase derivada seguido del nombre de la clase base. Aquí la clase Polygon es la clase base para la clase Rectangle.
Las propiedades Length y Width en la clase Polygon se declaran como un modifcador de acceso protegido para el accessor set. Esto signifca que el acceso al accesor set está disponible sólo desde dentro de la clase Polygon y sus clases derivadas. Aun puede obtener el valor de las propiedades Length y Width en el método Main pero obtendrá un error si intenta asignar un valor a estas propiedades.
RO
www.pdftron.com La clase Rectangle hereda todos los datos no privados y el comportamiento de la clase Polygon. Además, la clase Rectangle defne funcionalidad adicional (método GetArea) que no está disponible en la clase base.
BE
Comprender las clases abstractas y selladas
ET
CI
Las clases abstractas proporcionan una defnición común de la clase base que se pueden compartir por varias clases derivadas. Las clases selladas, por otro lado, cuentan con una funcionalidad completa pero no se pueden utilizar como clases bases. En el ejercicio anterior defnió un método GetArea en la clase Rectangle. Suponga que quiere crear otra clase, Triangle, que es del tipo Polygon. Ahora, necesitará un método GetArea en la clase Triangle para calcular el área de un triángulo.
Con frecuencia, las clases base actúan como el repositorio de la funcionalidad común. En el caso de Polygon, el polígono en sí no sabrá cómo calcular el área sin contar con el conocimiento sobre el tipo de forma. Pero en general, podemos esperar que todas las clases del tipo Polygon sean capaces de calcular sus propias áreas. Tales expectativas pueden depender de la clase base con la ayuda de una palabra reservada abstract.
Æ Crear clases abstractas UTILICE el proyecto que guardó en el ejercicio anterior. 1. Modifique la clase Polygon como se muestra a continuación:
Introducción a la programación orientada a objetos
59
abstract class Polygon { public double Length { get; protected set; } public double Width { get; protected set; } abstract public double GetArea(); }
ER ICA
2. Modifique la clase Rectangle como se muestra a continuación: class Rectangle : Polygon {
public Rectangle(double length, double width) {
Length = length; }
ÁM
Width = width;
www.pdftron.com public override double GetArea() {
RO
return Width * Length;
}
}
BE
3. No se necesita realizar modificaciones al método Main. Seleccione Depurar, Iniciar sin depurar. Aparecerá una ventana de consola para mostrar el ancho, longitud y área del rectángulo.
4. GUARDE su proyecto.
ET
CI
PAUSA. Deje el proyecto abierto para utilizarlo en el siguiente ejercicio.
Tome Nota No puede crear instancias de una clase abstracta.
Esta versión de la clase Polygon defne un método de nombre GetArea. La razón principal para incluir este método en la clase base es que ahora la clase base puede proporcionar una plantilla común de funcionalidad para las clases derivadas. Pero, como ya se comentó, la clase base Polygon no conoce lo sufciente para calcular el área de la forma. La situación se puede manejar haciendo el método abstracto. Un método abstracto cuenta con una defnición pero no proporciona ninguna implementación (cuerpo de método). Si ninguno de los miembros de la clase es abstracto, la clase en sí necesita marcarse como abstracta. No se puede instanciar una clase abstracta.
Las clases derivadas pueden proporcionar una implementación de la clase abstracta para crear una clase concreta (clase no abstracta). La clase derivada puede proporcionar una implementación de un método abstracto al sobrescribirlo en una clase derivada. Por ejemplo, la clase Rectangle sobrescribe el método abstracto GetArea de la clase base y proporciona una implementación completa. Como resultado, la clase Rectangle ya no es una clase abstracta y se puede instanciar de forma directa.
60
Lección 2
Las clases selladas, por otro lado, se defnen cuando su implementación está completa y no quiere que se herede una clase. Una clase sellada se puede crear utilizando la palabra reservada sealed como se muestra a continuación: sealed class Rectangle : Polygon { // miembros de la clase aquí }
ER ICA
Puesto que Rectangle es una clase sellada, no se puede utilizar como una clase base. También es posible marcar miembros de la clase seleccionados como sellados para evitar que se sobrescriban en una clase derivada. Por ejemplo, puede decir: sealed public override double GetArea()
Tome Nota
{
return Width * Length; }
Esta declaración asegura que el método GetArea no se pueda sobrescribir en una clase derivada.
ÁM
C# no soporta la herencia de más de una clase base, a lo cual se le conoce como herencia múltiple.
www.pdftron.com Herencia desde la clase Object
RO
La clase Object es la clase base más importante de todas las clases en el .NET Framework.
Todas las clases en el .NET Framework heredan de forma directa o indirecta de la clase Object. Por ejemplo, cuando declaró la siguiente clase anteriormente: class Polygon
BE
{
public double Length { get; protected set; } public double Width { get; protected set; }
ET
CI
}
era funcionalmente equivalente a la siguiente declaración: class Polygon : Object {
public double Length { get; protected set; } public double Width { get; protected set; } }
Pero no tiene que declarar la clase Polygon de la segunda manera porque la herencia de la clase Object se asume de forma implícita. Como parte de esta herencia, una clase derivada sobrescribe los métodos de la clase Object. Dos de los métodos más comunes son:
•
Equals: Soporta la comparación entre dos objetos. Retorna true si los dos objetos tienen el mismo valor.
Introducción a la programación orientada a objetos
•
61
ToString: Retorna una representación string de la clase. De manera predeterminada, retorna el nombre complete de la clase. Es con frecuencia útil para sobrescribir este método para que regrese una representación string del estado actual del objeto.
El siguiente ejemplo muestra como sobrescribir el método ToString en la clase Rectangle: class Rectangle : Polygon public Rectangle(double length, double width) {
}
Length = length;
ER ICA
{
Width = width;
public override double GetArea() { }
return Width * Length;
ÁM
public override string ToString()
www.pdftron.com {
return String.Format(
“Width = {0}, Length = {1}”, Width, Length);
RO }
}
BE
Casting entre tipos
El tiempo de ejecución le permite castear un objeto a cualquiera de sus tipos base.
ET
CI
Las clases derivadas tienen una relación “es un” con la clase base. Por ejemplo, podemos decir que el Rectángulo es un Polígono. Un objeto de la clase Rectangle tiene en este caso dos tipos de datos: el objeto es un Rectángulo y el objeto es también un Polígono.
El tiempo de ejecución le permite castear un objeto a su clase o a cualquiera de sus clases base. Por ejemplo, puede decir: Polygon p = new Rectangle(10, 20);
Aquí, se crea un nuevo objeto Rectangle y se castea a su tipo base Polygon. C# no requiere de una sintaxis especial porque castear a un tipo base se considera una conversión segura. También se puede castear de la siguiente manera: Object o = new Rectangle(10, 20); … Rectangle r = (Rectangle) o;
62
Lección 2
Aquí, un objeto Rectangle se asigna primero a un Object (la clase base fundamental) y el objeto resultante se castea de vuelta como un Rectangle. Cuando sucede la última asignación, se requiere de un casteo explicito porque convertirá un objeto más general a un objeto menos general. El tiempo de ejecución revisa si el valor de la variable o es compatible con la clase Rectangle. Si en tiempo de ejecución el valor de o no es compatible con la clase Rectangle, el tiempo de ejecución arroja una System.InvalidCastException.
El operador is
if (o is Rectangle) {
Rectangle r = (Rectangle) o; }
Aquí el tiempo de ejecución revisará el valor del objeto o. La sentencia cast sólo se ejecuta si o contiene un objeto Rectangle.
ÁM
Si se encuentra utilizando un operador as para convertir un tipo, la revisión del operador is no es necesaria. Puede simplemente revisar el valor de retorno de as contra null.
ER ICA
Para evitar errores en tiempo de ejecución como InvalidCastException, se utiliza el operador is para revisar si se permite el casteo antes de llevarlo a cabo:
Tome Nota
www.pdftron.com El operador as
RO
Otro operador cast útil es el operador as. El operador as es similar a la operación cast pero, en el caso de as, si el tipo de conversión no es posible, se retorna null en lugar de arrojar una excepción. Por ejemplo, considere este código: Rectangle r = o as Rectangle; if (r != null)
BE
{
// hacer algo
; ¿Listo para la certificación?
Si en tiempo de ejecución, no es posible castear el valor de la variable o a rectangle, se asigna un valor null a la variable r. No se arrojarán excepciones.
CI
¿Comprende la herencia? -2.2
}
ET
Comprender el polimorfismo È EN RESUMEN
El polimorfismo es la capacidad de las clases derivadas para compartir una funcionalidad en común con las clases base pero defniendo su propio comportamiento. Digamos que se encuentra desarrollando una aplicación que permite a los usuarios trabajar con diferentes tipos de polígonos. Cuenta con una colección que contiene diferentes tipos de polígonos como un rectángulo, un triángulo y un cuadrado. Cada polígono le provee con su propia implementación del método Draw. Cuando trabaja con esta colección, no
Introducción a la programación orientada a objetos
63
necesariamente debe saber exactamente con cual forma está trabajando sino que preferirá que se invoque el método Draw correcto en cada ocasión. El polimorfsmo le permite realizar esto. El polimorfsmo permite a los objetos de la clase derivada que se les trate en tiempo de ejecución como el objeto de la clase base. Cuando se invoca un método en tiempo de ejecución, su tipo exacto se identifca y se invoca el método apropiado desde la clase derivada.
ER ICA
Æ Uso del polimorfismo UTILICE el proyecto que guardó en el ejercicio anterior.
1. Modifique la clase Polygon como se muestra a continuación: class Polygon {
public virtual void Draw() { }
ÁM
Console.WriteLine(“Dibujando: Polígono”);
www.pdftron.com }
2. Modifique la clase Rectangle como se muestra a continuación:
RO
class Rectangle : Polygon {
public override void Draw()
BE
{
Console.WriteLine(“Dibujando: Rectángulo”);
}
CI
}
3. Agregue una nueva clase, Triangle, como se muestra a continuación: class Triangle : Polygon
ET
{
public override void Draw() { Console.WriteLine(“Dibujando: Triángulo”); } } 4. Modifique el método Main como se muestra a continuación: static void Main(string[] args) {
64
Lección 2
List polygons = new List(); polygons.Add(new Polygon()); polygons.Add(new Rectangle()); polygons.Add(new Triangle()); foreach (Polygon p in polygons) { } }
ER ICA
p.Draw();
5. Seleccione Depurar y después Iniciar sin depurar. Aparecerá una ventana de consola para mostrar el mensaje sobre el dibujo de cada polígono. 6. GUARDE su proyecto.
PAUSA. Deje el proyecto abierto para utilizarlo en el siguiente ejercicio.
Tome Nota
ÁM
En este ejercicio, las defniciones de las clases Polygon y Rectangle se simplifcan para enfatizar el concepto de polimorfsmo. La clase base proporciona un solo método Draw. Lo importante aquí es notar la palabra reservada virtual. Esta palabra permite a las clases derivadas sobrescribir el método.
www.pdftron.com RO
Tanto la clase Rectangle como Triangle sobrescriben el método Draw de la clase base con sus propias defniciones utilizando la palabra reservada override. Cuando se ejecuta el método Main se genera el siguiente resultado: Dibujando: Polígono
Dibujando: Rectángulo Dibujando: Triángulo
BE
Si el método en una clase derivada no se encuentra precedida por las palabras new u override, el compilador afrontará una advertencia y el método se comportará como si la palabra new estuviera presente.
ET
CI
El tipo de datos List es capaz de almacenar una colección de objetos que son del tipo Polygon o tipos que derivan de Polygon. EL ciclo foreach se encuentra iterando en una colección de objetos Polygon. El tipo subyacente del primer objeto es Polygon, pero el segundo y tercer objeto en la colección son de hecho objetos Rectangle y Triangle que se acaban de castear como Polygons. El tiempo de ejecución verá en el tipo subyacente e invocará el método de sobrescritura desde la clase derivada. Esa es la razón por la cual la versión de la clase derivada del método Draw se llama tanto para los objetos Rectangle como Triangle.
Comprender las palabras reservadas override y new La palabra reservada override reemplaza un miembro de la clase base en una clase derivada. La palabra reservada new crea un nuevo miembro del mismo nombre en la clase derivada y oculta la implementación de la clase base. Cuando una clase base defne un miembro virtual, la clase derivada tiene dos opciones para manejar esta situación: la clase derivada puede utilizar ya sea la palabra override o new. La palabra override toma la prioridad sobre la defnición de la clase base del miembro. El objeto de la clase derivada llamará el miembro sobrescrito en lugar del miembro de la clase base.
Introducción a la programación orientada a objetos
65
Si se utiliza la palabra reservada new, se crea una nueva defnición del miembro y se oculta el miembro de la clase base. Sin embargo, si la clase derivada se castea a una instancia de la clase base, se pueden seguir llamando a los miembros ocultos de la clase. Modifquemos el método Triangle del ejercicio anterior a lo siguiente: class Triangle : Polygon { public new void Draw() { } La clase System.Object proporciona un método ToString. Por estándar, debe utilizar este método para retornar la representación legible para el humano con respecto a una clase. Cuando cree sus tipos, es recomendable practicar la sobrescritura de este método para retornar información legible sobre los objetos.
}
Ahora modifquemos el código en la clase Main de la siguiente manera: Triangle t = new Triangle(); t.Draw();
ÁM
Tome Nota
ER ICA
Console.WriteLine(“Dibujando: Triángulo”);
Polygon p = t;
www.pdftron.com El programa producirá el siguiente resultado:
RO
Dibujando: Triángulo Dibujando: Polígono
Cuando se invoca directamente el método Draw en el objeto de la clase derivada, se utiliza la nueva versión del método. Sin embargo, si se ejecuta el método cuando la clase derivada se castee como una clase base, se ejecuta la versión oculta de la clase base del método Draw.
BE
; ¿Listo para la certificación?
p.Draw();
CI
¿Comprende el polimorfismo? -2.3
ET
Comprender las interfaces È EN RESUMEN
Las interfaces se utilizan para establecer contratos a través de los cuales los objetos pueden interactuar entre sí sin conocer los detalles de implementación. Las interfaces se defnen utilizando la palabra reservada interface. Una defnición de interface consiste en un conjunto de frmas para métodos, propiedades, delegados, eventos o indexadores. Una defnición de interface no puede consistir de ningún campo de datos o detalles de implementación como cuerpos de métodos. Una interface común defnida en el espacio de nombres System es el espacio IComparable.
66
Lección 2
Esta interface se defne de la siguiente manera: interface IComparable { int CompareTo(object obj); }
Por estándar, todas las interfaces definidas en el .NET Framework empiezan con la letra I mayúscula. Aun cuando puede asignar nombres a sus interfaces de la forma que quiera, es mejor utilizar el estándar de Framework.
La interface IComparable tiene un solo método (CompareTo) que acepta un objeto y retorna un int. El valor de retorno de este método indica el resultado de comparar un parámetro dado con el objeto actual. De acuerdo con la documentación del método CompareTo:
• • • •
ER ICA
Tome Nota
Si la instancia es igual al parámetro, CompareTo retorna 0. Se retorna un valor positivo si el valor del parámetro es menor que la instancia o si el parámetro es null. Si el valor del parámetro es mayor que la instancia entonces se retorna un valor negativo. Si el parámetro no es de tipo compatible, entonces se arroja una ArgumentException.
ÁM
¿Cómo es que IComparable decide cómo comparar dos objetos Rectangle o dos objetos Employee? No lo hace. Las clases que están interesadas en tales comparaciones deben implementar la interface IComparable al proporcionar un cuerpo de método para el método CompareTo. Cada clase que implementa IComparable es libre de proporcionar su propia comparación lógica dentro del método CompareTo.
RO
www.pdftron.com Æ Uso de la interface IComparable
UTILICE el proyecto que guardó en el ejercicio anterior.
BE
1. Modifique la clase Rectangle como se muestra a continuación: class Rectangle : Polygon, IComparable {
public double Length { get; set; }
ET
CI
public double Width { get; set; } public override void Draw() {
Console.WriteLine(“Dibujando: Rectángulo”); } public double GetArea() { return Length * Width; }
Introducción a la programación orientada a objetos
67
public int CompareTo(object obj) { if (obj == null) return 1; if (!(obj is Rectangle))
ER ICA
throw new ArgumentException(); Rectangle target = (Rectangle)obj;
double diff = this.GetArea() - target.GetArea(); if (diff == 0) return 0;
else if (diff > 0) return 1;
ÁM
else return -1;
www.pdftron.com }
}
2. Modifique el método Main como se muestra a continuación:
RO
static void Main(string[] args) {
Rectangle rect1 = new Rectangle
BE
{ Length = 10, Width = 20 };
Rectangle rect2 = new Rectangle
ET
CI
{ Length = 100, Width = 200 };
Console.WriteLine(rect1.CompareTo(rect2));
}
3. Seleccione Depurar y después Iniciar sin depurar. Aparecerá una ventana de consola al valor -1 puesto que el área de rect1 es menor que el área de rect2. GUARDE su proyecto.
La clase Rectangle deriva se la clase Polygon e implementa la interface IComparable. Una clase que implementa una interface debe implementar todos los métodos declarados en la interface. Una interface es similar a una clase abstracta pero hay diferencias notables. Una clase abstracta proporciona una implementación incompleta mientras que una interface no proporciona ninguna implementación. Una clase también puede implementar múltiples interfaces pero está limitada a heredar de una sola clase base.
68
Lección 2
; ¿Listo para la certificación?
ÁM
ER ICA
¿Comprende el encapsulamiento? -2.4
Por lo que, ¿cómo decide si utilizar una clase abstracta o una interface? Una forma de decidir es revisar si existe una relación “es un” entre los dos conceptos. Por ejemplo, si existe una relación de herencia entre SalariedEmployee y Employee, entonces puede utilizar una clase abstracta para estandarizar la funcionalidad común entre clases derivadas. Por otro lado, no hay una relación “es un” entre Employee y la IComparable. Por lo tanto, la funcionalidad de comparación es mejor si se implementa como una interface.
ET
CI
BE
RO
www.pdftron.com
Comprender los conceptos básicos de bases de datos
69
Resumen de la matriz de habilidades En esta lección aprendió:
• •
•
ER ICA
• • •
La programación orientada a objetos es una técnica de programación que utiliza objetos. Los objetos son estructuras de datos auto contenidas que consisten de propiedades, métodos y eventos. Las propiedades especifcan los datos representados por el objeto; los métodos especifcan el comportamiento del objeto y los eventos proporcionan la comunicación entre los objetos. Una clase es la plantilla a partir de la cual se crean los objetos individuales. Los constructores se utilizan para inicializar los miembros de datos del objeto. La palabra reservada this se pueden utilizar para acceder a los miembros desde dentro de los constructores, métodos de instancia y accessors de propiedades de instancia. Los delegados son tipos especiales utilizados para encapsular un método dentro de una frma específca. Los eventos son una forma en la cual una clase notifca a otras clases u objetos cuando sucede algo de interés. La clase que envía la notifcación se conoce como editor del evento. La clase que recibe la notifcación se conoce como suscriptor del evento. Los espacios de nombre le permiten organizar código y crear nombres de clase únicos. La palabra reservada static se utiliza para declarar miembros que no pertenecen a objetos individuales sino a la clase en sí. Los tipos de valor almacenan directamente el valor mientras que los tipos de referencia almacenan solo la referencia al valor real. La palabra reservada struct se utiliza para crear tipos defnidos por el usuario que consisten de pequeños grupos de campos relacionados. Las estructuras son tipos de valor, las clases son tipos de referencias. El encapsulamiento es un mecanismo para restringir el acceso a una clase o miembros de la clase para ocultar las decisiones de diseño que pueden cambiar. El encapsulamiento proporciona a los diseñadores de la clase la fexibilidad para cambiar el código cuando sea necesario sin cambiar todo el código involucrado. Un modifcador de acceso especifca la región de código a la cual tendrá acceso un campo. Por ejemplo, un modifcador de acceso público no limita el acceso, pero un privado limita el acceso dentro de la clase en la cual se defna el campo. La herencia le permite crear clases nuevas que reutiliza, extienden y modifcan la funcionalidad defnida en clases existentes. La clase que hereda funcionalidad se conoce como clase derivada y la clase cuya funcionalidad se hereda se conoce como clase base. El polimorfsmo es la capacidad que tienen las clases derivadas para compartir funcionalidad con las clases base pero aun defniendo su propio comportamiento único. La palabra reservada override reemplaza un miembro de la clase base en una clase derivada. La palabra new crea un nuevo miembro con el mismo nombre en la clase derivada y oculta la implementación en la clase base.
ÁM
•
www.pdftron.com •
RO
• •
BE
•
ET
CI
• •
• •
70
Lección 2
» Evaluación de conocimiento Complete los espacios en blanco Complete los siguientes enunciados escribiendo la palabra o palabras correctas en los espacios proporcionados. 1. Una __________ es una huella de un objeto.
ER ICA
2. Una clase que no proporciona una implementación complete se debe declarar con la palabra reservada __________.
3. Las clases que quieran soportar la comparación deben implementar la interface IComparable y luego proporcionar un cuerpo para el método __________. 4. Puede utilizar el operador __________ para verifcar si es legal castear un tipo a otro.
5. Las tres características principales de un lenguaje de programación orientada a objetos son el __________, __________, y __________.
ÁM
6. Podemos utilizar __________ para agrupar clases relacionaras para reducir la colisión de nombres. 7. La palabra reservada __________ se refere a la instancia actual de la clase.
www.pdftron.com 8. Un tipo__________ es uno que referencia a un método.
9. Una __________ es un tipo de valor, mientras que una __________ es un tipo de referencia.
RO
10. Puede utilizar la palabra reservada __________ para declarar un miembro, el cual pertenece a la clase en sí en vez de a un objeto específco. Opción múltiple
BE
Encierre en un círculo la opción que contenga la respuesta correcta. 1. Desea restringir el acceso de un método a la clase contenedora o a una clase que se derive de la clase contenedora. ¿Cuál modifcador de acceso debería utilizar para utilizar este método? Public Private Protected Internal
ET
CI
a. b. c. d.
2. En una clase defnió un método llamado Render. Este método proporciona funcionalidad a los archivos Render bitmap en pantalla. Le gustaría que las clases derivadas sustituyeran esta funcionalidad para soportar la renderización de formatos de imágenes adicionales. Desea que el método Render de la clase derivada se ejecute aun si la clase derivada esté casteada como la clase base. ¿Cuál palabra reservada utilizaría con la defnición del método Render en la clase base? a. b. c. d.
Abstract Virtual New Overrides
Comprender los conceptos básicos de bases de datos
71
3. Defnió una clase AdvMath que defne funcionalidad matemática avanzada. No desea que la funcionalidad de esta clase se herede a una clase derivada. ¿Cuál palabra reservada debe utilizar para defnir la clase AdvMath? a. b. c. d.
Sealed Abstract Private Internal
ER ICA
4. Necesita proporcionar la funcionalidad de consulta a varias de sus clases. Cada algoritmo de clase para consulta será diferente. No todas las clases tienen una relación “es un” entre sí. ¿Cómo soportaría esta funcionalidad? a. Agregar a la funcionalidad de consulta a la clase base con el modifcador de acceso público. b. Hacer que todas las clases hereden de la clase abstracta y sobrescriban el método de la clase base para ofrecer su propia funcionalidad de consulta. c. Hacer que todas las clases hereden de la clase base que proporcione la funcionalidad de consulta. d. Crear una interfaz común que se implemente por todas las clases.
a. b. c. d.
ÁM
5. ¿Cuál de los siguientes elementos de clase debería utilizar para defnir el comportamiento de una clase? Método Propiedad Evento Delegado
www.pdftron.com RO
6. Se encuentra escribiendo un código para una clase de nombre Product. Necesita asegurarse que los miembros de datos de las clases se inicialicen en sus valores correctos tan pronto como cree un objeto de la clase Product. El código de inicialización se debe ejecutar siempre. ¿Qué es lo que debería hacer?
ET
CI
BE
a. Crear un método estático en la clase Product para inicializar los miembros de datos. b. Crear un constructor en la clase Product para inicializar los miembros de datos. c. Crear una propiedad estática en la clase Product para inicializar los miembros de datos. d. Crear un evento en la clase Product para inicializar los miembros de datos.
7. Se encuentra creando una nueva clase de nombre Square que se deriva de la clase Polygon. La clase Polygon tiene el siguiente código: a. class Polygon b. { c. public virtual void Draw() d. { e. // código adicional... f. } g. }
8. El método Draw en la clase Square debe proporcionar nuevas funcionalidades pero también oculta la implementación de la clase Polygon del método Draw. ¿Cuál segmento de código debería elegir? a. class Square : Polygon
72
Lección 2
{ public override void Draw() { // código adicional... } }
b. class Square : Polygon
{
ER ICA
public new void Draw() {
// código adicional... } }
c. class Square : Polygon
{
ÁM
public virtual void Draw() {
www.pdftron.com // código adicional...
}
RO
}
d. class Square : Polygon
{
public static void Draw()
BE
{
// código adicional...
}
ET
CI
}
9. Se encuentra creando una nueva clase de nombre Rectangle. Escribe el siguiente código: class Rectangle : IComparable { public double Length { get; set; } public double Width { get; set; } public double GetArea() { return Length * Width; }
Comprender los conceptos básicos de bases de datos
73
public int CompareTo(object obj) { // a completarse } }
10. Necesita completar la defnición del método CompareTo para habilitar la comparación de los objetos de Rectangle. ¿Cuál de los siguientes códigos debería escribir? {
public int CompareTo(object obj)
ER ICA
a.
Rectangle target = (Rectangle)obj;
double diff = this.GetArea() - target.GetArea(); if (diff == 0) return 0;
else if (diff > 0)
ÁM
return 1;
else return -1;
www.pdftron.com }
b.
RO
{
public int CompareTo(object obj)
Rectangle target = (Rectangle)obj;
double diff = this.GetArea() - target.GetArea();
BE
if (diff == 0) return 1;
ET
CI
else if (diff > 0) return -1;
else return 0; }
c.
{
public int CompareTo(object obj) Rectangle target = (Rectangle)obj; if (this == target) return 0; else if (this > target) return 1; else return -1;
74
Lección 2
}
d. public int CompareTo(object obj) {
Rectangle target = (Rectangle)obj; if (this == target) return 1; return -1; else return 0; }
ER ICA
else if (this > target)
11. Se encuentra escribiendo un código para un nuevo método de nombre Process:
ÁM
a. void Process(object o) b. { c. d. }
www.pdftron.com RO
12. El código recibe un parámetro de tipo objeto. Necesita castear este objeto en el tipo Rectangle. En ocasiones, el valor de o enviado al método puede no ser un valor de Rectangle válido. Necesita asegurarse que el código no genere ningún error System. InvalidCastException al hacer las conversiones. ¿Cuál de las siguientes líneas de código debería utilizar dentro del método Process? Rectangle r = (Rectangle) o;
Rectangle r = o as Rectangle; Rectangle r = o is Rectangle;
Rectangle r = (o != null) ? o as rectangle:(Rectangle) o;
BE
a. b. c. d.
ET
CI
13. Se encuentra escribiendo el código para controlar los eventos en su programa. Defne un delegado de nombre RectangleHandler como el siguiente: a. public delegate void RectangleHandler(Rectangle rect); b. También crea una variable del tipo RectangleHandler como el siguiente:
c. RectangleHandler handler;
14. Más adelante en el programa, necesita agregar un método de nombre DisplayArea a la lista de invocación de métodos de la variable controladora. La frma del método DisplayArea corresponde al de la frma del método RectangleHandler. Cualquier código que escriba no debería afectar ningún código controlador de eventos existente. ¿Cuál de los siguientes códigos debería escribir? a. b. c. d.
Handler = new Rectanglehandler(DisplayArea); Handler = DisplayArea;
Handler += DisplayArea; Handler -= DisplayArea;
Comprender los conceptos básicos de bases de datos
75
» Evaluación de destreza Escenario 2-1: Creación de propiedades
ER ICA
Necesita crear una clase de nombre Product que represente un producto. La clase tiene una sola propiedad de nombre Name. Los usuarios de la clase Product deben ser capaces tanto de obtener como de establecer el valor de la propiedad Name. Sin embargo, cualquier intento por establecer el valor de Name a una cadena vacía o a un valor null debe arrojar una excepción. El usuario de la clase Product no debe ser capaz de acceder a cualquier otro miembro de datos de la clase Product. ¿Cómo creará esta clase?. Escenario 2-2: Creación de un Struct
Se encuentra desarrollando un juego que necesita representar la ubicación de un objetivo en el espacio tridimensional. La ubicación se identifca por los tres valores enteros x, y y z. Creará miles de estas estructuras de datos en su programa. Necesita una forma efciente para almacenar estos datos en memoria. Es improbable que necesite heredar cualquier otro tipo desde este tipo de ubicación. ¿Cómo debería representar la ubicación en su programa?.
ÁM
Evaluación de destreza
Proyecto 2-3: Sobrescribiendo el método ToString
www.pdftron.com RO
Se encuentra escribiendo un código para una clase Product. La clase Product contiene el nombre y el precio de un producto. Necesita sobrescribir el método de la clase base (System.Object) ToString para proporcionar información sobre los objetos de la clase product al código invocador. ¿Cuál código necesita escribir para la clase Product para cumplir con este requisito?. Proyecto 2-4: Creación y manejo de eventos
BE
Se encuentra escribiendo un código para la creación y manejo de eventos en su programa. La clase SampleClass necesita implementar la siguiente interface:
ET
CI
public delegate void SampleDelegate(); public interface ISampleEvents {
event SampleDelegate SampleEvent; void Invoke();
}
Necesita escribir el código para SampleClass y para un método test que crea una instancia de SampleClass e invoca el evento. ¿Cuál código debería escribir?. En una clase defnió un método llamado Render. Este método proporciona funcionalidad a los archivos Render bitmap en pantalla. Le gustaría que las clases
Lección 2
ÁM
ER ICA
76
ET
CI
BE
RO
www.pdftron.com
Lección 3
Desarrollo General de Software Matriz de Dominio de Objetivos Descripción del Dominio de Objetivo
Número del Dominio del Objetivo
Comprender la Administración del Ciclo de Vida de una Aplicación
Comprender la Administración del Ciclo de Vida de una Aplicación
3.1
Comprender las Pruebas
Comprender la Administración del Ciclo de Vida de una Aplicación
3.1
Comprender las Estructuras de Datos
Comprender los algoritmos y estructuras de datos
3.3
Comprender los Algoritmos de Clasificación
Comprender los algoritmos y estructuras de datos
3.3
ÁM
ER ICA
Habilidad Tecnológica
www.pdftron.com Términos Clave
• Ordenamiento rápido • Colas • Pruebas de regresión • Pilas
• Pruebas de unidad • Pruebas de caja blanca
BE
RO
• Arreglos o vectores • Pruebas de caja negra • Ordenamiento de burbuja • Listas enlazadas
ET
CI
Como desarrollador para la Corporación de Northwind, trabaja como parte de un equipo para desarrollar programas de computadora que resuelven problemas de negocios complejos. Como desarrollador, participa en el ciclo de vida de desarrollo de aplicaciones. Tiene que conocer las diferentes fases del ciclo de vida de aplicación y a menudo necesita interactuar con el equipo de pruebas de software y participar en las pruebas en persona. Necesita tener una comprensión general de las pruebas de software. Cuando desarrolla software utiliza varios tipos de estructuras de datos y algoritmos. Necesita saber cuál estructura de datos utilizar para cada una de las áreas a desarrollar así como conocer las implicaciones de su elección. También debe tener una comprensión general de varios métodos de ordenación.
78
Lección 3
Comprender la Administración del Ciclo de Vida de una Aplicación È EN RESUMEN
ER ICA
La Administración del Ciclo de Vida de una Aplicación se refere a las distintas actividades que giran en torno a un nuevo producto de software desde su comienzo hasta que el producto de software madura y eventualmente se deshecha. Desarrollar una aplicación de software es más que solo escribir el código. Se necesita desarrollar distintas actividades en el orden correcto para desarrollar una aplicación de software exitosamente. Administrar estas actividades es conocido colectivamente como una Administración del Ciclo de Vida de Aplicación (ALM). Algunas de las actividades que son parte del proceso de ALM como se muestra en la Figura 3-1 son: Requerimientos, Diseño, Desarrollo, Pruebas, Entrega y Administración de Liberación. Figura 3-1
ÁM
Administración del Ciclo de Vida de Aplicación
BE
RO
www.pdftron.com En esta sección aprenderá acerca de las distintas actividades y roles involucrados en cada una de las actividades en la administración del ciclo de vida de una aplicación.
ET
CI
El ciclo de vida de aplicación inicia cuando la necesidad por una nueva aplicación de software es identifcada. El administrador de un negocio generalmente es la persona que patrocina el proyecto. Él o ella analizan la necesidad, verifcan cómo el proyecto encaja con la estrategia global del negocio, organiza la fnanciación e inicializa el proceso de selección de equipo para el proyecto. Un administrador del proyecto es probablemente la primera persona contratada por el administrador del negocio. Este administrador del proyecto es responsable de la ejecución global del proyecto. Las responsabilidades principales de un administrador de proyecto son el garantizar que el proyecto se ajuste al presupuesto y se termine en tiempo. El administrador de proyecto es responsable de la contratación de miembros del equipo y de facilitar la cooperación dentro del equipo.
Comprender el Análisis de Requerimientos El análisis de requerimientos es el proceso de determinar los requerimientos del negocio detallados para un nuevo sistema de software.
Desarrollo General de Software
79
El análisis de requerimientos es uno de los pasos más importantes en el ciclo de vida de aplicación. Requerimientos precisos, completos y bien documentados son críticos para el éxito del proyecto. Los requerimientos pueden ser funcionales o no funcionales. Los requerimientos funcionales especifcan exactamente lo que el sistema está diseñado para llevar a cabo. En contraste, los requerimientos no funcionales son requerimientos de calidad tales como la escalabilidad, seguridad, confabilidad, etc.
Comprender el Proceso de Diseño
ER ICA
Un analista de negocios es responsable de analizar las necesidades del negocio y convertirlas en requerimientos que pueden ser ejecutados por el equipo de desarrollo.
El proceso de diseño es utilizado para crear planes, modelos y la arquitectura de cómo el software será implementado. El proceso de diseño despliega especifcaciones técnicas detalladas que serán utilizadas por el desarrollo del sistema. La salida del proceso de diseño es un conjunto de modelos y especifcaciones técnicas que proporcionan la dirección a los desarrolladores y otros miembros del equipo durante la actividad de desarrollo de software. La salida del proceso de diseño es más abstracta que concreta. Por ejemplo, no existen sistemas reales con los cuales pueda interactuar.
ÁM
Algunos de los participantes importantes en esta actividad son:
www.pdftron.com •
RO
•
Un arquitecto diseña el proyecto del sistema. Esto incluye identifcar los componentes y servicios, su comportamiento y cómo interactúan entre sí y con el mundo exterior. Un diseñador de experiencia del usuario crea la experiencia del usuario del sistema. Los elementos de experiencia del usuario incluyen el diseño de los elementos de la interfaz de usuario (UI), diseñar la navegación entre varios formularios, pantallas o páginas, etc.
BE
Comprender el Desarrollo de Software
La actividad de desarrollo de software involucra la implantación de diseño creando código de software, bases de datos y otro contenido relacionado.
ET
CI
Esta es la actividad donde los requerimientos son implementados en código funcional basado en el diseño que fue establecido en la actividad previa. Al fnal de esta actividad, se tiene una salida concreta en formato de un sistema de software con el cual el usuario puede interactuar. Los participantes en el proceso de desarrollo son:
• • • •
Los desarrolladores escriben el código con base en los requerimientos reunidos por el analista de negocios, la arquitectura establecida por el arquitecto y la experiencia del usuario desarrollada por el diseñador de experiencia del usuario. Los administradores de bases de datos (DBAs) son responsables de la implementación y administración de la base de datos. Los DBAs también planean la integridad de datos, seguridad y velocidad. Los escritores técnicos desarrollan los manuales del sistema y archivos de ayuda que serán entregados junto con la aplicación. Los desarrolladores de contenido son expertos en la material quienes desarrollan el contenido del sistema. Por ejemplo, si la aplicación es un sitio web de reseña de
80
Lección 3
películas, no es sufciente sólo mostrar videos en el sitio, necesita asegurarse que hay sufciente contenido para reunir el interés del usuario.
Comprendiendo las Pruebas de Software La Prueba de Software verifca que la implementación coincide con los requerimientos del sistema.
ER ICA
La prueba de software es utilizada para asegurar la calidad del producto fnal. La prueba puede identifcar posibles lagunas entre las expectativas del sistema como se describen en el documento de requerimientos y el comportamiento real del sistema. Un punto importante en la prueba de software se lleva a cabo por los testers (probadores) quienes verifcan la aplicación en acción para asegurarse que satisface los requerimientos. Los problemas identifcados por los testers son asignados a una persona para repararlos. Por ejemplo, un defecto en el código será asignado a un desarrollador para repararlo.
Comprender la Administración de Liberación
ÁM
La actividad de administración de liberación es utilizada para administrar el desarrollo, entrega y soporte de liberaciones de software.
La administración de liberación incluye actividades tales como empaquetado y despliegue del software, administración de defectos de software y administración de solicitudes de cambio de software.
www.pdftron.com •
; ¿Listo para la certificación?
•
ET
CI
¿Comprende la administración del ciclo de vida de aplicación y sus actividades? — USD 3.1
Administrador de Liberación: el administrador de liberación coordina a varios equipos y unidades del negocio para garantizar la liberación a tiempo del producto de software. Personal de Operación: Se aseguran que el sistema sea entregado como se prometió. Esto podría involucrar quemar los DVDs y embarcarlos conforme se reciben las órdenes. O podría ser mantener un sistema de Software como un Service (SaaS) de forma regular. El personal de operación es también responsable de la liberación de cualquier actualización del sistema (con reparadores de errores o nuevas características). Personal de soporte técnico: Interactúan con clientes y ayudan a resolver sus problemas con el sistema. El soporte técnico puede generar métricas valiosas acerca de cuáles áreas del sistema son más difíciles para los usuarios y que posiblemente necesiten ser actualizadas en la próxima versión del software.
BE
•
RO
Los participantes principales en las actividades de administración son:
Comprender las Pruebas È EN RESUMEN
La prueba de software es el proceso de verifcar el software contra sus requerimientos. La prueba se realiza después de que la mayoría del trabajo de desarrollo es completado. La prueba de software es un proceso de verifcar que el software funciona como se espera y cumple todos sus requerimientos técnicos y de negocios. Cuando hay diferencia entre
Desarrollo General de Software
81
lo esperado y el comportamiento actual del sistema, un defecto de software (o “bug”) es registrado y eventualmente pasado al responsable para repararlo.
Comprender los Métodos de Prueba
ER ICA
Las pruebas de software involucran tanto pruebas funcionales y no funcionales. La prueba funcional es probar precisamente los requerimientos funcionales del sistema y las características que conforman la funcionalidad esencial. Por ejemplo, probar si el usuario puede agregar artículos a un carrito de compras es parte de la prueba funcional para un sitio web de comercio electrónico. Por otro lado, la prueba no funcional involucra pruebas de atributos de software que no son parte de la funcionalidad esencial pero son parte de los requerimientos no funcionales, tales como la escalabilidad, facilidad de uso, seguridad, etc.
Los métodos de prueba de software son generalmente divididos en pruebas de caja blanca y caja negra. Tradicionalmente hay dos enfoques en la prueba de software:
• •
Prueba de caja negra Prueba de caja blanca
ÁM
La prueba de caja negra trata al software como una caja negra, enfocándose sólo en las entradas y salidas. Cualquier conocimiento del funcionamiento del sistema interno no es utilizado para la prueba. En contraste, en la prueba de caja blanca, los testers utilizan su conocimiento del interior del sistema para probar el sistema. Por ejemplo, en la prueba de caja blanca, los testers tienen acceso al código fuente.
www.pdftron.com RO
Estas técnicas se complementan entre sí. La prueba de caja negra es más utilizada para asegurarse que todos los requerimientos son cubiertos. La prueba de caja blanca es utilizada para asegurarse que cada método o función tiene sus propios casos de prueba disponibles.
Comprender los Niveles de Prueba
BE
La prueba se lleva cabo en varias fases del ciclo de vida del desarrollo de aplicación. Los Niveles de Prueba especifcan donde tiene lugar la prueba del ciclo de vida. Los niveles de prueba están defnidos por donde tiene lugar la prueba en el ciclo de vida del desarrollo de software. Están los siguientes cinco niveles de prueba:
•
ET
CI
Tome Nota Es importante notar que el proceso de prueba de software puede sólo ayudar a encontrar defectos, no garantiza la ausencia de defectos. El software complejo tiene un gran número de posibles rutas de ejecución y muchos parámetros que pueden afectar su comportamiento. No es factible y a menudo no es posible probar todas las diferentes situaciones que encontrará el software en un entorno de producción.
•
Prueba de unidad: La prueba de unidad verifca la funcionalidad de una unidad de código. Por ejemplo, una prueba de unidad puede probar si un método retorna el valor correcto. La prueba de unidad es una prueba de caja blanca y a menudo es hecha por el desarrollador que escribe el código. La prueba de unidad a menudo utiliza una herramienta automatizada que puede simplifcar el desarrollo de casos y también mantiene registro de si una modifcación de software causa que falle alguna de las pruebas de unidad existentes. Visual Studio tiene soporte integrado para la prueba de unidad. También puede utilizar herramientas de apertura de código tales como NUnit para automatizar pruebas de unidad para código de.NET Framework. Prueba de Integración: La prueba de integración prueba la interfaz entre los componentes de software. La prueba de integración puede ser desempeñada incrementalmente conforme los componentes se desarrollan, o puede ser llevada a cabo como un “bigbang” cuando todos los componentes están listos para trabajar juntos. El primer método se prefere sobre el segundo puesto que reduce el riesgo e incrementa la confanza en el sistema que se esté desarrollando. La prueba de integración puede también involucrar la prueba de interacción de componentes
Lección 3
Tome Nota Es mucho más efectivo y menos costoso encontrar defectos antes que tarde en el ciclo de desarrollo de software.
• •
•
¿Comprende los distintos métodos de prueba? — USD 3.1
ÁM
•
; ¿Listo para la certificación?
con un sistema externo. Por ejemplo, si un componente se basa en datos de un servicio Web externo, la prueba de integración garantiza que el componente está funcionando correctamente con la aplicación externa. Prueba de sistema: La prueba de sistema es la prueba global del sistema de software. En este punto todos los componentes del sistema implementados están funcionando juntos y con cualquier sistema externo. Prueba de aceptación: Este nivel de prueba a menudo es desempeñado por los propios clientes. Generalmente hay dos niveles de pruebas aceptación previa a la liberación amplia del producto: prueba alfa y prueba beta. La prueba Alfa es desempeñada por un grupo muy limitado de usuarios y es una oportunidad para dar una vista de cerca al producto a los clientes más importantes y reunir retroalimentación. Las liberaciones Alfa pueden omitir algunas características y generalmente la falta de muchos atributos no funcionales tales como el rendimiento. En el siguiente nivel de prueba, la prueba beta, libera el producto a una audiencia más amplia de clientes y solicita retroalimentación. En términos de funcionalidad, la liberación beta del software es muy cercana a la liberación fnal. Sin embargo, los equipos de desarrollo podrían estar trabajando en mejorar el rendimiento y reparando algunos defectos conocidos. Prueba de Regresión: Conforme los defectos son reportados y reparados, es importante asegurarse que una reparación no rompe nada que funcionaba previamente. Esto se lleva a cabo como parte de la prueba de regresión. Con cada nueva reparación, los testers de software ejecutan una serie de pruebas de regresión para asegurarse que la funcionalidad que se sabía que funcionaba aun funciona.
ER ICA
82
www.pdftron.com RO
Comprender las Estructuras de Datos È EN RESUMEN
BE
Las estructuras de datos son técnicas para organizar y almacenar datos en la memoria de la computadora. El cómo la información es almacenada afecta la manera en la cual los datos son recuperados y manipulados. Comprender una estructura de datos involucra comprender no solo el patrón de almacenamiento sino también conocer los métodos utilizados para crear, acceder y manipular la estructura de datos.
ET
CI
Las estructuras de datos son los bloques de construcción de la mayoría de los programas de computadora y permite a los desarrolladores el implementar funcionalidad compleja. La mayoría de los frameworks de programación proporcionan soporte integrado para una variedad de estructuras de datos y métodos asociados para manipular estas estructuras de datos. En esta sección aprenderá algunos tipos distintos de estructuras de datos de manera que está familiarizado con las técnicas generales para la manipulación de estructuras de datos.
Arreglos
Un arreglo es una colección de ítems almacenados en una ubicación de memoria contigua y direccionados utilizando uno o más índices. Un arreglo es una estructura de datos muy común que representa una colección de ítems de un tipo similar. Los ítems en un arreglo son almacenados en ubicaciones de memoria contigua. Un arreglo es una estructura de datos homogénea ya que todos los ítems de un arreglo son del mismo tipo de datos. Cualquier ítem del arreglo puede ser directamente accedido utilizando un índice. En .NET Framework, los índices de arreglo están basados en ceros.
Desarrollo General de Software
83
Representación Interna En el siguiente código, la primera sentencia crea una variable de arreglo y la segunda sentencia inicializa la variable con un arreglo de cuatro enteros: 1. int[] numbers; 2. numbers = new int[4];
ER ICA
Inicialmente, los números variables serán establecidos a null debido a que el arreglo aún no está inicializado. La segunda sentencia inicializa el arreglo asignando un espacio de memoria contigua lo sufcientemente grande para almacenar cuatro enteros en la pila de memoria. La dirección de inicio en la memoria asignada es almacenada en la variable del arreglo numbers como se muestra en la Figura 3-2. Todos los elementos del arreglo son inicializados en este caso con el valor 0 ya que es el valor por defecto para un entero. Figura 3-2
ÁM
Representación interna de una estructura de datos de un arreglo
RO
www.pdftron.com
ET
CI
BE
La variable numbers entonces actúa como una referencia a la ubicación de memoria asignada al arreglo. El nombre del arreglo puede ser utilizado para acceder a cada uno de los ítems de arreglo directamente. En el.NET Framework, todos los arreglos están basados en cero. Esto es, el primer ítem del arreglo es accedido utilizando un índice 0, como esto: numbers[0], el segundo ítem es accedido por numbers[1],y así sucesivamente.
También es posible tener arreglos multidimensionales. Un arreglo de dos dimensiones puede ser visto como una tabla donde cada celda es un elemento del arreglo y puede ser direccionado utilizando el número de fla y el número de columna al cual pertenece. Tanto el número de fla y el número de columna son indexados por cero. Por ejemplo, la expresión table[2, 3] se refere a un ítem en la tercera fla y en la cuarta columna de un arreglo por el nombre table.
Operaciones Comunes El arreglo soporta las siguientes operaciones:
• •
Asignación Acceso
Para trabajar con un arreglo, primero asigne la memoria creando e inicializando un arreglo
84
Lección 3
como se mostró previamente. Una vez que el arreglo es asignado, puede acceder a cualquier elemento del arreglo en cualquier orden que desee directamente referenciando a su índice. Por ejemplo, el siguiente código asigna un valor de 10 al cuarto ítem del arreglo, y el doble de ese valor es entonces asignado a la variable calc: 3. number[3] = 10; 4. intcalc = number[3] * 2;
Rendimiento y uso
ER ICA
Los contenidos de un arreglo son establecidos como un bloque contiguo de memoria y puede ser directamente accedido utilizando el índice del arreglo. Por lo tanto la lectura o escritura en un arreglo es extremadamente rápida. Sin embargo, los arreglos están limitados por los requerimientos de homogeneidad y de tamaño fjo. Aunque el tamaño del arreglo puede ser incrementado, el hacerlo requiere la reasignación de todos los elementos del arreglo y es una operación que consume tiempo. Los arreglos funcionan mejor cuando el número de ítems en la colección está predeterminado y se requiere de acceso rápido a cada ítem.
ÁM
En el.NET Framework, puede utilizar la clase ArrayList para aproximarse a los requerimientos de un vector para lograr la homogeneidad y un tamaño fjo. Un ArrayList es un tipo de colección que puede mantener ítems de cualquier tipo de datos y se puede expandir dinámicamente cuando sea necesario. Sin embargo, un ArrayList no es tan rápido como un arreglo.
www.pdftron.com RO
Colas
Una cola es una colección de ítems en la cual el primer ítem añadido a la colección es el primer en ser removido.
CI
BE
La estructura de datos de una cola imita una cola en vida real. En una cola, los ítems son procesados en el orden en el que fueron agregados a la cola. En una cola, los ítems siempre son agregados al fnal de la cola y son removidos desde el frente de la cola. Esto es comúnmente conocido como el primero que entra es el primero que sale (FIFO). La capacidad de una cola es el número de ítems que puede mantener. Sin embargo, conforme los elementos son agregados a la cola, la capacidad es incrementada automáticamente. Una cola es una estructura de datos heterogénea, lo que signifca que los ítems en una cola pueden ser de diferentes tipos de datos.
ET
Representación Interna
Con el fn de evitar la reubicación excesiva de espacio de memoria y permitir una administración sencilla, una cola a menudo es implementada internamente como un arreglo circular de objetos, como se muestra en la Figura 3-3. En la Figura 3-3, el índice cabeza apunta a la ubicación 2 en la cola. Ya que la cola es circular, mientras tenga registro de los apuntadores de cabeza y cola, no importa en cual ubicación empieza la cola. El índice cabeza apunta al primer ítem en la cola y el índice cola apunta al último ítem en la cola. Cuando un ítem es removido, la cabeza se mueve al siguiente ítem en la cola. Un nuevo ítem siempre es agregado al fnal y la cola inicia apuntando al ítem recién agregado. Los espacios null en la Figura 3-3 son los lugares vacíos en la cola que pueden ser llenados antes de que la cola necesite una reasignación de memoria.
Desarrollo General de Software
85
El .NET Framework proporciona una implementación de la estructura de datos de una cola como parte de la clase Queue en el espacio de nombres de System.Collections. En lenguajes de programación que no proporcionan una implementación de una cola, puede escribir su propia clase Queue utilizando una estructura de datos parecida a un arreglo y simulando las operaciones de una cola. Figura 3-3
ER ICA
Representación interna de una estructura de datos de una cola
Una versión genérica de la clase Queue está disponible como parte del espacio de nombres de System. Collections.Generic. Esta versión genérica es utilizada para crear una cola de ítems que son del mismo tipo de datos.
ÁM
Tome Nota
www.pdftron.com Operaciones Comunes
RO
Una cola soporta las siguientes operaciones comunes:
•
BE
•
Enqueue: Esta operación primero verifca si hay sufciente capacidad disponible en la cola para agregar un ítem más. Si la capacidad está disponible, el ítem es agregado al fnal de la cola. Si no hay espacio disponible en la cola, el arreglo es reasignado por un factor de crecimiento pre especifcado y luego el nuevo ítem es agregado a la cola. Dequeue: Esta operación remueve el elemento actual en la cabeza de la cola para apuntar al siguiente elemento en la cola, como se muestra en la Figura 3-3. Peek: La operación Peek le permite mirar el ítem actual en la posición de la cabeza sin removerlo realmente de la cola. Contains: Esta operación le permite determinar si existe un ítem en particular en la cola.
•
CI
•
ET
Rendimiento y Uso
Una cola es una estructura de datos de un propósito especial que es más adecuada para una aplicación donde necesita procesar ítems en el orden recibido. Algunos ejemplos pueden incluir una cola de impresión, sistema de mensajería y un calendario de trabajo. A diferencia de un arreglo, una cola no puede ser utilizada para acceder aleatoriamente a elementos. Las operaciones tales como enqueue y dequeue en realidad agregan y remueven los ítems de la cola.
Pilas Una pila es una colección de ítems en la cual el último ítem agregado es el primero en ser removido. Como opuesto a una cola, una pila es una estructura de datos en la que el ultimo que
86
Lección 3
entra es el primero que sale (LIFO). Puede pensar en una pila como la pila de platos de cena en un buffet de mesa. El último en ser agregado es el primero en ser removido. La capacidad de una pila es el número de ítems que puede mantener. Sin embargo, conforme los elementos son agregados a la pila, la capacidad es automáticamente incrementada. Una pila es una estructura de datos heterogénea, lo que signifca que los ítems en una pila pueden ser de diferentes tipos de datos.
Representación Interna
ER ICA
Una versión generic de la clase Stack está disponible como parte del espacio de nombres de System. Collections.Generic. Esta versión genérica es utilizada para crear una pila de ítems que son del mismo tipo de datos.
Un nuevo ítem siempre es agregado en la parte superior de la pila, y el fondo de la pila inicia apuntando al elemento recién agregado. Los ítems también son removidos desde la parte superior de la pila y cuando esto sucede, la parte superior de la pila es ajustada para apuntar al siguiente ítem en la pila.
El .NET Framework proporciona una implementación de la estructura de datos de pila como parte de la clase Stack en el espacio de nombres de System.Collections. En lenguajes de programación que no proporcionan una implementación de la pila, puede escribir su propia clase Stack utilizando una estructura de datos parecida al arreglo y simular las operaciones de la pila.
ÁM
Tome Nota
Como una cola, una pila a menudo es implementada como un buffer circular con el fn de evitar la reubicación de espacio en memoria y para una administración más sencilla. Una pila puede ser visualizada justo como la cola en la Figura3-3, excepto que la cola ahora es llamada tope de la pila y la cabeza es llamada fondo de la pila.
www.pdftron.com Operaciones Comunes
Push: La operación push primero verifca si hay capacidad sufciente disponible en la pila para agregar un ítem más. Si la capacidad está disponible, el ítem es agregado en la parte superior de la pila. Si no hay espacio en la pila, el arreglo es reubicado por un factor de crecimiento pre especifcado y entonces el nuevo ítem es agregado a la pila. Pop: La operación pop remueve el elemento de la parte superior de la pila y establece la parte superior para que apunte al siguiente elemento en la pila. Peek: La operación Peek le permite mirar en el ítem actual en la parte superior de la pila sin removerlo realmente de la pila. Contains: La operación Contains le permite determinar si un ítem en particular existe en la pila.
BE
•
RO
Una pila soporta las siguientes operaciones comunes:
•
CI
• •
ET
Rendimiento y Uso
Una pila es una estructura de datos con propósito especial que es más adecuada para aplicaciones donde necesita procesar ítems en orden del último que entra es el primero que sale. Una pila es una estructura de datos muy útil debido a sus aplicaciones en la administración de memoria en tiempo de ejecución, evaluación de expresión, registro de llamado de método, etc. A diferencia de un arreglo, una pila no puede ser utilizada para acceder a elementos aleatoriamente. Las operaciones tales como push y pop realmente agregan y remueven los ítems de la pila.
Listas Enlazadas Una lista enlazada es una colección de nodos ordenados de forma que cada nodo contiene un enlace al siguiente nodo en la secuencia.
Desarrollo General de Software
87
Una lista enlazada es una colección de nodos de tal manera que cada nodo contiene una referencia (o enlace) al siguiente nodo en la secuencia. A diferencia de un arreglo, los ítems en una lista enlazada no necesitan ser contiguos y por lo tanto una lista enlazada no requiere de reubicación de espacio en memoria para la lista entera cuando se necesita agregar más ítems.
Representación Interna En memoria, una lista enlazada puede ser visualizada como una colección de nodos, como se muestra en la Figura 3-4.
ER ICA
Figura 3-4 Representación interna de una estructura de datos de una lista enlazada sencilla
ÁM
Cada nodo contiene dos piezas de información: los datos correspondientes al nodo y el enlace al siguiente nodo. El primer nodo de la lista es llamado el nodo encabezado. Utilizando el enlace del nodo encabezado, puede llegar al siguiente nodo y continuar atravesando nodos hasta que el enlace fnal es un valor null. A menudo el termino cola es utilizado para referirse a la lista apuntada por el nodo encabezado, la cola es todo lo demás después del nodo encabezado. En la Figura 3-4, la cola es la lista enlazada iniciando desde el nodo B.
www.pdftron.com BE
Figura 3-5
RO
Algunas otras implementaciones de listas enlazadas pueden ser utilizadas dependiendo de los requerimientos. En una lista enlazada circular, el último nodo es la lista apuntando de regreso al primer nodo para crear un círculo. En una lista doblemente enlazada, cada nodo contiene dos enlaces, como se muestra en la Figura 3-5.
ET
CI
Representación de una estructura de datos de una lista doblemente enlazada
Un enlace es una referencia de dirección que apunta al siguiente nodo en la secuencia y el otro enlace es una referencia hacia atrás que apunta de regreso al nodo previo en la secuencia. Como puede imaginar, una lista doblemente enlazada es fácil de atravesar en cualquier dirección. El .NET Framework proporciona una clase LinkedList como parte del espacio de nombres de System.Collections.Generic. Esta clase implementa homogéneamente una lista doblemente enlazada de un tipo de datos específco. Puede escribir sus propias clases para implementar un diferente tipo de implementación de lista enlazada.
88
Lección 3
Operaciones Comunes Una lista enlazada soporta las siguientes operaciones comunes:
•
ÁM
•
Add: Agregar o insertar un ítem en una lista enlazada es un asunto de cambiar enlaces, como se muestra en la Figura 3-6. Digamos que le gustaría insertar un nuevo nodo (con valor Z) entre los nodos con valores A y B. primero necesita asignar memoria para el nuevo nodo y asignar el valor Z a la sección de datos del nodo. Luego, copiara la sección de enlace del nodo A a la sección de enlace del nodo Z de modo que el nodo Z está apuntando al nodo B. Finalmente, necesitará copiar la dirección del nodo Z recién creado a la sección de enlace del nodo A de manera que el nodo A inicia apuntando al nodo Z. Remove: Similar a la operación add, la operación de remove o delete es también asunto de cambiar enlaces. Por ejemplo, para eliminar el tercer nodo en la Figura 3-4, cambiará el enlace del Segundo nodo a un valor null. El tercer nodo ahora será una pieza de memoria sin referencia y eventualmente será retornada al pool de memoria disponible. Find: Esta operación encuentra un nodo con un valor dado en la lista enlazada. Para encontrar un valor, generalmente inicia desde el nodo encabezado y verifca si el valor coincide. Si no, seguirá el enlace al siguiente nodo y continuará la operación fnd hasta que alcance el fnal de la lista, lo cual sucede cuando encuentra un enlace null.
ER ICA
•
Figura 3-6
www.pdftron.com CI
BE
RO
Agregando un nuevo nodo a una lista enlazada
ET
Rendimiento y Uso
; ¿Listo para la certificación? ¿Comprende las estructuras de datos comunes? — USD 3.2
Una lista enlazada no permite acceso aleatorio a sus ítems. La única manera de llegar a un ítem es iniciar desde el nodo encabezado y seguir los enlaces. Como resultado, las listas enlazadas son muy lentas en la recuperación de datos. Sin embargo, para operaciones de insertar y eliminar, las listas enlazadas son extremadamente rápidas: la inserción o eliminación de un nodo involucra solo cambiar un link. Además las listas enlazadas no tienen una capacidad máxima después de la cual el contenido necesita ser reasignado. De hecho, una lista enlazada proporciona una manera alternativa para implementar las estructuras de datos de la cola y la pila. Si sus requerimientos realizan accesos frecuentes a datos pero rara vez necesita insertar o eliminar datos, un arreglo es la implementación ideal. Si en su lugar, los requerimientos llaman con frecuencia operaciones de insert y delete, entonces puede ser más recomendable utilizar una lista enlazada.
Desarrollo General de Software
89
Comprender los Algoritmos de Ordenamiento È EN RESUMEN
Los algoritmos de ordenamiento tales como Ordenamiento de burbuja y el Ordenamiento Rápido (QuickSort) ordenan ítems en una lista en un orden en particular. Comprender los algoritmos de ordenamiento pueden ayudarle a comprender, analizar y comparar distintas maneras de resolver un problema.
ER ICA
Los algoritmos de ordenamiento son algoritmos que ordenan los ítems en una lista en un cierto orden. Por ejemplo, puede utilizar un algoritmo de ordenamiento para ordenar una lista de estudiantes en orden ascendente de su apellido. En la época de los primeros procesamientos de datos, el ordenamiento era un problema muy importante. En estos días, puede encontrar capacidades de ordenamiento básicas ya integradas en librerías populares y estructuras de datos. Por ejemplo, en el .NET Framework, puede hacer uso del método Array.Sort para ordenar un arreglo. Sin embargo, aún es importante mirar el ordenamiento como una manera de comprender la resolución de un problema y análisis de algoritmos.
Ordenamiento de Burbuja
ÁM
En esta sección, le echará un vistazo a dos algoritmos de ordenamiento comunes: ordenamiento de burbuja y ordenamiento rápido.
www.pdftron.com El algoritmo de ordenamiento de burbuja utiliza una serie de operaciones de comparación e intercambio para ordenar una lista en el orden correcto.
BE
RO
El ordenamiento de burbuja funciona comparando dos elementos para verifcar si están fuera de lugar, si lo están, los intercambia. El algoritmo continúa haciendo esto hasta que la lista entera está en el orden deseado. El ordenamiento de burbuja obtiene su nombre de la manera en que funciona el algoritmo; como el algoritmo progresa, los ítems más pequeños son “burbujeados” hacia arriba.
ET
CI
Visualicemos el ordenamiento de burbuja con ayuda de un ejemplo. Digamos que desea ordenar todos los ítems en la siguiente lista en orden ascendente: (20, 30, 10, 40). Los ítems deberían ser ordenados en orden del más pequeño al más grande. El algoritmo de ordenamiento de burbuja intenta solucionar este problema en una o más pasadas, con cada pasada escaneando completamente la lista de ítems. Si el algoritmo encuentra elementos fuera de lugar, los intercambia. El algoritmo termina cuando escanea toda la lista sin intercambiar ningún elemento, si no hubo intercambios entonces ninguno de los elementos esta fuera de lugar y la lista ha sido completamente ordenada.
Tabla 3-1
Paso
Antes
Después
Comentarios
Primera pasada del ordenamiento de burbuja
1.
20, 30, 10, 40
20, 30, 10, 40
El algoritmo compara los primeros dos elementos (20 y 30),y ya que están en el orden correcto, no es necesario el intercambio.
2.
20, 30, 10, 40
20, 10, 30, 40
El algoritmo compara los siguientes dos elementos (30 y 10),y ya que están fuera de lugar, los elementos son intercambiados.
3.
20, 10, 30, 40
20, 10, 30, 40
El algoritmo compara los siguientes dos elementos (30 y 40),y ya que están en el orden correcto, no es necesario el intercambio.
90
Lección 3
Al fnal de la primera pasada, el ordenamiento de burbuja ha desempeñado un intercambio y hay una posibilidad que los ítems aún no están completamente ordenados. De manera que el ordenamiento de burbuja da otra pasada a la lista. Paso
Antes
Después
Comentarios
Primera pasada del ordenamiento de burbuja
1.
20, 10, 30, 40
10, 20, 30, 40
El algoritmo compara los primeros dos elementos (20 y 10),y como están fuera de lugar, los elementos son intercambiados.
2.
10, 20, 30, 40
10, 20, 30, 40
El algoritmo compara los siguientes dos elementos (20 y 30),y ya que están en el orden correcto, no es necesario el intercambio.
3.
10, 20, 30, 40
10, 20, 30, 40
ER ICA
Tabla 3-2
El algoritmo compara los siguientes dos elementos (30 y 40),y ya que están en el orden correcto, no es necesario el intercambio.
Al fnal de la segunda pasada, el ordenamiento de burbuja ha desempeñado un intercambio y aun no puede garantizar que la lista está completamente ordenada. De manera que el ordenamiento de burbuja da otra pasada a la lista: Paso
Antes
Después
Primera pasada del ordenamiento de burbuja
1.
10, 20, 30, 40
10, 20, 30, 40
Comentarios
El algoritmo compara los siguientes dos elementos (10 y 20),ya que están en el orden correcto, no es necesario el intercambio.
ÁM
Tabla 3-3
www.pdftron.com 3.
10, 20, 30, 40
10, 20, 30, 40
El algoritmo compara los siguientes dos elementos (20 y 30),y ya que están en el orden correcto, no es necesario el intercambio.
RO
2.
10, 20, 30, 40
10, 20, 30, 40
El algoritmo compara los siguientes dos elementos (30 y 40),y ya que están en el orden correcto, no es necesario el intercambio.
BE
Al fnal de la tercera pasada, el ordenamiento de burbuja no realizó ningún intercambio. Eso garantiza que la lista ahora esta ordenada y el algoritmo puede fnalizar. En C# este algoritmo puede ser expresado por el siguiente método:
CI
staticint[] BubbleSort(int[] numbers) {
Tome Nota
ET
Cuando se utiliza el ordenamiento de burbuja puede asegurarse que un arreglo estará ordenado en un paso menos que el número de ítems. De manera que si hay cuatro ítems, como se ilustró arriba, el arreglo será ordenado (sin importar en qué orden empieza) en tres pasadas.
bool swapped; do { swapped = false; for (int i = 0; i numbers[i + 1]) { //swap
Desarrollo General de Software
91
int temp = numbers[i + 1]; numbers[i + 1] = numbers[i]; numbers[i] = temp; swapped = true; } }
return numbers; }
Ordenamiento Rápido (QuickSort)
ER ICA
} while (swapped == true);
ÁM
El algoritmo de ordenamiento rápido utiliza las operaciones de partición y comparación para ordenar los elementos de una lista en el orden correcto. El algoritmo de ordenamiento rápido utiliza la técnica de divide y conquista para particionar continuamente una lista hasta que el tamaño del problema sea realmente pequeño y difícilmente requiera algún ordenamiento. Los siguientes pasos explican esto más a detalle:
www.pdftron.com Un lista de tamaño cero o uno siempre es ordenada por sí misma. Para una lista más grande, puede elegir algún elemento como elemento pivote. Luego particionar la lista de tal manera que todos los elementos más pequeños que o iguales al elemento pivote van a la lista izquierda y todos los elementos más grandes que el elemento pivote van a la lista derecha. Ahora la combinación de la lista izquierda, el elemento pivote y la lista derecha están ordenadas. El problema ahora se particiona en dos listas más pequeñas, la lista de la izquierda y la lista de la derecha. Ambas listas pueden ser resueltas utilizando la técnica descrita en las viñetas anteriores. Finalmente, unir todas las pequeñas listas ordenadas con el fn de crear la lista ordenada completa.
RO
• •
BE
• •
CI
•
ET
La siguiente tabla explica el algoritmo de ordenamiento rápido con un pequeño ejemplo.
Tabla 3-4
Visualizando el ordenamiento rápido
Paso
Datos a ser ordenados 50, 10, 30, 20, 40
1. 2.
Comentarios
20, 10
30
Inicia con una lista no ordenada y elige un elemento pivote, en este caso 30. 50, 40
Partición de la lista: los ítems menores al pivote van a la lista izquierda y los ítems más grandes que el pivote van a la lista derecha. Para ordenar la lista izquierda. Elija un pivote (10). Para ordenar la lista derecha, seleccione un pivote (40) para la lista derecha.
92
Lección 3
-
3.
10
20
30
-
40
50
10, 20, 30, 40, 50
4.
En la lista izquierda, 20 es mayor que 10 y 50 es más grande que 40, por lo tanto ambos van en la lista derecha. Nos quedan listas con solo un número, las cuales por definición están ordenadas. La lista unida final es la lista ordenada.
ER ICA
El defecto principal del algoritmo descrito podría parecer la memoria adicional requerida por la creación de listas más pequeñas separadas. Sin embargo, crear listas separadas no es necesario. Utilizando una técnica ligeramente modifcada, el arreglo puede ser particionado, como se muestra en el siguiente código: staticint Partition (int[] numbers, int left, int right, intpivotIndex) {
intpivotValue = numbers[pivotIndex];
// se mueve el elemento pivote al fnal
ÁM
int temp = numbers[right];
numbers[right] = numbers[pivotIndex];
www.pdftron.com numbers[pivotIndex] = temp;
// newPivot almacena el indice del primer número
RO
// mayor que el pivote intnewPivot = left;
for (int i = left; i < right; i++) {
BE
if (numbers[i] <= pivotValue) {
temp = numbers[newPivot];
numbers[newPivot] = numbers[i];
ET
CI
numbers[i] = temp; newPivot++; }
}
//mueve el elemento pivote a su posición //almacenada
temp = numbers[right];
numbers[right] = numbers[newPivot]; numbers[newPivot] = temp; returnnewPivot; }
En esta técnica, primero el elemento pivote es movido al fnal del arreglo. Luego todos
Desarrollo General de Software
93
los elementos menores que o iguales al elemento pivote son movidos al frente del arreglo. Finalmente, el elemento pivote es ubicado justo antes del elemento más grande que él, efectivamente particionando el arreglo. Este algoritmo de partición puede entonces ser utilizado por el ordenamiento rápido para particionar la lista, reducir el problema en problemas más pequeños y entonces lo resuelve recursivamente:
staticint[] QuickSort(int[] numbers, {
if (right > left) {
ER ICA
int left, int right)
intpivotIndex = left + (right - left) / 2; //particiona el vector
pivotIndex= Partition(
numbers, left, right, pivotIndex);
//ordena la partición izquierda
ÁM
QuickSort(
numbers, left, pivotIndex - 1);
www.pdftron.com // ordena la partición derecha
}
return numbers; }
Debido al enfoque de partición, el algoritmo de ordenamiento rápido, es mucho más rápido que el algoritmo de ordenamiento de burbuja.
ET
CI
BE
¿Comprende los algoritmos de ordenamiento comunes? — USD 3.3
numbers, pivotIndex + 1, right);
RO
; ¿Listo para la certificación?
QuickSort(
94
Lección 3
Resumen de matriz de habilidades En esta lección aprendió:
•
• • •
ER ICA
•
La administración del ciclo de vida de aplicación son las distintas actividades que giran alrededor de un nuevo producto de software desde su comienzo a cuando el producto de software madura y tal vez se retira. La prueba de software es el proceso de verifcar el software contra sus requerimientos. Las pruebas toman lugar después que la mayoría del trabajo de desarrollo está completado. Las estructuras de datos son técnicas de organización y almacenamiento de datos en la memoria de la computadora. Como los datos son almacenados afecta cómo son recuperados y manipulados. Comprender una estructura de datos involucra comprender no solo el patrón de almacenamiento sino también los métodos utilizados para crear, acceder y manipular la estructura de datos. Un arreglo es una colección de ítems, del mismo tipo de datos, almacenados en ubicaciones de memoria contiguas y direccionadas utilizando uno o más índices. Una cola es una colección de ítems que permite operaciones tales que el primer ítem agregado a la colección es el primero en ser removido. Una pila es una colección de ítems que permite operaciones tales que el ultimo ítem agregado a la colección es el primero en ser removido. Una lista enlazada es una colección de nodos ordenados de tal manera que cada nodo contiene un enlace al siguiente nodo en la secuencia. El algoritmo de ordenamiento de burbuja utiliza una serie de operaciones de comparación e intercambio para ordenar los elementos en una lista en el orden correcto. El algoritmo de ordenamiento rápido utiliza las operaciones de partición y comparación para ordenar los elementos de una lista en el orden correcto.
ÁM
•
• •
RO
www.pdftron.com •
BE
» Evaluación de Conocimientos
Llene los Espacios en Blanco
ET
CI
Complete los siguientes enunciados escribiendo la palabra o palabras correctas en los espacios proporcionados. 1. En la prueba de________, los testers utilizan sus conocimientos del sistema interno para probar el sistema. 2. Con cada nueva reparación, los testers de software ejecutan una serie de ______ para asegurarse que la funcionalidad que se sabía que funcionaba aun funciona. 3. El algoritmo de ordenamiento de burbuja utiliza una serie de operaciones de ______ y ______ para ordenar los elementos de una lista en el orden correcto. 4. Una ______ es una colección de ítems que permite operaciones tales que el ultimo ítem agregado a la colección es el primero en ser removido.
5. El______ es el proceso de determinar los requerimientos detallados del negocio para un nuevo sistema de software. 6. Una lista enlazada es una colección de nodos tales que cada nodo contiene un ____ al
Comprender los conceptos básicos de bases de datos
95
siguiente nodo en la secuencia. 7. La operación______agrega un ítem a la cola mientras que la operación ______remueve un ítem desde una cola. 8. El algoritmo de ordenamiento rápido utiliza las operaciones de ______ y comparación para ordenar los elementos de una lista en el orden correcto. 9. Un ______ es responsable de analizar las necesidades del negocio y convertirlas en requerimientos que pueden ser ejecutados por el equipo de desarrollo.
Elección Múltiple
ER ICA
10. Tanto la prueba Alfa y la prueba Beta son parte de las pruebas de ______de un sistema.
Encierre en un círculo la letra que corresponda a la mejor respuesta.
1. El producto que está desarrollando aún no está terminado, pero le gustaría liberar el producto a una audiencia de clientes más amplia para su retroalimentación y pruebas. ¿Bajo cuál de los siguientes niveles de pruebas caerá esta actividad? Prueba de Integración Prueba de Sistema Prueba de Aceptación Prueba de Regresión
ÁM
a. b. c. d.
www.pdftron.com RO
2. Los testers del software tienen acceso a su código fuente. Los testers necesitan escribir casos de prueba que garanticen que el método retorna valores correctos. ¿En cuál de los siguientes niveles de pruebas caerá esta actividad? Prueba de Integración Prueba de Unidad Prueba Alfa Prueba Beta
BE
a. b. c. d.
3. ¿Cuál de las siguientes estructuras de datos permite acceso directo a todos sus ítems?
ET
CI
a. b. c. d.
Arreglo Pila Cola Lista enlazada
4. ¿Cuál de las siguientes actividades en el ciclo de vida de aplicación es utilizado por un arquitecto para crear el proyecto técnico del sistema? a. b. c. d.
Análisis de requerimientos Diseño Desarrollo Mantenimiento
5. En su aplicación, usted está utilizando una estructura de datos de cola para manipular datos. Necesita encontrar cuál ítem de datos será procesado después, pero no desea realmente procesar los ítems aun. ¿Cuál de las siguientes operaciones de la cola utilizará?. a. Enqueue b. Dequeue
96
Lección 3
c. Peek d. Contains
a. b. c. d.
Cola Arreglo Lista enlazada Pila
ER ICA
6. Está desarrollando un programa que requiere que registre los llamados de método. Puede invocar solo un método a la vez. Sin embargo, un llamado de método puede a su vez invocar a otros métodos. Cuando un método termina y retorna el control al método que lo llama. ¿Cuál estructura utilizará para registrar estos llamados de método?.
7. Está desarrollando un programa que simula una cola de trabajo. A menudo los trabajos se hacen más rápidos de lo que puede procesarlos y en ese caso los trabajos esperan su turno para ser procesados. Necesita asegurarse que el trabajo que llega primero es el que se procesa primero también. ¿Cuál de las siguientes estructuras de datos es más adecuada para este requerimiento? Arreglo Cola Lista enlazada Pila
ÁM
a. b. c. d.
8. Usted escribe el siguiente código en su programa:
www.pdftron.com a. int[] numbers = {2, 3, 1, 4}; b. numbers[2] = 4;
RO
9. ¿Cuáles serán los contenidos del arreglo después de que la segunda sentencia es ejecutada?. {2, 4, 1, 4} {2, 3, 4, 4} {2, 4, 1, 2} {4, 3, 1, 4}
BE
a. b. c. d.
ET
CI
10. Está desarrollando un programa que desempeña operaciones de insertar y eliminar frecuentes en los datos. Su requerimiento también dicta una capacidad para acceder a registros previos y siguientes cuando el usuario presiona el botón de previo o siguiente. ¿Cuál de las siguientes estructuras de datos se ajustará mejor a sus requerimientos?. a. b. c. d.
Arreglo Lista enlazada circular Lista enlazada Lista doblemente enlazada
11. Está desarrollando un programa que desempeña operaciones de insertar y eliminar frecuentes en los datos. los datos necesitan ser accedidos como una pila con la funcionalidad del último que entra es el primero que sale. Su solución debe requerir tan poca memoria como sea posible. ¿Cuál de las siguientes estructuras de datos se ajustará mejor a sus requerimientos?. a. b. c. d.
Arreglo Lista enlazada circular Lista enlazada Lista doblemente enlazada
Comprender los conceptos básicos de bases de datos
97
» Evaluación de Competencia Caso 3-1: Utilizando Arreglos Está escribiendo un programa que utiliza un arreglo bidimensional. El arreglo tiene cuatro flas cinco columnas. Necesita imprimir el elemento mayor en cada fla del arreglo. ¿Cómo escribiría tal programa?.
ER ICA
Proyecto 3-2: Utilizando Colas Está escribiendo un programa que utiliza dos colas. Los datos en cada cola ya están en orden ascendente. Necesita procesar el contenido de ambas colas de tal manera en que la salida sea impresa en la pantalla ordenada. ¿Cómo escribiría tal programa?.
» Evaluación de Competencia
Proyecto 3-3: Utilizando Pilas
ÁM
Está escribiendo un programa que utiliza dos pilas. Los datos en cada pila ya están en orden descendiente. Necesita procesar el contenido de ambas pilas de tal manera que la salida sea impresa en la pantalla en orden ascendente. ¿Cómo escribiría tal programa?.
www.pdftron.com Proyecto 3-4: Utilizando Listas Enlazadas
ET
CI
BE
RO
Está escribiendo un programa que almacena la lista de nombres de productos en una lista enlazada. El usuario introducirá un nombre de producto y un programa necesita verifcar si la lista enlazada contiene el producto dado. ¿Cómo escribiría tal programa?.
Lección 3
ÁM
ER ICA
98
ET
CI
BE
RO
www.pdftron.com
Lección 4
Comprender las Aplicaciones Web Matriz de Dominio de Objetivos Descripción del Dominio de Objetivo
Comprender el Desarrollo de una Página Web
Comprender el Desarrollo de una Página Web
4.1
Comprender el Desarrollo de una Aplicación ASP.NET
Comprender el desarrollo de una aplicación Web del Microsoft ASP.NET
4.2
Comprender el IIS Web Hosting
Comprender el Web hosting
4.3
Comprender el Desarrollo de Servicios Web
Comprender los servicios Web
4.4
ÁM
Términos Clave
Número del Dominio del Objetivo
ER ICA
Habilidad Tecnológica
www.pdftron.com (IIS) • JavaScript • SOAP • Administración de estado
• Servicio Web • Lenguaje de Defnición de Servicio Web (WSDL)
BE
RO
• Hojas de estilo en cascada (CSS) • Lenguaje de Marcado de Hipertexto (HTML) • Servicios de Información de Internet
ET
CI
Como desarrollador de una gran empresa necesita desplegar aplicaciones que se puedan utilizar a través de redes como la World Wide Web. La aplicación será desplegada en un servidor Web de Windows pero sus usuarios utilizarán múltiples sistemas operativos y navegadores Web.
100
Lección 4
Comprender el Desarrollo de una Página Web È EN RESUMEN
Una página Web es un documento que es servido a través de la World Wide Web (WWW) y que se puede mostrar a través de un navegador Web. Las páginas Web se desarrollan utilizando el Lenguaje de Marcado de Hipertexto (HTML) y se almacenan en un servidor Web. Los navegadores Web descargan el HTML solicitado del servidor Web y lo interpretan en la pantalla del usuario.
• •
ER ICA
La World Wide Web (también conocida como WWW o “la Web”) es un sistema de documentos de hipertexto interconectados y otros recursos tales como imágenes y video que se pueden acceder vía internet. Tecnologías múltiples trabajan juntas para hacer posible la WWW. Discutiremos dos de estas tecnologías en esta sección: Protocolo de Transferencia de Hipertexto (HTTP) Lenguaje de Marcado de Hipertexto (HTML)
ÁM
HTTP es el protocolo de comunicación fundamental utilizado por la World Wide Web. HTTP proporciona el lenguaje común que los servidores Web y los navegadores Web utilizan con el fn de comunicarse.
HTTP utiliza el Localizador de Recurso Uniforme (URL) para identifcar únicamente y direcciona cada recurso en Internet. Una URL es esencialmente una dirección Web y se parece a esto: http://www.microsoft.com/en/us/default.aspx. Cada URL inicia con un protocolo. En este ejemplo, el protocolo es HTTP. También notará el protocolo HTTPS (HTTP Seguro) en uso para asegurar aplicaciones donde los datos necesitan ser cifrados antes de que puedan ser transmitidos a través de la red. La siguiente parte de la URL es la dirección del servidor Web: (www.microsoft.com), seguido por el localizador del recurso dentro del servidor Web (/en/us/), y fnalmente el propio recurso solicitado (default.aspx). Cada documento, imagen, video y otros recursos en la Web es identifcado por una URL.
RO
www.pdftron.com BE
Tome Nota
Cuando un navegador envía una solicitud HTTP para una página Web a un servidor Web (tanto la página y el servidor Web son identifcados por una URL), el servidor prepara una respuesta HTTP para el navegador. Esta respuesta especifca el contenido y presentación de la página Web.
El lenguaje que el servidor Web y el navegador Web utilizan para describir una página Web es el Lenguaje de Marcado de Hipertexto (HTML). HTML es un lenguaje basado en texto que utiliza varias etiquetas de marcado describiendo como el contenido es desplegado. HTML permite que imágenes, videos y otros objetos sean referenciados en un archivo para crear páginas Web multimedia. HTML puede incrustar scripts tales como JavaScript que afecta el comportamiento de las páginas Web. HTML también puede ser utilizado para incluir hojas de estilo en cascada (CSS) para defnir el formato y presentación del contenido de una página. El navegador Web lee el código HTML e interpreta los resultados en la pantalla.
ET
CI
Los términos “Internet” y “la Web” son comúnmente utilizados de forma indistinta pero son en realidad diferentes y no deben confundirse entre sí. El Internet es un sistema de comunicaciones de datos global que proporciona conectividad entre computadoras. En contraste, la Web es uno de los servicios disponibles en Internet que nos permite acceder a recursos hiper vinculados.
Una página Web puede contener hipervínculos a otros recursos tales como imágenes y videos. Cada uno de estos recursos es identifcado por su propia URL. Con el fn de interpretar completamente una página, el navegador hará solicitudes HTTP adicionales para obtener esos recursos y desplegarlos como parte de la página Web. En las siguientes secciones, aprenderá más acerca de varios componentes que conforman una página Web tales como HTML, CSS y JavaScript.
Comprender las Aplicaciones Web
101
Comprender HTML El Lenguaje de Marcado de Hipertexto (HTML) es el lenguaje utilizado por los servidores y navegadores Web para describir una página Web.
HTML está basado en texto. HTML utiliza etiquetas para incrustar imágenes, audio, video y otros muchos tipos de multimedia y contenido interactivo en la página.
ER ICA
Tome Nota
El propósito de HTML es proporcionar un lenguaje estándar para describir páginas Web de forma que diferentes navegadores Web pueden comprenderlo y desplegar las páginas Web. HTML es un lenguaje basado en texto, lo cual signifca que puede escribir y editar paginas HTML utilizando cualquier editor de texto. Cuando HTML es enviado al navegador Web, la mayoría de los navegadores le permiten visualizar el código fuente HTML de la página. HTML consiste de un conjunto de etiquetas (también llamadas elementos HTML) que defnen la estructura y contenido de una página. Por ejemplo, la etiqueta especifca el inicio del documento HTML. Las etiquetas HTML siempre son rodeadas por paréntesis angulares. Las etiquetas HTML siempre se utilizan en pares. Cada inicio de etiqueta tiene una etiqueta par al fnal. Las etiquetas fnales tienen un slash que indica que es una etiqueta de fnal. Por ejemplo, la etiqueta de fnal para es .
ÁM
Una página HTML consta de dos partes: un encabezado y un cuerpo. El encabezado es encerrado dentro de las etiquetas yy es utilizado para proporcionar un título al documento y vínculos a ítems externos que pueden ser utilizados en la página, tales como archivos CSS y archivos de JavaScript. El cuerpo es encerrado dentro de las etiquetas y y es utilizado para proporcionar la estructura complete y contenido de la página que será desplegada dentro del navegador Web.
www.pdftron.com
“http://upload.wikimedia.org/wikipedia/commons/b/bc/Mimas_ Cassini.jpg”/>
BE
Note que el documento HTML no contiene la imagen en sí. La etiqueta img específica la URL de la imagen, la cual el navegador descarga separadamente y la interpreta como parte de la página.
Este es un ejemplo de una etiqueta que despliega una imagen:
RO
Tome Nota
CI
La etiqueta
especifca atributos adicionales. Por ejemplo, el atributo src especifca la ubicación del archivo de imagen, y los atributos height y width especifcan qué dimensiones utilizar cuando se interpreta la imagen en el navegador. Este es otro ejemplo de una etiqueta HTML:
ET
Tome Nota Esta lección no cubre todos los elementos HTML. Para aprender más sobre elementos HTML, busque “Elementos HTML” en el MSDN.
Saturn’s moon
Aquí, es la etiqueta de anclaje, la cual es utilizada para crear hipervínculos en la página Web. El atributo href especifca la URL objetivo y el texto dentro de los paréntesis angulares es el que es mostrado como un enlace. Tome los pasos en el siguiente ejercicio para crear un documento HTML.
102
Lección 4
Æ Trabajar con HTML PREPÁRESE. Para crear un documento HTML, haga lo siguiente: 1. Abra el Visual Studio. Crear un Nuevo proyecto basado en la plantilla de aplicación web vacía de ASP.NET. Nombre al proyecto TrabajandoConHTML y nombre la solución Leccion04. 2. Seleccione Proyecto, Agregar Nuevo Ítem, y seleccione la platilla de Pagina HTML. Nombre el archivo default.htm. 3. Remplace el código por defecto en el archivo HTML con el siguiente código:
ER ICA
Saturn’s Moon Mimas Cassini
La etiqueta img es utilizada para mostrar la imagen de
ÁM
Saturn’s moon:
www.pdftron.com
height=”400px” width=”400px”
alt=”Mimas Cassini”
src=”http://goo.gl/3BeK”/>
RO
Figura 4-1
BE
4. Seleccione Depurar y después Inicie la Depuración (o presione F5). La páginadefault.htm se abrirá en un navegador Web. Note que la salida se parece a la figura 4-1, donde puede ver las etiquetas
yen acción.
ET
CI
Una página HTML simple con una imagen y un hipervínculo.
Comprender las Aplicaciones Web
103
Comprender las Hojas de Estilo en Cascada Las hojas de estilo en cascada (CSS) le permiten almacenar el estilo e información separada del código HTML. Esta separación hace más fácil el actualizar la apariencia de su sitio Web. Visual Studio incluye herramientas para construir y pre visualizar sus hojas de estilo.
Cuando se utiliza efectivamente, CSS es una gran herramienta para incrementar la consistencia del ancho del sitio y la posibilidad de mantenimiento.
CSS le permite separar la presentación de una página Web de su contenido. Esta separación le permite cambiar uno sin afectar a otro. Mezclar el contenido y el estilo juntos reduce la posibilidad de mantenimiento de un sitio Web. Por ejemplo, digamos que quiere cambiar el color y fuente de todos los encabezados de H1 en su sitio Web. Un enfoque podría ser abrir un editor HTML y modifcar cada archivo en el sitio Web que utiliza la etiqueta H1. Esto podría ser una solución aceptable si el sitio Web tiene solo una o dos páginas, pero ¿y si el sitio web tiene un gran número de páginas, digamos 50 o 100? Imagine cambiar manualmente cada página. Si tal cambio es solicitado muy a menudo, el proceso de desarrollo Web será muy tedioso y propenso a errores (¿Cómo garantiza que no omitió ninguna etiqueta?).
ÁM
Tome Nota
ER ICA
CSS es un lenguaje que describe toda la información acerca de mostrar una página Web. Cuando se interpreta páginas Web en un navegador, HTML especifca lo que será mostrado. Por ejemplo, HTML puede especifcar que su documento tiene un encabezado H1 con un texto dado, mientras CSS puede especifcar la fuente y el color que serán aplicados al encabezado H1.
www.pdftron.com RO
Afortunadamente, con CSS puede poner toda la información de estilo en un archivo separado y conectar todas las páginas Web en un sitio Web con el archivo CSS. Una vez que está confgurado, para modifcar cualquier estilo (tal como el color y fuente de los encabezados H1), simplemente cambia el estilo en el archivo CSS, un simple cambio afectará todas las páginas en el sitio Web.
Diseño de Hojas de Estilo en Cascada
BE
El lenguaje CSS está basado en texto y es fácil de leer y entender. A continuación se muestra un ejemplo de una página HTML que defne estilo CSS:
ET
CI
Comprendiendo CSS
ÁM
}
www.pdftron.com
RO
Sample body text
Sample DIV text
BE
Sample DIV text with block class
ET
CI
Sample SPAN text with block class
Las defniciones CSS deben estar dentro del elemento
ET
CI
Texto de Ejemplo