You now know about the fundamental object-oriented concepts of encapsulation, abstraction and inheritance. It is time to focus on an equally important concept, polymorphism. Generally, polymorphism allows one piece of code to adapt automatically to the different types of data it might encounter. It is an important concept, since it makes it possible to move towards generic code; code that is written in unified way for different types of data. To introduce the concept of polymorphism more concretely, let's start with an example. Suppose that we wish to program a game that features the characters from the hierarchy we have already used in the previous episodes. Suppose that our game features a main character which would be the player. And that in one turn in the game, this character faces encounters, that is, it will meet with a whole set of other characters. The set of characters could be represented in the following way in C++: a vector of Personnage (TN: "personnage" means "character"), which would be the <i>autres</i> (TN: means "others"). And to write the code that would make the others meet the player, a for loop like this, for example, where each of the other characters meet our player in turn. So that our game doesn't become too monotonous, we would of course like to have, in the collection of other characters, characters of various natures, of various types. meaning that here, in this perso variable, we would have, alternately, a warrior, a thief, or a wizard. We also know, from a previous episode, that a subclass can have its own, more specific definition of a method already defined higher up. For example, we could imagine that when the thief meets the character, he steals from him. Polymorphism consists in applying the same code to objects taking different forms and having the execution adapt automatically to the form of the object. This means, concretely, that if at a certain moment our character is of type Voleur (TN: means "Thief"), the rencontrer (TN: means "to meet") method will be chosen to be the thief's one, who will thus rob our character without further ado. The idea is that thanks to inheritance, the same code can apply to any type of character possible. All these forms of characters have a rencontrer method allowing the way that a character meets another to take on different forms, meaning, effectively, that a magician can greet a character, a warrior can hit him, a thief can rob him and so on. And thanks to polymorphism, the same code, when applied to different characters, will be able to have a different behavior specific to each of them. In other words, if I put a Voleur (= 'Thief') in a Personnage (='Character'), in a polymorphic context, the rencontrer method would adapt automatically to the real nature of the object contained in the Personnage-type variable and so here, we would use the rencontrer method of the thief. The point of manipulating a thief as a generic character and not directly in the form of a thief is to be able to make unified manipulations on all sorts of objects. You have an example of this here where a whole set of characters of different natures are manipulated in the same way by being placed in an array of characters (Personnage). This supposes that at one point, I added to my collection of characters different characters of various natures, i.e that I carried out manipulations such as these For example, if I have an object of type Guerrier (TN: means "warrior") and an object of type Sorcier (TN: means "sorceror") then I will have filled my array of characters by doing something like this, for example. That is, since the cells of my array are of type Personnage, we have put an object of type Guerrier in a Personnage variable. Small reminder on inheritance: assigning a Guerrier to a Personnage is completely valid. In a class hierarchy, the subclass inherits from the superclass not only the member variables and methods but also the type. Guerrier is also a Personnage and so, this assignment is completely valid. Remember also that inheritance in transitive, meaning that I can also assign a Sorcier to a Personnage. Why? Because since inheritance is transitive, a Sorcier is also a Magicien which is a Personnage itself. The Sorcier is also a Personnage. We can thus assign to an object of the superclass type an object of subclass type. We see an example of this here in this assignment. This possibility also applies when passing parameters, as we will see in an example on the next slide. Here, we suppose that there exists a class hierarchy as described in the previous example. A programmer who uses this class hierarchy has defined a <i>faire_rencontrer</i> function (TN: means "make meet") which allows a character to meet another. This <i>faire_rencontrer</i> function is used in this main program and it is passed, as arguments, a first character who is a warrior and a second character who is a thief. This is to show that we can indeed put a Guerrier in a Personnage or a Voleur in a Personnage when passing parameters. Putting an object of the subclass type in a variable of the superclass type is allowed both in the context of assignment and in the context of passing parameters. This is due to the fact that in an inheritance relationship, a Guerrier is a Personnage. Somewhat more formally then, polymorphism allows instances of a subclass to substitute for instances of their parent classes, of their superclasses, whether they are arguments of a method or during assignment -- as we have just seen in the previous slides -- while keeping their own properties. In this example, the idea would thus be to put a Voleur in a Personnage while guaranteeing that the execution of the <i>rencontrer</i> method will adapt automatically to the real nature of the instance contained in the Personnage variable, meaning that we would apply the <i>rencontrer</i> method of Voleur. The fact that we can assign a thief to a character variable is a direct consequence of inheritance. However, the fact that the method to invoke is chosen at execution time depending on the real nature of the instances depends on what is known as dynamic binding. Let's see what this really is. To do so, let's return to our previous example where we substituted an object of the subclass type for an instance of the superclass type. We put a Guerrier in a Personnage which is the parameter of the <i>faire_rencontrer</i> method and we call the <i>rencontrer</i> method on the Personnage concerned. Here, we are in the context where our class hierarchy would have two rencontrer methods. One defined in the superclass which is the default method, the general method, and one that is specific to warriors, in the Guerrier subclass. Which of these two rencontrer methods will be called here? Looking closer, we can see that there are two possible points of view. The first consists in saying that the parameter is of type Personnage, so we will fetch the <i>rencontrer</i> method in the Personnage class. The second consists in saying that we put a Guerrier in Personnage, and so it is the Guerrier class that we will go and fetch the <i>rencontrer</i> method. There is thus a point of view which says that it is the type of the variable that determines the choice of methods, and a second point of view that says that it is the actual type of the object contained in the variable that determines the choice of methods. In C++, if we do nothing special, it is the type of the variable that will determine which method to execute. We use what is known as static binding meaning that here, it is Personnage's <i>rencontrer</i> method that will be called. We speak of static binding because the choice of methods can be made statically, before the program is even executed, during compilation. At that stage, we can already know which type a variable has and based on this type, choose which method to apply. In some cases however, it can be more natural to resort to another type of binding, known as dynamic binding. With this, the method will be chosen during execution, dynamically, based on the type of the object actually contained in the variable, meaning that here, we could make sure that the <i>rencontrer</i> method is the one belonging to the object that is actually stored in the Personnage-type variable. Static binding is what is used by default in C++ if we do nothing special. However, it is possible to use dynamic binding but for that, we need to use two specific ingredients. The first is that methods for which we want to use dynamic binding must be declared with a specific label, they must be virtual methods and they must be able to apply to the real instances of the objects via references or pointers. Our small initial example thus uses static binding here. In order to use dynamic binding, the <i>rencontrer</i> method has to be virtual, and should apply not to an object but to a reference of this object, or to a pointer to this object. This is not the case here; we do indeed have static binding. Virtual methods and their use via references and pointers will be the subject of the next episode.