Métodos
Los métodos son bloques de código manejan los datos de la clase. Cómo se define
un método en C#:
acceso tipo NombreMetodo(TipoArg1 argumento1, TipoArg2 argumento2 ...)
{
// Aquí se codifica lo que tiene que hacer el
método
}
acceso es el modificador de acceso del método, que puede ser private,
protected, internal o public (como las variables). Posteriormente el tipo de
retorno, es decir, el tipo de dato que devolverá el método (que puede ser
cualquier tipo). Luego el nombre del método (sin espacios en blanco). Después,
entre paréntesis y separados unos de otros por comas, la lista de argumentos
que aceptará el método: cada uno de ellos se especificará poniendo primero el
tipo y después el nombre del mismo. Por fin, la llave de apertura de bloque
seguida del código del método y, para terminarlo, la llave de cierre del bloque.
Un método es como un procedimiento o una función. Necesitamos pasar datos a
los métodos. Estos datos se llaman argumentos. Vamos a verlo:
public bool MiMetodo(byte argumento)
{
}
Los métodos también pueden devolver un valor de cualquier tipo después de
su ejecución si fuera necesario. En caso de que no devuelva nada hay que
declararlo como void.
Ejemplo. Escribir una clase que maneja gastos e ingresos:
class Cuentas
{
protected
double saldo=0;
public
double Saldo
{
get
{
return this.saldo;
}
}
public bool NuevoGasto(double cantidad)
{
if (cantidad<=0) return false;
this.saldo -= cantidad;
return true;
}
public bool NuevoIngreso(double cantidad)
{
if (cantidad <=0) return false;
this.saldo += cantidad;
return true;
}
}
Esta clase contiene una variable protected (es decir, que es visible dentro
de la clase y dentro de clases derivadas, pero no desde el cliente), una
propiedad y dos métodos. Los métodos NuevoIngreso y NuevoGasto se ocupan de
modificar el valor de la variable saldo según cuánto se ingrese o se gaste. Si
la cantidad que se pretende ingresar es menor o igual que cero, el método no
modificará el valor de la variable saldo y devolverá false.
Sobrecarga de métodos
La sobrecarga de métodos consiste en poner varios métodos con el mismo
nombre en la misma clase, pero siempre con una lista de argumentos distinta. No puede haber dos métodos que se llamen igual
con la misma lista de argumentos.
Ejemplo:
public
bool NuevoIngreso(single cantidad)
{...}
public int NuevoIngreso(double cantidad, double argumento2)
{...}
public
int NuevoIngreso(single cantidad, double argumento2)
{...}
Lo que diferencia las listas de argumentos de las
diferentes sobrecargas no es el nombre de las variables, sino el tipo de cada
una de ellas. Por ejemplo, la siguiente sobrecarga tampoco sería válida:
public bool NuevoIngreso(single num)
{...}
A pesar de que el argumento tiene un nombre distinto (num en lugar de
cantidad), es del mismo tipo que el del método del ejemplo, por lo que el
compilador tampoco sabría cuál de las dos sobrecargas ejecutar.
¿Qué sobrecarga ejecutará si se efectúa la siguiente llamada?
MisCuentas.NuevoIngreso(200.53);
El número 200.53 puede ser double, o single. Para números decimales, el
compilador ejecutará la sobrecarga con el argumento de tipo double. En el caso
de números enteros, el compilador ejecutará la sobrecarga cuyo argumento mejor
se adapte con el menor consumo de recursos (int, uint, long y unlong, por este
orden). Si deseamos que, se ejecute la sobrecarga con el argumento de tipo
single, tendríamos que añadir un sufijo al número para indicarle al compilador
cuál es el tipo de dato que debe aplicar para el argumento:
MisCuentas.NuevoIngreso(200.53F);
Los sufijos para literales de los distintos tipos de datos numéricos son
los siguientes:
L (mayúscula o minúscula): long ó ulong,
por este orden;
U (mayúscula o minúscula): int ó uint, por
este orden;
UL ó LU (independientemente de que esté en
mayúsuculas o minúsculas): ulong;
F (mayúscula o minúscula): single;
D (mayúscula o minúscula): double;
M (mayúscula o minúscula): decimal;
Argumentos pasados por valor y por referencia
Puede que necesitemos que los métodos NuevoIngreso y NuevoGasto devuelvan
el saldo nuevo, además de true o false. ¿Es posible hacerlo?: no se puede, ya
que un método no puede retornar más de un valor. Sin embargo, sí es posible
hacer que un método devuelva datos en uno o varios de sus argumentos. Pasando
esos argumentos por referencia. Me explicaré mejor: un método puede aceptar
argumentos de dos formas distintas (en C# son tres, aunque dos de ellas tienen
mucho que ver): argumentos pasados por valor y argumentos pasados por
referencia.
Cuando un método recibe un argumento por valor, se crea una copia local de
la variable que se ha pasado en una nueva dirección de memoria. Así, si el
método modifica ese valor, la modificación se hace en la nueva dirección de
memoria, quedando la variable original sin cambio alguno. Por ejemplo, si escribimos
el método NuevoIngreso de este modo:
public bool NuevoIngreso(double cantidad)
{
if (cantidad <=0)
return
false;
this.saldo += cantidad;
cantidad=this.saldo;
return
true;
}
Si el saldo era 100, y se efectúa la siguiente llamada.
double dinero=365.88;
MisCuentas.NuevoIngreso(dinero);
Console.Write(dinero);
La salida sería 365.88,
es decir, la variable dinero no ha sido modificada, ya que se ha pasado al
método por valor (en C#, si no se
indica otra cosa, los argumentos de los métodos se pasan por valor).
Sin embargo, si escribimos el método del siguiente modo para que reciba los
valores por referencia:
public bool NuevoIngreso(ref double cantidad)
{
if (cantidad <=0)
return
false;
this.saldo += cantidad;
cantidad=this.saldo;
return true;
}
Y se modifica también el código:
double dinero=365.88;
MisCuentas.NuevoIngreso(ref dinero);
Console.Write(dinero);
La salida en la consola sería 465.88
pues ahora, la variable cantidad apunta a la misma zona de memoria a la que
apunta la variable dinero. Por este motivo, cualquier modificación que se haga
sobre la variable cantidad afectará también a la variable dinero, ya que dichas
modificaciones se harán en la zona de memoria reservada para ambas.
Las variables que se pasen a un método por referencia deben de inicializarse
previamente, pues el programa no se
habría compilado, si no se hubiera inicializado antes la variable dinero. Para pasar
por referencia argumentos con un valor
inicial que no nos interesa, es posible utilizar out en lugar de ref. Por
ejemplo, imagina que queremos devolver en otro argumento el valor del saldo
redondeado. Habría que hacerlo así:
public bool NuevoIngreso(ref double cantidad, out int redondeado)
{
redondeado=(int) Math.Round(this.saldo);
if (cantidad <=0)
return
false;
this.saldo += cantidad;
cantidad=this.saldo;
redondeado=(int) Math.Round(this.saldo);
return
true;
}
Y modificar el código que hacía la llamada:
double dinero=365.88;
int redoneo;
MisCuentas.NuevoIngreso(ref dinero, out redondeo);
Console.Write(redondeo);
Ahora la salida en la consola sería 367. Es necesario fíjarse que la variable redondeo no ha sido
inicializada antes de efectuar la llamada al método (no ha recibido ningún
valor). Por otra parte, este argumento debe recibir algún valor antes de salir
del método, por lo que se asigna antes del if y luego se asigna otra vez
después de hacer el ingreso. Sin embargo, la variable dinero sí ha sido
inicializada antes de invocar el método, puesto que el método necesitaba saber
cuánto había que ingresar, pero no necesita saber nada del valor redondeado,
pues este se calculará a partir del saldo.
Métodos static
Los métodos static, son aquellos que se pueden ejecutar sin necesidad de
instanciar la clase donde está escrito. Pues un método estático existe en una
clase como un todo, más que en una instancia específica de la clase. El
hecho de que el método Main tenga que ser static no es un capricho, ya que, de
lo contrario, el CLR no sería capaz de encontrarlo pues antes de que se ejecute
la aplicación, lógicamente, no puede haber instancias de ninguna de las clases
que la componen.
Estos métodos suelen usarse para hacer una serie de operaciones globales
que tienen más que ver con la clase como tal, que con una instancia específica
de la misma: por ejemplo, si tenemos una clase Moto y queremos listar todas las
marcas de motos que hay en el mercado, lo más propio es un método static. Pues
no es necesario instanciar un objeto de esa clase, si solamente queremos ver
las marcas disponibles.
Otro ejemplo:
class LimiteTarjeta
{
public static ushort Limite()
{
return 300;
}
// Aquí irían más
miembros de la clase
}
class LimiteTarjetaApp
{
static void Main()
{
Console.WriteLine("El
límite de la tarjeta es: {0}",
LimiteTarjeta.Limite());
string a=Console.ReadLine();
}
}
Para hacer que un método sea static hay que poner esta palabra después del
modificador de acceso (si lo hay) y antes del tipo de retorno del método. Este
método devolvería el límite que tienen todas las tarjetas para extraer dinero
en un sólo día. No se ha instanciado ningún objeto de la clase LimiteTarjeta,
sino que se ha puesto directamente el nombre de la clase.
No hay comentarios:
Publicar un comentario