Il y a une différence entre newet virtual/ override.
Vous pouvez imaginer qu'une classe, une fois instanciée, n'est rien de plus qu'une table de pointeurs, pointant vers l'implémentation réelle de ses méthodes. L'image suivante devrait bien visualiser cela:

Maintenant, il existe différentes manières, une méthode peut être définie. Chacun se comporte différemment lorsqu'il est utilisé avec l'héritage. La méthode standard fonctionne toujours comme l'illustre l'image ci-dessus. Si vous souhaitez modifier ce comportement, vous pouvez associer différents mots-clés à votre méthode.
1. Classes abstraites
Le premier est abstract. abstractles méthodes ne pointent simplement nulle part:

Si votre classe contient des membres abstraits, elle doit également être marquée comme abstract, sinon le compilateur ne compilera pas votre application. Vous ne pouvez pas créer d'instances de abstractclasses, mais vous pouvez en hériter et créer des instances de vos classes héritées et y accéder à l'aide de la définition de classe de base. Dans votre exemple, cela ressemblerait à:
public abstract class Person
{
public abstract void ShowInfo();
}
public class Teacher : Person
{
public override void ShowInfo()
{
Console.WriteLine("I am a teacher!");
}
}
public class Student : Person
{
public override void ShowInfo()
{
Console.WriteLine("I am a student!");
}
}
S'il est appelé, le comportement de ShowInfovarie en fonction de l'implémentation:
Person person = new Teacher();
person.ShowInfo(); // Shows 'I am a teacher!'
person = new Student();
person.ShowInfo(); // Shows 'I am a student!'
Les deux, Students et Teachers sont des Persons, mais ils se comportent différemment quand on leur demande de demander des informations sur eux-mêmes. Cependant, la façon de leur demander de demander leurs informations est la même: en utilisant l' Personinterface de classe.
Alors que se passe-t-il dans les coulisses, lorsque vous héritez Person? Lors de l'implémentation ShowInfo, le pointeur ne pointe plus vers nulle part , il pointe désormais vers l'implémentation réelle! Lors de la création d'une Studentinstance, il pointe vers Students ShowInfo:

2. Méthodes virtuelles
La deuxième façon est d'utiliser des virtualméthodes. Le comportement est le même, sauf que vous fournissez une implémentation par défaut facultative dans votre classe de base. Les classes avec des virtualmembres peuvent être instanciées, mais les classes héritées peuvent fournir différentes implémentations. Voici à quoi votre code devrait ressembler pour fonctionner:
public class Person
{
public virtual void ShowInfo()
{
Console.WriteLine("I am a person!");
}
}
public class Teacher : Person
{
public override void ShowInfo()
{
Console.WriteLine("I am a teacher!");
}
}
La principale différence est que le membre de base Person.ShowInfone pointe plus vers nulle part . C'est également la raison pour laquelle vous pouvez créer des instances de Person(et il n'est donc pas nécessaire de le marquer abstractplus longtemps):

Vous devriez remarquer que cela ne semble pas différent de la première image pour le moment. C'est parce que la virtualméthode pointe vers une implémentation «à la manière standard ». En utilisant virtual, vous pouvez dire Personsqu'ils peuvent (pas obligés ) fournir une implémentation différente pour ShowInfo. Si vous fournissez une implémentation différente (en utilisant override), comme je l'ai fait pour ce qui Teacherprécède, l'image aura la même apparence que pour abstract. Imaginez, nous n'avons pas fourni d'implémentation personnalisée pour Students:
public class Student : Person
{
}
Le code serait appelé comme ceci:
Person person = new Teacher();
person.ShowInfo(); // Shows 'I am a teacher!'
person = new Student();
person.ShowInfo(); // Shows 'I am a person!'
Et l'image de Studentressemblerait à ceci:

3. Le mot-clé magique `new` aka" Shadowing "
newest plus un hack autour de cela. Vous pouvez fournir des méthodes dans des classes généralisées, qui ont les mêmes noms que des méthodes dans la classe / interface de base. Les deux pointent vers leur propre implémentation personnalisée:

L'implémentation ressemble à celle que vous avez fournie. Le comportement diffère selon la manière dont vous accédez à la méthode:
Teacher teacher = new Teacher();
Person person = (Person)teacher;
teacher.ShowInfo(); // Prints 'I am a teacher!'
person.ShowInfo(); // Prints 'I am a person!'
Ce comportement peut être souhaité, mais dans votre cas, il est trompeur.
J'espère que cela rend les choses plus claires à comprendre pour vous!