La herencia en C# permite un diseño más limpio y mantenible: reduces código redundante, centralizas comportamientos en una clase base y controlas quién puede instanciar u heredar. Aquí verás cómo crear un objeto base reutilizable, corregir errores de namespace y GUID, y aplicar clases abstractas y clases selladas en Visual Studio Code con debug y build.
¿Qué es herencia y cómo se aplica en c#?
La herencia replica la idea real: un “padre” transmite atributos y métodos a sus “hijos**.** Un objeto padre puede exponer todo o reservar comportamientos para que el hijo los implemente. Esto habilita la sobreescritura de métodos: por ejemplo, definir un método caminar y exigir que cada hijo lo implemente a su manera.
Centraliza campos comunes: Unique ID y Nombre se mueven a un objeto base.
Define la inicialización del ID en un único lugar: dentro del constructor.
Elimina duplicados: Alumno, Asignatura, Curso, Escuela y Evaluación heredan y borran sus copias locales.
Ejemplo de objeto base con inicialización desde el constructor:
usingSystem;// Base reutilizable para todos los objetos del dominio.abstractclassObjetoEscuelaBase{publicstring Nombre {get;set;}publicGuid UniqueId {get;}publicObjetoEscuelaBase(){ UniqueId = Guid.NewGuid();}}
Clases que heredan y simplifican su código:
classAlumno:ObjetoEscuelaBase{// Propiedades específicas, por ejemplo: evaluaciones.}classAsignatura:ObjetoEscuelaBase{}classCurso:ObjetoEscuelaBase{}classEscuela:ObjetoEscuelaBase{}classEvaluacion:ObjetoEscuelaBase{}
Validación práctica con debug: se ejecuta, se recorre la inicialización, se crean entidades y se imprimen resultados. Si aparecen errores, se revisa el editor y se corrigen.
¿Cómo controlar instanciación y herencia con clases abstractas y selladas?
Para evitar usos incorrectos, se definen modificadores que expresan la intención del diseño.
Clase abstracta: se puede heredar, pero no instanciar. Ideal para “solo idea” o contrato base.
Clase sellada: se puede instanciar, pero no heredar. Útil cuando no debe extenderse.
Aplicación directa:
El objeto base se marca como abstracto: nadie puede crear “nuevo ObjetoEscuelaBase”, pero todos pueden heredar de él.
EscuelaEngine se marca sellada: se puede instanciar para operar el motor, pero no permite subclases.
abstractclassObjetoEscuelaBase{/* ... */}sealedclassEscuelaEngine{// Lógica de orquestación del dominio.}// Error de compilación: no se puede heredar de una clase sellada.// class Dummy : EscuelaEngine { }// Herencia permitida desde la base abstracta.classDummy:ObjetoEscuelaBase{}
Este control evita mal uso del modelo: la base es una idea compartida, el engine es una implementación cerrada.
¿Qué problemas comunes se resolvieron y qué sigue con polimorfismo?
Durante la ejecución aparecieron errores visibles en el editor. La solución se centró en dependencias y espacios de nombres.
Falta de namespace para GUID: se agrega la directiva correspondiente y se corrigen puntos y comas sobrantes.
Namespace incorrecto en la base: se ajusta para alinear a “Core Escuela” y desaparecen los errores.
Verificación por consola:
dotnet build
Prueba con debug: se recorre la carga de Escuela, Cursos, Asignaturas y Evaluaciones; luego se imprime el resultado.
Habilidades y conceptos reforzados:
Refactorización por herencia: mover atributos y constructores al padre.
Inicialización en el constructor: asignar el Unique ID una sola vez.
Sobreescritura de métodos: reservar comportamientos para que cada hijo los implemente.
Clases abstractas y selladas: controlar instanciación y extensibilidad.
Diagnóstico de errores: corregir namespaces, compilar con build y validar con debug.
Polimorfismo (avance): un Alumno puede tratarse como ObjetoEscuelaBase, pero no al revés. Se profundizará con ejemplos prácticos.
¿Con qué casos aplicarías herencia, clases abstractas o selladas en tu proyecto? Comparte tus dudas y ejemplos para analizarlos juntos.
Si queremos que nuestra clase sea INSTANCIADA pero que no fuera posible **HEREDAR de ella ** debemos utilizar el tipo de clase SEALED (Clase sellada).
Si queremos que nuestra clase sea HEREDADA pero que no fuera posible INSTANCIARLA debemos utilizar el tipo de clase ABSTRACT (clase abstracta)
Me encantó este resumen buen aporte doc!
Los términos de programación que cuestan tanto trabajo explicar aquí se aclaran de manera fácil. "Una clase abstracta es una idea".
Creo que solo las personas que dominan bien un tema pueden llegar a simplificar un concepto.
Una clase abstracta (asbtract) puede ser heredada pero no instanciada
Una clase sellada (sealed) no puede ser heredada pero si instaciada
¿Cómo aplicarlas?
public abstract/sealed classdummy(){//props and methods}
Una pregunta respecto a las dos formas que presenta Juan para inicializar la variable UniqueID. Cuando la inicializo desde la propiedad:
public string UniqueId { get; private set; } = Guid.NewGuid().ToString();
¿En que momento se genera el valor UniqueId?
¿Se crea al momento de llamar al constructor? Osea, da exáctamente lo mismo inicializarla en la propiedad que en el constructor? o ¿existe diferencia entre las dos respecto a cuando se inicializa el valor?
La respuesta está en tu corazón. jaja
Un pequeño obsequio.
classProgram{publicstatic string UniqueId{ get;private set;}=AsignadorDeGuid();publicstatic string UniqueId2{ get;private set;}publicstatic string UniqueId3{ get;private set;}staticvoidMain(string[] args){UniqueId2=AsignadorDeGuid();}staticProgram(){UniqueId3=AsignadorDeGuid();}publicstatic string AsignadorDeGuid([CallerMemberName] string caller ="",[CallerFilePath] string path ="",[CallerLineNumber] int line =0){Console.WriteLine($"LLamado desde {caller}, línea{line} archivo: {path}");returnGuid.NewGuid().ToString();}}
Y la respuesta en la salida
LLamado desde UniqueId, línea9 archivo:C:\Temp\tests\Program.csLLamado desde .cctor, línea21 archivo:C:\Temp\tests\Program.csLLamado desde Main, línea16 archivo:C:\Temp\tests\Program.cs
jajaja … Gracias profe Juan !! Mi corazón ya lo intuía … jejeje
Yo hice lo de esta clase en el curso pasado asi que me siento orgulloso de ello.
Abstract : es solo una idea, no deja crear un objeto pero si lo deja heredar
Sealed: Si deja crear instancias pero no deja heredar.
Gracias, se entiende la esencia del concepto de herencia, pero siendo un poco pragmáticos creo que no es el mejor ejemplo dado a que Escuela no comparte una relación de origen con las clases que está heredando. El razonamiento sería: si yo tengo un objeto BaseEscuela esperaría que los heredaran otros tipos de escuelas personalizadas ejemplo : EscuelaDanza, EscuelaArtesMarciales, EscuelaPrescolar etc.
En éste caso para que el concepto fuera coherente me gustaría llamar a la base:
ObjetoNegocioBase.
Ya que así, siendo más general (abstracto) sé que las propiedades y métodos que puedo concentrar en base comparten comportamientos en común con un objeto de negocio y no con un concepto al que no tienen una relación clara.
Espero haberme dado a entender.
Vengo del 2022 y estoy de acuerdo contigo. Ademas la ultima parte que menciono el profesor no tiene sentido un Alumno no es una EscuelaBase y una EscuelaBase tampoco es un alumno. En si aqui se esta aplicando la herencia de forma netamente funcional pero no encaja conceptualmente del todo.
Herencia : En POO , una clase HIJA puede HEREDAR de su clase PADRE cualquier OBJETO que este tenga. Existen diferentes formas de aplicar la herencia :
Puede ser que se elija que va heredar todos los atributos y métodos de mi clase PADRE.
Puede ser que se elija pasar todo, excepto un método que quiero que la clase HIJA implemente de acuerdo a su necesidad, es decir solo heredo la estructura de dicho método pero dejo que
su construcción, su estructura interna lo haga la clase HIJA.(Sobre escritura de métodos).
Si solo quiero utilizar una clase para que hereden de ella se debe utilizar un modificador de acceso llamado "abstract".
Si quiero que de una clase solo se pueda realizar instancias de la misma debo utilizar el modificador de acceso llamado " selead".
Gracias por los apuntes Viejo.
Una clase puede **Heredar ** de otra clase "Padre" todo los atributos, métodos y demás contenido dentro de la clase.
La palabra clave sealed se usa para indicar que esa clase no permitirá que herede sus propiedades y métodos a ninguna otra clase pero si se pueda instanciar.
La palabra clave abstract se usa para indicar que esa clase no permitira que se instancie en ninguna otra clase pero si permitirá que se hereden sus propiedades y métodos.
Abstract
Al anteponer la clase con la palabra abstract le decimos que solamente puede ser heredada, pero nunca instanciada.
Sealed
Al anteponer la clase con la palabra sealed le decimos que puede ser instanciada, pero no permita que sea heredada.
Clases tipo Sealed y Abstractas
Sealed -> No puedo heredar pero si puedo instanciar.
Abstract -> Puedo heredar pero no puedo instanciar.
Tanto que en la universidad me explicaban esto y no entendía, en platzi solo en minutos aprendes algo nuevo.
ohhh waw, siempre tuve un miedo por la herencia irracional. Ahora entiendo que era más sencillo de lo que creí. Definitivamente platzi vale la pena.
Si suele pasar, esos términos asustan un poco, por si de pronto no lo has realizado te recomiendo mucho el curso de POO
La clase ObjetoEscuelaBase, se debería llamar solo EscuelaBase, pues con la palabra Objeto confunde el concepto, una clase no es un objeto.
Al realizar la Herencia, dentro del file: Escuela.cs, aun me subraya la propiedad "nombre" dentro del constructor de esa clase. ¿Alguien me podrá explicar por que sucede esto y como solucionarlo?
Por favor, copia tal cual el código para poder revisar... O sube una captura de pantalla.
Es muy probable que te falte la palabra reservada "this" que hace referencia al objeto actual:
this.nombre = nombre;
Una clase abstracta se define como una clase que declara la existencia de métodos pero no la implementación de dichos métodos
Error. Una clase abstracta ademas de definir metodos tambien podria implementarlos. De hecho podria ambos, definir algunos metodos e implementar otros.
Una explicación sencilla y muy clara de lo que es una clase abstracta...
Excelente clase...
clases abstractas, se pueden heredar pero no se pueden crear instancias :)