Clase poo

¿Que puede contener una clase?.

Una clase puede contener en su declaración los siguientes elementos (que podremos ver en el curso de C#):

  • Constructores
  • Destructores
  • Constantes
  • Atributos o campos (fields) que es como los llama la MSDN
  • Métodos
  • Propiedades
  • Indexers
  • Operadores
  • Eventos
  • Delegates
  • Otras clases, structs e interfaces dentro de esta clase (anidados)

Las clases tiene algunos de estos elementos de forma básica, es decir, que son inherentes a u las clases.

Constructores
Se puede evitar que un usuario inicialice una clase con unos parámetros concretos declarando un constructor privado (con esos parámetros).

Si un constructor tiene uno o más constructores privados y no tiene constructores públicos, otras clases (excepto clases anidadas) no podrán crear instancias de esa clase.

Ejemplo:

 

class Circle
{
  private float radius;
  private float x;
  private float y;

  public Circle() { }

  public Circle(float r, float x, float y)
  {
  this.radius = r;
  this.x = x;
  this.y = y;
  }
};

En este ejemplo opdemos ver una clase que tiene 3 atributos y 2 constructores. Uno de ellos no hace nada, y el otro toma 3 parámetros de entrada y hace operaciones con ellos. En este caso los asigna a los atributos.

Programación orientada a objetos - clase I

¿Que es una clase?. Una clase es una construcción usada como plano o patrón para crear los objetos de esa clase. Este plano describe el estado y comportamiento que comparten los objetos de esa clase. Un objeto es contenedor con el que podremos utilizar las propiedades y los métodos públicos de una clase y se pueden crear(instanciar) tantos objetos como necesitemos y todos tendrán los mismos métodos y propiedades.

Una clase puede tener propiedades (atributos) y métodos(funciones) que hacen interactuar a la clase consigo misma o con el mundo exterior

La clase es la base de la Programación Orientada a Objetos, por loque conviene entenderlo bien. Vamos a ver un ejemplo:

Tenemos una clase llamada Coche que representa coches en nuestro programa y tiene, por ejemplo, los atributos color y posición, y un método mover() que haría que que el coche se moviera, (por ejemplo si nuestro programa fuera un videojuego).
La sintaxis de la definición de clases es bastante parecida en todos los lenguajes, así que vamos a ver como se hace en C#.

[private/protected/public/internal] class NameOfClass [: BaseClass] [, Interface1, Interface2…]
{
  // Attributes, Properties, Methods,…
}

Las clases en C# pueden tener una única clase base, pero pueden implementar tantos interfaces como quieran esto es Herencia que es una característica de la POO que veremos más tarde.

Microsoft recomienta que los nombres de las clases empiecen con mayúscula, pero esto es opcional, aunque mucha gente lo usa así en el mundo laboral.

Poo introduccion a la programacion orientada a objetos
En la programación funcional la compartición de datos se implementa normalmente usando funciones y estructuras de datos globales. Esto significa que cualquiera puede acceder a esos datos, independientemente de si debería poder o no. Quizás en la programación unipersonal, esto no sea ningún problema pero cuando se programa en grupo puede suponer grandes quebraderos de cabeza.
Por ejemplo, si estamos haciendo un programa sobre una moto y se exponen los datos de la moto, las funciones que manejan las luces tendrían  acceso a las ruedas (que puede ser razonable), pero las ruedas también tendrán acceso (y podrán modificar) a los datos de las luces (que ya no tiene tanto sentido)
Esto acarrea un incremento en la complejidad del manejo y actualización del programa conforme va creciendo. La complejidad en programación conlleva más errores (bugs) y más difíciles de encontrar. Así aumenta el coste y el mantenimiento. Tampoco es sencillo reutilizar código y esto es algo fundamental en la programación.

El paradigma de Programación Orientada a Objetos (POO) intenta solucionar estos problemas usando un punto de vista que es bastante ‘natural’ algo similar a como normalmente pensamos de las cosas como vemos en el siguiente capítulo.
Logotipo de funciones y métodos en csharp

Definición y Uso:

Una función es un bloque de código que realiza x operaciones y puede devolver o no algún valor.
La principal usabilidad de las funciones y los métodos es aclarar y resusar la programación. Si tuviéramos todo el código de una apicación del tirón sería muy difcícil de leer y de mantener.
Por ejemplo si tenemos un programa en el que hacemos una operación de sumar dos números y luego mostrárla por pantalla, podríamos hacer una función a la que le diéramos los 2 números y ya nos hiciera ella el resto.

La diferencia entre un método y una función es simplemente que los métodos están dentro de las clases, es decir, a las funciones dentro de las clases les llamamos métodos.

Ya que C# sólo admite funciones dentro de clases, todo lo que nos encontramos son métodos.

Declaración:

Sintaxis:

[private/protected/public/internal] [virtual/override/new] [static]
returnType NameOfFunction(
  [ref/out] typeParam1 nameParam1,
  …
  [ref/out] typeParamN nameParamN)
{
  // Code
}

Se puede especificar la visibilidad del método (privada/protegida/pública), si no se especifica, los métodos son privados.

Si el keyword static se declara quiere decir que es un método estático. Estos métodos pueden llamarse sin necesidad de tener un objeto de la clase a la que pertencen, aunque no podrán acceder tampoco a los miembros no estáticos de la clase (sean métodos, atributos, propiedades, etc)
También se puede especificar si un método es virtual, sobrecargado o se debe ignorar la virtualidad.

En C# hay que especificar un valor de retorno, aunque si el método no devuelve nada se especifica con el valor void. Si el valor especificado es distinto de void es obligatorio devolver algo en la función (usando return).

Hay que especificar un nombre para los métodos, normalmente es una buena idea que el nombre sea explicatorio de lo que hace la función. También se recomienda escribir un comentario sobre el método explicando su funcionamiento.

Se pueden incluir tantos parámeteros como se quiera (e incluso no poner parámetro). Todos los parámetros especifican primero el tipo y luego el nombre que tienen dentro de la función.

Se puede especificar algunos atributos a los parámetros que se pasan. Vamos a ver 2 posibles valores para estos atributos:
ref: es usado para pasar un parámetro por referencia. Para los tipos por referencia esto significa que se pueden asignar objetos a las variables pasadas. Para los tipos por valor, lo que significa es que pueden ser modificados dentro de la función.
out: es como ref (pasa el valor por referencia) pero además fuerza al método a inicializar el valor antes del final de la función (para cualquier posible punto de retorno).

Como llamar a una función / método en C#:

Sintaxis:

Si el método pertenece a la misma clase:
[val = ]MyFunc([ref/out] param1, [ref/out] param2,…);
Si pertence a otra clase:
[val = ]myObj.MyFunc([ref/out] param1,…);
Si es un método estático (de otra clase):
[val = ]MyClass.MyFunc([ref/out] param1,…);
Si el valor de retorno es void o no es necesario guardarlo, se puede ahorrar esa primera parte. Si la función toma parámetros ref/out éstos deben indicarse también en la llamada a la función.

Ejemplos:

Declaración:

//Funcion que devuelve la suma de los parámetros que le pasamos
public int suma (int operando1, int operando2)
{
    int resultado = operando1 + operando2;
    return resultado;
}

Utilización:

//Mostramos por pantalla el resultado de la suma de dos números
Console.WriteLine("El resultado de la suma es: " + suma(2,4).ToString());
//Esto tendría como resultado en la consola
//El resultado de la suma es: 6

 

C-sharp, logo, logotipo bucles en c# while, for, foreach

Los bucles permiten ejecutar un bloque de código varias veces seguidas. Se utilizan para muchas cosas como por ejemplo recorrer arrays y listas de elementos.

Vamos a ver 3, que son los más utilizados y con estos 3 bucles podremos hacer casi todo lo que queramos con relación a los bucles.

  • While, el más generico y siempre una buena opción.
  • For, muy útil cuando sabes exactamente cuántas veces quieres iterar un bucle.
  • Foreach, muy útil para iterar sobre estructuras de datos, aunque presenta ciertas restricciones.
- Un bucle while ejecutará un trozo de código mientras una condición sea true. La condición es comprobada antes de ejecutar el código.
Hay otro tipo de bucle while que comprueba la condición después de ejecutar el código: do/while.
Los bucles while son los más simples y fáciles de entender, pero además, también son los más versátiles.

Cualquier otro tipo de bucle puede ser reescrito como un bucle while.

Sintaxis:
while (condition)
{
// code
}

Ejemplo:

int numero = 0;
while (numero != 7) //mientras la variable numero sea distinta de 7 hara lo que hay entre paréntesis
{
numero++; //sumamos uno a la variable
}
El bucle For es como el bucle while pero teniendo una inicialización y una modificación de la condición formando parte de la sintanxis
Es particularmente útil cuando sabes cuántas veces quieres ejecutar un bloque de código
Y esto es algo muy habitual, especialmente trabajando con datos.

Las variables declaradas en la inicialización tienen como scope el código dentro del bucle y la condición y modificación, no pueden ser accedidas fuera del bucle.

Sintaxis:
for (initialization; condition; modification)
{
// code
}

Ejemplo:

for(int i=0; i<10; ++i)
El bucle foreach sólo se puede usar con colecciones de objetos.
Itera sobre todos los objetos en orden, desde el elemento 0 al último.
Se pueden definir clases que se pueden iterar con el bucle foreach implementando el interfaz IEnumerable.
No se puede cambiar el tamaño de una colección desde dentro del bucle foreach.
No se puede usar foreach para inicializar o modificar el valor de los objetos en la colección.

Usar foreach puede ayudar al compilador a optimizar e incluso a generar código multithread.

Sintaxis:
foreach (Type nameOfObj in arrayToIterate)
{
// code where we can use nameOfObj
}

Ejemplo:

// Declaro el array de 10 elementos de tipo int y le doy los valores de 1 a 10
int[] myArray = new int[10] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
foreach (int number in myArray)
{  //por cada numero en el array escribo el valor
Console.WriteLine(“myArray has {0} inside”, number);
}

Si en cualquier punto dentro de un bucle se ejecuta un return, se sale de la función.
Hay 2 keywords que se pueden usar dentro de los bucles para modificar su comportamiento por defecto: continue y break.
Continue moverá el puntero de ejecución a la condición del bucle y continuará con la siguiente iteración (si la condición no se cumple), saltándose el resto de código que quede dentro del bucle a ejecutar en esa iteración.
Break saldrá del bucle independientemente de la condición, colocándose en la primera instrucción justo después del bucle

Logotipo - Logo c-sharp c# estructuras de control

Las estructuras de control en c-sharp es la forma de hacer elecciones entre unas porciones de código u otras. Las 2 más utilizadas son if y switch.

La estructura de control IF permite ejecutar una porción de código sólo si la expresión entre paréntesis () es verdadera. Luego se puede incluir la cláusula else para ejecutar código en caso de que la expresión sea falsa.

int suma = 2 + 2;
if (suma == 4)
{
   Console.WriteLine("La suma es cuatro");
}
else
{
   Console.WriteLine("La suma es distinta de cuatro");
}

Se pueden anidar varios IF para formar una estrucutra con más opciones.

int suma = 2 + 2;
if (suma == 4)
{
   Console.WriteLine("La suma es cuatro");
}else if(suma == 5)
{
   Console.WriteLine("La suma es cinco");
}else
{
   Console.WriteLine("La suma es distina de cuatro y cinco");
}

Para el ejemplo anterior hay otra opción más económica que es la estructura switch, aunque ésta sólo compara cadenas de texto.

string miCadena = "HolaMundo";
swtich (variable to evaluate):
{
case "HolaMundo":
   Console.WriteLine("Ha entrado en este caso");
   break;
case "NoEntro":
   Console.WriteLine("Ha entrado en este otro caso");
   break;
default:
   Console.WriteLine("Entraría aquí si no coincide en ningún caso anterior");
   break;
}
Arrays en c-sharp c#
Los arrays se usan para guardar colecciones de un número determinado de objetos del mismo tipo.
Para colecciones de objetos con tamaño variable se pueden utilizar otras clases como List<>, definida en System.Collections.Generic.
Los arrays se pueden definir de varias manera como vemos en estos ejemplos:
Type[] nombreArray = new Type[numeroElementos];

int[] arrayDeEnteros = new int[10]; 

string[] listaDeFrases = new string[20];
Se pueden definir los miembros de un array en su declaración usando {}:
Type[] nameOfArray = new Type[numElems] { elem1,… }

int[] myArray = new int[5] { 1, 2, 3, 4, 5 };
Para acceder a los miembros de un array se usa el operador []
Se empieza a indexar por el cero.
float[] myArray = new float[4] { 4.0f, 3.0f, 2.0f, 1.0f };

Console.WriteLine(“Mi tercer elemento es: {0}”, myArray[2]); //resultado-> Mi tercer elemento es: 2.0

myArray[1] = 0.0f;  //resultado-> { 4.0f, 0.0f, 2.0f, 1.0f }
Se pueden definir arrays multidimensionales:
int[,] my2DArray = new int[2,3] { {1, 2, 3}, {3, 2, 1} };

float[,,] my3DArray = new float[3, 3, 3];

int a = my2DArray[0,2];   // a == 3

También se pueden definir arrays de arrays aunque no tengan todos el mismo tamaño:

int[][] arrayOfArrays = new int[2][] { new int[3] {1, 2, 3}, new int[4] {4, 3, 2, 1} };

int a = arrayOfArrays[1][3];  // a == 1

Al igual que en los Strings los arrays tienen un monton de funciones. Algunas de estas son las más usadas:

La propiedad Length devuelve el tamaño del array

int[] myArray = new int[100];
int arraySize = myArray.Length; // arraySize == 100

Los arrays son tipos por referencia. Si quieres copiar un array entero (con sus valores) se pueden usar las funciones CopyTo() o Copy():

int[] array1 = new int[4] { 1, 2, 3, 4 };
int[] array2 = new int[4];
Array.Copy(array1, array2, array1.Length);

Logotipo de C# strings

Sin duda uno de los principales tipos de datos es el tipo de dato String (“cadena de texto”). Por ello C# tiene implementadas un montón de funciones que nos harán la vida mucho más fácil al manejar este tipo de datos.

Vamos a ver algunas de las más “usadas”.
ToLower() y ToUpper(), convierten una string a minúsculas/mayúsculas:

string s = “My String”
s = s.ToUpper();  // s == “MY STRING”
s = s.ToLower();  // s == “my string”

Hay una propiedad Length que devuelve el tamaño de una string:

int numLetters = myString.Length;

Format() se usa para generar una string usando parámetros (al estilo de Write()/WriteLine()):

string s = string.Format(“My number is {0}”, 69);

StartsWith(), EndsWith() se usa para determinar si una string comienza o termina con un determinado texto:

string s = “This is my string”;
bool b = s.StartsWith(“This is”);  // b == true

IndexOf() devuelve el índice del primer carácter de la primera aparición de un texto:

string s = “This is my string”;
int index = s.IndexOf(“is”);  // index == 5

LastIndexOf() devuelve el índice de la última ocurrencia de un texto o carácter.

string s = “This is a string”;
int index = s.LastIndexOf(‘i’);	// index == 13

Replace() permite reemplazar las ocurrencias de un texto por otro

string s = “The teacher is good”;
s = s.Replace(“good”, “crap”);

Casi cualquier objeto en C# puede ser transformado en una string usando la función ToString()

string s1 = myFloat.ToString();
string s2 = myBool.ToString();

Se puede acceder a los caracteres de una string directamente usando el operador [].

string s = “My string”;
char c1 = s[4];  // c1 == ‘s’

Clase items del video juego en xna serpiente

La clase Items es muy sencilla. La idea de esta clase es sacar lo que se va a comer la serpiente en un punto aleatorio de la pantalla.Para hacerlo un poco más estético he incluido unos cuantos dibujos de frutas al directorio Content, en el que he creado una carpeta que se llama Models.

El constructor de la clase es la parte más importante, puesto que cada vez que instanciemos un objeto de tipo Item en la clase principal del juego, tendrá que salir una nueva fruta en una parte aleatoria de la pantalla para ello he hecho lo siguiente:

Pongo las variables estáticas de la clase que me indicarán cuál es el tamaño de la pantalla.

//inicialize the variables with screen size
Game1.windowHeight = Game1.graphics.PreferredBackBufferHeight;
Game1.windowWidth = Game1.graphics.PreferredBackBufferWidth;

Cargo la lista de texturas con los modelos que tenemos en la carpeta Models del Content de nuestro juego.

//Inicialize Items list with content.
_fruitList.Add(game.Content.Load("Models\\Apple"));
_fruitList.Add(game.Content.Load("Models\\Banana"));
_fruitList.Add(game.Content.Load("Models\\Cherry"));
_fruitList.Add(game.Content.Load("Models\\Orange"));
_fruitList.Add(game.Content.Load("Models\\Pear"));
_fruitList.Add(game.Content.Load("Models\\Strawberry"));

Ahora llamo a la función que hubicará, la fruta, en un posición de la pantalla aleatoria. Dentro de esta función llamo a otra de la serpiente para saber si la posición elegida por la fruta no está ocupada por la serpiente.

//Inicialize itemPosition
this.mtInicializeRandomPosition();

Ahora el item seleccionado al azar (para que vayan rotando) de la lista de modelos

//Select a random item from fruiList
Random rnd = new Random();
_fruitSelectedItem = _fruitList[rnd.Next(0,_fruitList.Count)];

Con esto ya tengo un item cargado en una posición aleatoria y buena de la pantalla. Ya estaría listo para ser dibujado, cosa que hará el bucle principal con la función Draw().

Comparaciones en C#

Las comparaciones en C-Sharp, son muy útilies para las estructuras de control, como veremos más adelante.

Vamos a aprender a comparar tipos de número, cadenas y booleanos.

Las expresiones de comparación siempre devuelven un boolean
Booleans y números sólo comparten == (es igual que)  and != (no es igual que).
bool b = (1 == 5); //el resultado sería falso puesto que 1 es distinto que 5

bool c = (1 != 4); //el resultado sería verdadero puesto que 1 es distino que 4

Hay más operadores de comparación para números:

> y >= la parte de la izq más grande y más grande o igual que la parte de la dch
< y <= la parte de la izq más pequeño y más pequeño o igual que la parte de la dch

El operador de negación se usa con los booleans: !, y nos indica el contrario.

a = !b;  // si b fuera verdadero, a sería falso
a = !(1 == c);  // a = (1 != c);

En las cadenas también se puede usar los operadores == y != que funcionan como se podría esperar (igualdad y desigualdad). Esto son ‘case sensitive’ es decir discrimina entre mayúsculas y minúsculas:

"hola" == "Hola"; //el resultado sería false

"Hola" == "Hola"; //el resultado sería true

"hola" != "Hola"; //el resultado sería true

C# proporicona un montón de funciones para comparar strings:
Compare() tiene un montón de variantes pero una de las que más se usa es la función Compare (string, string, bool). El último valor que le pasamos a la función es si queremos que ignore las mayúsculas y las minúsculas.

string s1 = “My String”;
string s2 = “my string”;

//haciendo la comparación con operador
bool b1 = (s1 == s2);  // b1 sería false
//haciendo la comparación con función
//le pasamos a la función la cadena1, la cadena2 y le decimos que ingore las mayusculas y minusculas
bool b2 = string.Compare(s1, s2, true);  // b2 sería true