Certificado de C# OOP

10h 0m

Curso de C# para aprender programación orientada a objetos: clases, herencia, interfaces y más para crear aplicaciones modernas.

Accede GRATIS y certifícate

La programación orientada a objetos (OOP) representa uno de los paradigmas más importantes en el desarrollo de software moderno. C# se ha consolidado como un lenguaje versátil y potente que implementa este paradigma de forma elegante y completa, convirtiéndose en una herramienta fundamental para desarrolladores profesionales en el ecosistema Microsoft y más allá.

¿Qué es la programación orientada a objetos?

La OOP es un paradigma de programación que utiliza "objetos" como elementos fundamentales. Estos objetos son instancias de clases, que funcionan como plantillas o moldes que definen las características (propiedades) y comportamientos (métodos) que tendrán los objetos creados a partir de ellas.

Este enfoque permite modelar problemas del mundo real de manera más intuitiva, organizando el código en unidades cohesivas que encapsulan datos y funcionalidad relacionada, facilitando así el desarrollo, mantenimiento y escalabilidad de aplicaciones complejas.

C# como lenguaje orientado a objetos

C# fue diseñado desde sus inicios como un lenguaje orientado a objetos puro, incorporando todos los conceptos fundamentales de este paradigma:

  • Encapsulación: Permite ocultar los detalles internos de implementación y exponer solo lo necesario.
  • Herencia: Facilita la reutilización de código mediante la creación de jerarquías de clases.
  • Polimorfismo: Permite que objetos de diferentes clases respondan de manera distinta al mismo mensaje.
  • Abstracción: Posibilita representar conceptos complejos de forma simplificada.

A lo largo de este curso, exploraremos estos conceptos y muchos más, desde los fundamentos hasta técnicas avanzadas que te permitirán aprovechar todo el potencial de C# como lenguaje OOP.

Fundamentos de clases y objetos en C#

En C#, todo comienza con las clases y objetos. Una clase es una estructura que define un tipo de datos, mientras que un objeto es una instancia concreta de esa clase. Por ejemplo:

// Definición de una clase
public class Persona
{
    // Propiedades
    public string Nombre { get; set; }
    public int Edad { get; set; }
    
    // Método
    public void Presentarse()
    {
        Console.WriteLine($"Hola, soy {Nombre} y tengo {Edad} años.");
    }
}

// Creación de un objeto (instancia de la clase)
Persona persona1 = new Persona();
persona1.Nombre = "Ana";
persona1.Edad = 30;
persona1.Presentarse(); // Salida: Hola, soy Ana y tengo 30 años.

Este ejemplo ilustra cómo una clase encapsula tanto datos (propiedades Nombre y Edad) como comportamiento (método Presentarse).

Encapsulación y control de acceso

La encapsulación es un principio fundamental que permite controlar el acceso a los miembros de una clase. C# proporciona modificadores de acceso como public, private, protected e internal para este fin:

public class CuentaBancaria
{
    // Campo privado - solo accesible dentro de la clase
    private decimal _saldo;
    
    // Propiedad pública con lógica de validación
    public decimal Saldo
    {
        get { return _saldo; }
        private set { _saldo = value; } // Solo se puede modificar dentro de la clase
    }
    
    public void Depositar(decimal cantidad)
    {
        if (cantidad <= 0)
            throw new ArgumentException("La cantidad debe ser positiva");
            
        _saldo += cantidad;
    }
}

Este patrón de diseño protege los datos internos y garantiza que solo puedan modificarse a través de métodos controlados, manteniendo la integridad de los datos.

Constructores y ciclo de vida de los objetos

Los constructores son métodos especiales que se ejecutan cuando se crea un objeto, permitiendo inicializar sus propiedades. C# también proporciona destructores (o finalizadores) que se ejecutan cuando un objeto es eliminado por el recolector de basura:

public class Recurso
{
    private string _nombre;
    
    // Constructor sin parámetros
    public Recurso()
    {
        _nombre = "Sin nombre";
        Console.WriteLine("Recurso creado");
    }
    
    // Constructor con parámetros
    public Recurso(string nombre)
    {
        _nombre = nombre;
        Console.WriteLine($"Recurso '{_nombre}' creado");
    }
    
    // Destructor
    ~Recurso()
    {
        Console.WriteLine($"Recurso '{_nombre}' liberado");
    }
}

C# también proporciona el patrón IDisposable para una gestión más controlada de recursos:

public class ConexionBD : IDisposable
{
    private bool _disposed = false;
    
    public void Dispose()
    {
        Dispose(true);
        GC.SuppressFinalize(this);
    }
    
    protected virtual void Dispose(bool disposing)
    {
        if (!_disposed)
        {
            if (disposing)
            {
                // Liberar recursos administrados
            }
            
            // Liberar recursos no administrados
            _disposed = true;
        }
    }
}

