1. Creación de un objeto
Por fin llegamos a la creación de objetos. Ya te has topado con esto antes, solo que ahora vamos a ver el tema con más detalle. En realidad, crear objetos es súper fácil.
Para crear un objeto, tienes que usar el operador new. Normalmente creas una nueva instancia (objeto) de una clase y la guardas en una variable del mismo tipo.
Clase nombre = new Clase(parámetros);
Donde Clase es el tipo del objeto, nombre es el nombre de la variable (normalmente en minúscula, por ejemplo cat), y a la derecha del = — la creación de un nuevo objeto de esa clase.
Ejemplos:
| Código | Nota |
|---|---|
|
Creación de un objeto de tipo object |
|
Creación de un objeto de tipo Cat |
|
Creación de un objeto StreamReader con parámetro |
Muy a menudo los programadores llaman a las variables igual que a las clases, solo que en minúscula. Para un programador novato, este código puede ser confuso:
| Código |
|---|
|
|
|
En realidad, en este código no hay nada raro — es el código más normal, donde se crea una variable y se inicializa al instante con un objeto de su tipo.
A la izquierda — declaración de la variable, a la derecha — creación de un nuevo objeto en memoria usando new. ¡Eso es todo!
2. Constructor
Seguro que has visto muchas veces que al crear un objeto se le pasan algunos parámetros. Y en algunos objetos se pasan parámetros, y en otros — no. ¿Cómo funciona todo este rollo de los parámetros?
Aquí también es fácil: cada clase tiene un método especial (o varios) que se encarga de procesar los parámetros al crear el objeto. Estos métodos se llaman constructores. Y uno solo, pues, constructor.
Distinguir un método-constructor de un método normal en el código es fácil. Este método tiene dos características:
- el nombre del método-constructor coincide con el nombre de su clase (y empieza con mayúscula)
- el método-constructor no tiene tipo de retorno (ni siquiera se pone void).
Normalmente se ve así:
modificadores Clase(parámetros)
{
código del constructor
}
Ejemplo de declaración de constructor:
public class Point
{
public int X;
public int Y;
public Point(int x, int y) // Constructor
{
X = x;
Y = y;
}
}
Uso:
Point p = new Point(5, 10); // Llamada al constructor
Al crear el objeto con new Point(5, 10) se llamará al constructor con dos parámetros, que inicializan los campos X y Y.
A veces los parámetros del constructor tienen el mismo nombre que los campos — por comodidad. Este conflicto de nombres se resuelve usando la palabra clave this:
public Point(int x, int y)
{
this.x = x; // this.x — campo del objeto, x — parámetro del constructor
this.y = y;
}
3. Llamada al constructor
Cuando escribes new Clase(parámetros), C#:
- crea un nuevo objeto en memoria,
- llama al constructor adecuado, pasando tus parámetros.
Ejemplo con la clase gato:
public class Cat
{
public string Name;
public int Age;
public Cat(string name, int age)
{
Name = name;
Age = age;
}
}
Uso:
Cat cat = new Cat("Vaska", 2); // Se puede: se llama al constructor con dos parámetros
Cat cat2 = new Cat("Vaska"); // No se puede: no existe ese constructor — error de compilación
Cat cat3 = new Cat(); // No se puede: no hay constructor sin parámetros — error de compilación
Si la clase solo tiene constructor con parámetros, tienes que pasarle valores al crear el objeto sí o sí.
4. Varios constructores
Pero si quieres, puedes añadir varios constructores a la clase. No hay límite en la cantidad de constructores ni en sus parámetros. Al crear el objeto, el compilador elige el constructor que encaje con los parámetros.
Ejemplo:
public class Cat
{
public const int DESCONOCIDO = -1;
public string Name;
public int Age;
public Cat(string name, int age)
{
Name = name;
Age = age;
}
public Cat(string name)
{
Name = name;
Age = DESCONOCIDO; // Valor "por defecto" para edad desconocida
}
}
Uso:
Cat cat1 = new Cat("Vaska", 2); // Usa el primer constructor
Cat cat2 = new Cat("Murka"); // Usa el segundo constructor
Cat cat3 = new Cat(); // ¡Error! No hay constructor sin parámetros
Decidimos tener en cuenta que la edad del gato puede ser desconocida. Para ese caso añadimos una constante especial — DESCONOCIDO y un constructor que solo recibe el nombre del gato.
Fíjate que seguimos inicializando ambas variables de clase dentro de los dos constructores. Los parámetros desconocidos/ausentes los cambiamos por la constante DESCONOCIDO.
5. Constructor por defecto
Si tu clase no tiene ningún constructor, el compilador añade automáticamente un constructor vacío sin parámetros:
public ClassName()
{
}
Pero si en la clase ya hay al menos un constructor propio — automáticamente el constructor vacío ya no se añade.
Ejemplo 1:
public class Cat
{
public string Name;
public int Age;
}
// Se puede:
Cat cat = new Cat(); // Se llama al constructor por defecto (sin parámetros)
Ejemplo 2:
public class Cat
{
public string Name;
public int Age;
public Cat(string name) { Name = name; }
}
// No se puede:
Cat cat = new Cat(); // Error: ¡ya no hay constructor sin parámetros!
6. Inicialización de variables
En C# puedes inicializar variables de clase directamente al declararlas, o en el constructor.
Ejemplo:
public class Cat
{
public string Name;
public int Age = -1; // Valor inicial
public Cat(string name, int age)
{
Name = name;
Age = age; // Sobrescribe el valor inicial
}
public Cat()
{
Name = "SinNombre";
// Age se queda en -1 (valor inicial)
}
}
Explicación:
- Al crear con new Cat("Vaska", 2) la variable Age primero será -1, pero luego el constructor le pone 2.
- Al crear con new Cat() — Age se queda en -1.
7. Orden de inicialización de variables
Los datos de un nuevo objeto se inicializan en este orden:
- Los campos de la clase primero reciben valores por defecto (0 para int, null para tipos de referencia, etc.).
- Luego se ejecutan los inicializadores que pusiste al declarar los campos, en el orden en que aparecen en el código.
- Y solo después se ejecuta el código del constructor.
Las variables se inicializan antes del constructor y en el orden de declaración. Así que ojo con las dependencias entre campos.
Ejemplo incorrecto
Los campos no estáticos no se pueden inicializar con variables no estáticas:
public class Solution
{
public int a = 1;
public int b = a; // no se puede usar a
public int c = a + b; // no se puede usar a y b
}
// ¡Este código dará error de compilación!
Ejemplo correcto
Para variables estáticas todo funciona:
public class Solution
{
public static int a = 1; // Ponemos a = 1
public static int b = a + 2; // b = 1 + 2 ⇒ 3
public static int c = a + b + 3; // c = 1 + 3 + 3 ⇒ 7
public Solution()
{
Console.WriteLine($"a = {a}, b = {b}, c = {c}");
// Imprime: a = 1, b = 3, c = 7 — justo lo que esperas
}
}
Ejemplo correcto 2
Para campos estáticos incluso puedes hacer esto:
public class Solution
{
public static int a = b + c + 1; // b y c aún valen 0
public static int b = a + c + 2; // a == 1, c aún vale 0
public static int c = a + b + 3; // a == 1, b == 3
}
GO TO FULL VERSION