Los métodos virtuales y no virtuales soportan las características polimorfísticas de C#, combinando la palabra clave virtual con la anulación . Con la combinación del método virtual en la clase base y la anulación del método en la clase derivada, se dice que ambos métodos son métodos virtuales.
En términos sencillos, este método puede redefinirse en clases derivadas.
La implementación está presente tanto en la clase base como en la derivada, y la mayoría de las veces en las clases derivadas, se añade una funcionalidad extra. Cuando declaramos un método como virtual en una clase base, entonces tenemos la posibilidad de definirlo en la clase base, y opcionalmente la anulación está disponible en las clases derivadas. Cuando el método se declara como virtual en una clase base, y la misma definición existe en una clase derivada, no hay necesidad de anularlo, pero una definición diferente sólo funcionará si el método se anula en la clase derivada.
Dos reglas importantes:
- Por defecto, los métodos no son virtuales y no pueden ser anulados.
- Los modificadores virtuales no pueden utilizarse con modificadores estáticos, abstractos, privados y de anulación.
Demostrémoslo con un ejemplo de código.
1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253 usando el sistema;namespace virtnonvirt{clase públicaPersona{cadena pública _nombre;publicint _edad;cadena pública _sex;publicPerson(nombre de cadena,int edad,sexo de cadena){esto. _age = edad;esto._sex = sexo;esto._nombre = nombre;}publicvoidAge(){ Consola.WriteLine($"Persona :: ¡Hola, tengo {esta._edad} años!");}publicvirtualvoidIntroducción(){ Consola.WriteLine($"Persona :: Hola, mi nombre es {este._nombre}, tengo {esta._edad} años y soy un {este._sexo}");}}clase públicaHombres:Persona{públicoHombres(nombre de la cadena, edad):base(nombre, edad, "hombre"){}publicvoidAge(){consola. WriteLine($"Hombres :: ¡Hola, tengo {esta._edad} años!");}publicoverridevoidIntroduction(){ Consola.WriteLine($"Hombres :: Hola, mi nombre es {este._nombre}, tengo {esta._edad} años y soy un {este._sexo}");}}programa de clase{estaticovacío principal(cadena[] args){Hombres Dani =nuevosHombres("Szabó Dániel Ernő",28);Persona Alien = Dani; Dani. Introducción(); Alien.Introducción(); Dani.Edad(); Alien.Edad(); Consola.Leer Clave();}}}
csharp
La salida del código se ve algo así:
1234Hombres :: Hola, mi nombre es Szabó Dániel Erno, tengo 28 años y soy un hombreHombres :: Hola, mi nombre es Szabó Dániel Erno, tengo 28 años y soy un hombreHombres :: Hola, tengo 28 años! Persona :: Hola, tengo 28 años!
bash
Pero, ¿qué está pasando entre bastidores? Diseccionemos el ejemplo.
Tenemos dos clases. Una es Persona y la otra es Hombre . La Persona es la clase base con dos métodos, Age() y Introduction() . El último es un método virtual, el primero es un método no virtual. El método Introduction() se anula en la clase derivada.
En nuestra función Principal , instanciamos la clase Men con la instancia Dani y luego asignamos la instancia a la Persona clases base nueva instancia. Cuando se invocan los métodos virtual y no virtual en las dos instancias de la clase, se invoca la anulación de la subclase en ambos casos, mostrando el polimorfismo y el funcionamiento interno de la palabra clave virtual.