Herencia y extensibilidad

La herencia permite crear nuevas clases basadas en clases existentes, heredando sus miembros y añadiendo o modificando funcionalidad:

// Clase base
public class Vehiculo
{
    public string Marca { get; set; }
    public string Modelo { get; set; }
    
    public virtual void Arrancar()
    {
        Console.WriteLine("El vehículo está arrancando");
    }
}

// Clase derivada
public class Coche : Vehiculo
{
    public int NumeroPuertas { get; set; }
    
    // Sobrescribe el método de la clase base
    public override void Arrancar()
    {
        Console.WriteLine("El coche está arrancando con llave");
    }
}

La palabra clave virtual permite que los métodos sean sobrescritos en clases derivadas, mientras que override indica que estamos redefiniendo un método de la clase base.

Polimorfismo y flexibilidad

El polimorfismo es la capacidad de tratar objetos de diferentes clases a través de una interfaz común. Esto proporciona gran flexibilidad al código:

public void ProcesarVehiculos(List<Vehiculo> vehiculos)
{
    foreach (var vehiculo in vehiculos)
    {
        // Cada tipo de vehículo responderá según su implementación
        vehiculo.Arrancar();
    }
}

// Uso
var listaVehiculos = new List<Vehiculo>
{
    new Coche { Marca = "Toyota", Modelo = "Corolla" },
    new Motocicleta { Marca = "Honda", Modelo = "CBR" }
};

ProcesarVehiculos(listaVehiculos);

Interfaces y contratos

Las interfaces definen contratos que las clases pueden implementar, estableciendo qué métodos y propiedades deben proporcionar sin especificar cómo deben implementarse:

public interface IVolador
{
    void Despegar();
    void Aterrizar();
    double CalcularAutonomia();
}

public class Avion : IVolador
{
    public void Despegar()
    {
        Console.WriteLine("El avión está despegando");
    }
    
    public void Aterrizar()
    {
        Console.WriteLine("El avión está aterrizando");
    }
    
    public double CalcularAutonomia()
    {
        return 5000.0; // km
    }
}

Las interfaces permiten implementar múltiples herencias de comportamiento, algo que no es posible con la herencia de clases en C#.

Clases abstractas

Las clases abstractas combinan características de las interfaces y las clases normales, permitiendo implementación parcial y definición de contratos:

public abstract class Animal
{
    public string Nombre { get; set; }
    
    // Método con implementación
    public void Respirar()
    {
        Console.WriteLine("El animal está respirando");
    }
    
    // Método abstracto (sin implementación)
    public abstract void HacerSonido();
}

public class Perro : Animal
{
    // Obligatorio implementar los métodos abstractos
    public override void HacerSonido()
    {
        Console.WriteLine("¡Guau!");
    }
}

Genéricos para código reutilizable

Los genéricos permiten crear clases, interfaces y métodos que operan con tipos que se especifican cuando se crea una instancia o se invoca el método:

public class Contenedor<T>
{
    private T _contenido;
    
    public void Guardar(T item)
    {
        _contenido = item;
    }
    
    public T Obtener()
    {
        return _contenido;
    }
}

// Uso con diferentes tipos
var contenedorEnteros = new Contenedor<int>();
contenedorEnteros.Guardar(42);

var contenedorCadenas = new Contenedor<string>();
contenedorCadenas.Guardar("Hola mundo");

Esta característica proporciona seguridad de tipos y evita conversiones innecesarias, mejorando el rendimiento y la legibilidad del código.

Delegados y eventos

Los delegados son tipos que representan referencias a métodos, permitiendo pasar métodos como parámetros:

// Definición de un delegado
public delegate int Operacion(int a, int b);

// Métodos que coinciden con la firma del delegado
public int Sumar(int a, int b) => a + b;
public int Multiplicar(int a, int b) => a * b;

// Uso del delegado
public void Calcular(int x, int y, Operacion operacion)
{
    int resultado = operacion(x, y);
    Console.WriteLine($"El resultado es: {resultado}");
}

// Llamadas
Calcular(5, 3, Sumar);        // El resultado es: 8
Calcular(5, 3, Multiplicar);  // El resultado es: 15

Los eventos son un mecanismo basado en delegados que permite a una clase notificar a otras cuando ocurre algo relevante:

public class Temporizador
{
    // Definición del delegado para el evento
    public delegate void TiempoTranscurridoHandler(object sender, EventArgs e);
    
    // Declaración del evento
    public event TiempoTranscurridoHandler TiempoTranscurrido;
    
    public void Iniciar()
    {
        // Simulación de tiempo transcurrido
        Thread.Sleep(1000);
        
        // Disparar el evento
        OnTiempoTranscurrido();
    }
    
