1. Créer un objet
Le processus de création d'un objet est principalement divisé en deux parties : l'allocation de mémoire et l'initialisation. Dans .NET, la zone mémoire gérée par CLR se compose principalement de trois parties : la pile, le tas GC et le tas LOH. La pile est principalement utilisée pour allouer des données de type valeur. Sa gestion est contrôlée par le système, et non par le GC comme le tas GC. Lorsque le thread termine d'exécuter la méthode de l'instance de type valeur, cet espace sera automatiquement libéré. Généralement, la pile a une efficacité d'exécution élevée mais une capacité limitée.
Le tas GC est utilisé pour allouer de petites instances d'objets. Il est entièrement contrôlé par le GC pour allouer et recycler la mémoire. Le tas LOH est préparé pour les instances d'objets volumineux. Il ne sera pas compressé et ne sera recyclé que lorsque le GC sera entièrement recyclé. Dans IL, vous pouvez voir des instructions courantes pour créer des objets tels que newobj, ldstr (création d'objets chaîne), newarr (utilisé pour allouer de nouveaux objets tableau), box (boxing), etc.
Bien sûr, les types valeur existent également sur le tas. Par exemple, lorsqu'un type valeur est utilisé comme champ d'une classe, il sera stocké dans l'espace objet de l'instance dans le tas, et lors du boxing, le type valeur existera également sur le tas. D'accord, jetons un coup d'œil à l'allocation de mémoire lors de la création d'un objet. Il existe maintenant une classe Person et une classe Student. Ensuite, cette phrase Student s = new Student() { studentId = 2, Id = 4 }; Après l'exécution, l'objet s est créé ci-dessous pour illustrer l'allocation de mémoire lors de la création d'un objet, dans laquelle l'objet s est également créé. Il existe des blocs d'index synchronisés et des pointeurs d'objets de type que je n'ai pas dessinés.
public class Person { public int Id; public void Eat() { Console.WriteLine("Eat Pear"); } } public class Student:Person { public int studentId; public void GotoSchool() { Console.WriteLine("Go to School"); } }
Afficher le code
2. L'objet de classe parent pointe vers la sous-classe
us Lors de l'écriture d'un programme, afin d'obtenir le polymorphisme, l'objet de la classe parent est généralement utilisé pour pointer vers la sous-classe. Ensuite, lorsque j'écris Person p=new Student();, un objet de sous-classe est créé dans le tas. Voici le diagramme d'allocation de mémoire de l'objet de classe parent pointant vers la sous-classe. J'ai ajouté des méthodes virtuelles et des méthodes abstraites dans Person et des méthodes remplacées dans la sous-classe Student.
Comme le montre l'image, une fois que la sous-classe remplace la méthode virtuelle ou la méthode abstraite de la classe parent, les deux méthodes de la table des méthodes Person seront remplacées par la sous-classe, et nous pouvons implémenter le polymorphisme basé sur dessus. De plus, il existe une nouvelle méthode void Eat() dans la table des méthodes Student, mais elle ne peut pas être appelée par p car new Eat() appartient actuellement à une sous-classe.
C'est-à-dire qu'à l'exception des méthodes remplacées, p ne peut appeler que des méthodes dans la table des méthodes Person. S'il ne peut pas être trouvé, il continuera à rechercher les méthodes de la classe parent Person jusqu'à l'objet. Notez qu'il ne regardera pas en arrière, il ne cherchera pas la méthode dans la table des méthodes Student
public abstract class Person { public int Id; public void Eat() { Console.WriteLine( "在吃梨"); } public virtual void Walk() { Console.WriteLine("在散步"); } //抽象方法只能在抽象类中声明,因此要在Person前加abstract,且只能声明并必须在子类中实现。 public abstract void Run(); } public class Student:Person { public int studentId; public void GotoSchool() { Console.WriteLine("Go to School"); } public new void Eat() { Console.WriteLine("学生 吃苹果"); } public override void Walk() { Console.WriteLine("学生 在散步"); } public override void Run() { Console.WriteLine("学生 在跑步"); } }
3. Pointez sur l'objet petit-enfant
maintenant j'ai ajouté une autre sous-classe James de Student. À partir de l'exemple précédent, je savais déjà que seules les méthodes réécrites par le mot-clé override seront appelées par la classe parent, j'ai donc supprimé toutes les méthodes ordinaires. Le code d'exécution est Person p = new James() { name = “James”, studentId = 2, Id = 4 }; Le code et le diagramme d'allocation de mémoire sont les suivants Afin de mettre en évidence les points clés, je n'ai pas dessiné le schéma. champs dans le diagramme. D'après les résultats, nous pouvons voir que la méthode SayHi a finalement été écrasée par la méthode SayHi du petit-enfant. De là, nous pouvons voir la transitivité de l'héritage !
public abstract class Person { public int Id; public virtual void Eat() { Console.WriteLine( "在吃梨"); } public virtual void Walk() { Console.WriteLine("在散步"); } //抽象方法只能在抽象类中声明,因此要在Person前加abstract,且只能声明并必须在子类中实现。 public abstract void Run(); public virtual void SayHi() { Console.WriteLine("人说:你好!"); } } public class Student:Person { public int studentId; public virtual void Eat() { Console.WriteLine("学生 在吃梨"); } public override void Walk() { Console.WriteLine("学生 在散步"); } public override void Run() { Console.WriteLine("学生 在跑步"); } } public class James:Student { public string name; public override void Eat() { Console.WriteLine("James 在吃梨"); } public override void Walk() { Console.WriteLine("James 在散步"); } public override void Run() { Console.WriteLine("James 在跑步"); } public override void SayHi() { Console.WriteLine("James说:你好!"); } }
Ce qui précède est le contenu de l'allocation de mémoire de base de C#. Pour plus de contenu connexe, veuillez faire attention au site Web PHP chinois (www.php.cn. )!