Clases y objetos en C#
Introducción
Las clases y los objetos constituyen la base fundamental de la programación orientada a objetos en C#. Una clase es como un plano o plantilla que define las características y comportamientos que tendrán los objetos creados a partir de ella, mientras que un objeto es una instancia específica de esa clase. Este concepto es similar a como un plano arquitectónico define la estructura de una casa, pero la casa construida es el objeto real que podemos habitar.
Comprender las clases y objetos es esencial para dominar C#, ya que todo en este lenguaje está basado en este paradigma. Incluso el programa más simple que hemos escrito utiliza clases, aunque no hayamos sido conscientes de ello. En este artículo aprenderemos a crear nuestras propias clases, instanciar objetos y trabajar con sus miembros.
¿Qué es una clase?
Una clase es un tipo de datos personalizado que agrupa variables (llamadas campos o propiedades) y métodos relacionados en una sola unidad. Es una plantilla que describe qué datos puede almacenar un objeto y qué operaciones puede realizar.
Elementos básicos de una clase
Elemento | Descripción | Propósito |
---|---|---|
Campos | Variables que almacenan datos | Representan el estado del objeto |
Propiedades | Acceso controlado a los campos | Encapsulan el acceso a los datos |
Métodos | Funciones que realizan operaciones | Definen el comportamiento del objeto |
Constructor | Método especial de inicialización | Configura el estado inicial del objeto |
Sintaxis básica de una clase
public class NombreDeLaClase
{
// Campos
private tipo campo;
// Propiedades
public tipo Propiedad { get; set; }
// Constructor
public NombreDeLaClase()
{
// Código de inicialización
}
// Métodos
public tipo NombreDelMetodo()
{
// Código del método
return valor;
}
}
Creando nuestra primera clase
Vamos a crear una clase Persona
que represente a una persona con características básicas:
public class Persona
{
// Campos privados
private string nombre;
private int edad;
private string email;
// Constructor
public Persona(string nombre, int edad, string email)
{
this.nombre = nombre;
this.edad = edad;
this.email = email;
}
// Método para mostrar información
public void MostrarInformacion()
{
Console.WriteLine($"Nombre: {nombre}");
Console.WriteLine($"Edad: {edad} años");
Console.WriteLine($"Email: {email}");
}
// Método para saludar
public string Saludar()
{
return $"¡Hola! Soy {nombre} y tengo {edad} años.";
}
// Método para validar si es mayor de edad
public bool EsMayorDeEdad()
{
return edad >= 18;
}
}
En este ejemplo, la clase Persona
tiene:
- Tres campos privados para almacenar los datos
- Un constructor que inicializa estos datos
- Tres métodos que definen comportamientos específicos
¿Qué es un objeto?
Un objeto es una instancia específica de una clase. Es la materialización de la plantilla que representa la clase, con valores concretos para sus campos y la capacidad de ejecutar sus métodos.
Proceso de creación de objetos
Paso | Acción | Descripción |
---|---|---|
1 | Declaración | Se declara una variable del tipo de la clase |
2 | Instanciación | Se usa new para crear el objeto en memoria |
3 | Inicialización | Se ejecuta el constructor para configurar el estado inicial |
4 | Uso | Se accede a los miembros del objeto mediante el operador punto |
Creando y usando objetos
Una vez que tenemos nuestra clase definida, podemos crear objetos (instancias) de ella:
class Program
{
static void Main()
{
// Crear objetos de la clase Persona
Persona persona1 = new Persona("Ana García", 25, "ana@email.com");
Persona persona2 = new Persona("Carlos López", 17, "carlos@email.com");
// Usar los métodos de los objetos
Console.WriteLine("=== Información de las personas ===");
persona1.MostrarInformacion();
Console.WriteLine(persona1.Saludar());
Console.WriteLine($"¿Es mayor de edad? {persona1.EsMayorDeEdad()}");
Console.WriteLine(); // Línea en blanco
persona2.MostrarInformacion();
Console.WriteLine(persona2.Saludar());
Console.WriteLine($"¿Es mayor de edad? {persona2.EsMayorDeEdad()}");
}
}
Salida esperada:
=== Información de las personas ===
Nombre: Ana García
Edad: 25 años
Email: ana@email.com
¡Hola! Soy Ana García y tengo 25 años.
¿Es mayor de edad? True
Nombre: Carlos López
Edad: 17 años
Email: carlos@email.com
¡Hola! Soy Carlos López y tengo 17 años.
¿Es mayor de edad? False
La palabra clave this
La palabra clave this
hace referencia a la instancia actual del objeto. Es especialmente útil cuando hay ambigüedad entre parámetros del método y campos de la clase:
public class CuentaBancaria
{
private double saldo;
private string titular;
public CuentaBancaria(string titular, double saldoInicial)
{
// 'this' distingue entre el campo y el parámetro
this.titular = titular;
this.saldo = saldoInicial;
}
public void Depositar(double cantidad)
{
// Aquí no es necesario 'this' porque no hay ambigüedad
saldo += cantidad;
Console.WriteLine($"Depósito realizado. Saldo actual: {saldo:C}");
}
public bool Retirar(double cantidad)
{
if (cantidad <= saldo)
{
saldo -= cantidad;
Console.WriteLine($"Retiro realizado. Saldo actual: {saldo:C}");
return true;
}
else
{
Console.WriteLine("Fondos insuficientes");
return false;
}
}
public string ObtenerInformacion()
{
return $"Titular: {titular}, Saldo: {saldo:C}";
}
}
Ejemplo práctico: Sistema de biblioteca
Veamos un ejemplo más complejo con una clase Libro
que podría formar parte de un sistema de gestión de biblioteca:
public class Libro
{
// Campos privados
private string titulo;
private string autor;
private string isbn;
private bool prestado;
private DateTime fechaPrestamo;
// Constructor
public Libro(string titulo, string autor, string isbn)
{
this.titulo = titulo;
this.autor = autor;
this.isbn = isbn;
this.prestado = false; // Por defecto, no está prestado
}
// Método para prestar el libro
public bool Prestar()
{
if (!prestado)
{
prestado = true;
fechaPrestamo = DateTime.Now;
Console.WriteLine($"El libro '{titulo}' ha sido prestado el {fechaPrestamo.ToShortDateString()}");
return true;
}
else
{
Console.WriteLine($"El libro '{titulo}' ya está prestado");
return false;
}
}
// Método para devolver el libro
public bool Devolver()
{
if (prestado)
{
prestado = false;
TimeSpan tiempoPrestado = DateTime.Now - fechaPrestamo;
Console.WriteLine($"El libro '{titulo}' ha sido devuelto después de {tiempoPrestado.Days} días");
return true;
}
else
{
Console.WriteLine($"El libro '{titulo}' no estaba prestado");
return false;
}
}
// Método para obtener información del libro
public string ObtenerInformacion()
{
string estado = prestado ? $"Prestado desde {fechaPrestamo.ToShortDateString()}" : "Disponible";
return $"Título: {titulo}\nAutor: {autor}\nISBN: {isbn}\nEstado: {estado}";
}
// Método para verificar disponibilidad
public bool EstaDisponible()
{
return !prestado;
}
}
Ahora podemos usar esta clase para gestionar libros:
class Program
{
static void Main()
{
// Crear algunos libros
Libro libro1 = new Libro("El Quijote", "Miguel de Cervantes", "978-84-376-0494-7");
Libro libro2 = new Libro("Cien años de soledad", "Gabriel García Márquez", "978-84-376-0495-4");
Console.WriteLine("=== Estado inicial de los libros ===");
Console.WriteLine(libro1.ObtenerInformacion());
Console.WriteLine();
Console.WriteLine(libro2.ObtenerInformacion());
Console.WriteLine();
Console.WriteLine("=== Operaciones de préstamo ===");
libro1.Prestar(); // Prestamos el primer libro
libro1.Prestar(); // Intentamos prestarlo de nuevo
Console.WriteLine();
Console.WriteLine("=== Estado después del préstamo ===");
Console.WriteLine(libro1.ObtenerInformacion());
Console.WriteLine();
Console.WriteLine("=== Verificar disponibilidad ===");
Console.WriteLine($"¿Está disponible '{libro1.ObtenerInformacion()}'? {libro1.EstaDisponible()}");
Console.WriteLine($"¿Está disponible '{libro2.ObtenerInformacion()}'? {libro2.EstaDisponible()}");
// Simulamos el paso del tiempo y devolvemos el libro
Console.WriteLine("\n=== Devolución del libro ===");
libro1.Devolver();
}
}
Múltiples objetos de la misma clase
Una de las grandes ventajas de las clases es que podemos crear múltiples objetos, cada uno con su propio estado independiente:
class Program
{
static void Main()
{
// Crear múltiples cuentas bancarias
CuentaBancaria cuenta1 = new CuentaBancaria("María Fernández", 1000);
CuentaBancaria cuenta2 = new CuentaBancaria("Pedro Jiménez", 500);
CuentaBancaria cuenta3 = new CuentaBancaria("Laura Martín", 1500);
Console.WriteLine("=== Estado inicial de las cuentas ===");
Console.WriteLine(cuenta1.ObtenerInformacion());
Console.WriteLine(cuenta2.ObtenerInformacion());
Console.WriteLine(cuenta3.ObtenerInformacion());
Console.WriteLine("\n=== Operaciones bancarias ===");
cuenta1.Depositar(200);
cuenta2.Retirar(100);
cuenta3.Retirar(2000); // Intento de retiro con fondos insuficientes
Console.WriteLine("\n=== Estado final de las cuentas ===");
Console.WriteLine(cuenta1.ObtenerInformacion());
Console.WriteLine(cuenta2.ObtenerInformacion());
Console.WriteLine(cuenta3.ObtenerInformacion());
}
}
Cada objeto mantiene su propio estado independiente. Las operaciones en cuenta1
no afectan a cuenta2
o cuenta3
.
Diferencias entre clases y objetos
Aspecto | Clase | Objeto |
---|---|---|
Naturaleza | Plantilla o molde | Instancia específica |
Memoria | No ocupa memoria para datos | Ocupa memoria en tiempo de ejecución |
Cantidad | Una definición por programa | Pueden existir múltiples instancias |
Estado | Define qué datos puede tener | Tiene valores específicos para esos datos |
Momento | Se define en tiempo de compilación | Se crea en tiempo de ejecución |
Buenas prácticas para clases y objetos
- Nombres descriptivos: Usa nombres que describan claramente el propósito de la clase
- Responsabilidad única: Cada clase debe tener una responsabilidad específica
- Encapsulación: Mantén los campos privados y proporciona acceso controlado
- Constructores útiles: Asegúrate de que los objetos se inicialicen en un estado válido
- Métodos con propósito: Cada método debe realizar una tarea específica y bien definida
Resumen
Las clases y objetos son los pilares fundamentales de la programación orientada a objetos en C#. Una clase es una plantilla que define la estructura y comportamiento de los objetos, mientras que un objeto es una instancia específica de esa clase con valores concretos. Hemos aprendido a crear clases con campos, constructores y métodos, así como a instanciar objetos y utilizar sus miembros. La palabra clave this
nos permite referenciar la instancia actual, y cada objeto mantiene su propio estado independiente. Este conocimiento forma la base para conceptos más avanzados como propiedades, herencia y polimorfismo que exploraremos en los siguientes artículos.