    protected virtual void OnTiempoTranscurrido()
    {
        // Verificar si hay suscriptores antes de invocar
        TiempoTranscurrido?.Invoke(this, EventArgs.Empty);
    }
}

Características avanzadas

C# también ofrece características avanzadas como:

  • Métodos de extensión: Permiten añadir métodos a tipos existentes sin modificarlos:
public static class StringExtensions
{
    public static bool EsPalindromo(this string texto)
    {
        string textoNormalizado = texto.ToLower().Replace(" ", "");
        char[] caracteres = textoNormalizado.ToCharArray();
        Array.Reverse(caracteres);
        string textoInvertido = new string(caracteres);
        
        return textoNormalizado == textoInvertido;
    }
}

// Uso
bool esPalindromo = "Anita lava la tina".EsPalindromo(); // true
  • Tuplas y tipos anónimos: Facilitan el trabajo con datos estructurados sin necesidad de definir clases específicas:
// Tupla
(string Nombre, int Edad) persona = ("Carlos", 28);
Console.WriteLine($"{persona.Nombre} tiene {persona.Edad} años");

// Tipo anónimo
var producto = new { Id = 1, Nombre = "Laptop", Precio = 1200.50m };
Console.WriteLine($"Producto: {producto.Nombre}, Precio: {producto.Precio}€");
  • Manejo de excepciones: Permite gestionar errores de forma estructurada:
try
{
    int resultado = 10 / 0; // Esto generará una excepción
}
catch (DivideByZeroException ex)
{
    Console.WriteLine($"Error matemático: {ex.Message}");
}
catch (Exception ex)
{
    Console.WriteLine($"Error general: {ex.Message}");
}
finally
{
    Console.WriteLine("Este bloque siempre se ejecuta");
}

Aplicaciones prácticas

La programación orientada a objetos en C# se utiliza en una amplia variedad de aplicaciones:

  • Desarrollo de aplicaciones empresariales con .NET y ASP.NET
  • Desarrollo de videojuegos con Unity
  • Aplicaciones de escritorio con WPF o Windows Forms
  • Aplicaciones móviles con Xamarin o MAUI
  • Servicios web y microservicios con ASP.NET Core

A lo largo de este curso, aprenderás a aplicar estos conceptos en situaciones reales, desarrollando habilidades prácticas que podrás utilizar en proyectos profesionales.

Buenas prácticas en OOP con C#

Para aprovechar al máximo la programación orientada a objetos en C#, es importante seguir algunas buenas prácticas:

  • Principio de responsabilidad única: Cada clase debe tener una única razón para cambiar.
  • Principio abierto/cerrado: Las entidades deben estar abiertas para extensión pero cerradas para modificación.
  • Principio de sustitución de Liskov: Los objetos de una clase derivada deben poder sustituir a los objetos de la clase base sin afectar la corrección del programa.
  • Principio de segregación de interfaces: Es mejor tener muchas interfaces específicas que una interfaz general.
  • Principio de inversión de dependencias: Depender de abstracciones, no de implementaciones concretas.

Estos principios, conocidos como principios SOLID, te ayudarán a crear código más mantenible, extensible y robusto.

Herramientas y entorno de desarrollo

Para desarrollar aplicaciones con C# y OOP, utilizaremos:

  • Visual Studio o Visual Studio Code: Entornos de desarrollo integrados (IDE) con potentes características para C#.
  • .NET SDK: El kit de desarrollo de software que proporciona las herramientas necesarias para compilar y ejecutar aplicaciones .NET.
  • NuGet: El gestor de paquetes para .NET que facilita la incorporación de bibliotecas externas.

Estas herramientas te proporcionarán un entorno completo para aplicar todos los conceptos que aprenderás en este curso.

A través de este itinerario, adquirirás una comprensión profunda de la programación orientada a objetos en C#, desde los conceptos fundamentales hasta técnicas avanzadas, preparándote para desarrollar aplicaciones robustas y mantenibles en el mundo profesional.

Empezar curso GRATIS

Tutoriales de programación en este certificado

Completa estas lecciones de programación para obtener tu certificado de superación

Ejercicios de programación de C# OOP

Completa estos ejercicios de programación para obtener tu certificado de superación

Otros cursos de programación con certificado

Supera todos los retos de C# OOP y obtén estos certificados de superación para mejorar tu currículum y tu empleabilidad.

Tecnologías que aprenderás

C# OOP

Al finalizar este curso obtendrás

Certificado de superación en C# OOP

Certificado de superación en C# OOP

Tras completar todas las lecciones y ejercicios del curso C# OOP se te genera un enlace con tu certificado para que lo puedas descargar o compartir directamente en cualquier plataforma, siempre accesible.

Accede a todas certificaciones