 Polymorphism allows us to build lots of similar objects, objects that have similar features and similar operations. Most of the elements of polymorphism are actually handled by the compiler. They're really a form of abstraction that's saying, I want all of these types of data structures to have a similar set of properties. So I'm just going to inherit those automatically. The compiler would take care of making sure that each of those glasses has all of the elements that you really need in it. But the actual operation of those individual classes is determined at runtime based on the differences between them. What functions do they have available to them? Last time, we saw that we could just include a function pointer into a data structure. So we could start building our objects by adding function pointers to all of the functions that we're interested in running with this class, followed by all of the data that goes along with it. So each instance of our class might have a couple different function pointers and then a pile of data that we use. We might have some fixed functions for this class, but we can also have ones that we determine dynamically. We go, we look at the class, we see it has a pointer to this function, so I'll call that function with some of this data that it contains. But if we've got a lot of functions attached to a class, then it's probably going to be better to build an array of them. We might have an array sitting over here that contains pointers to all of the functions that are relevant to a given class. Then every instance of that class just needs to reference the table. So when I want to call one of these functions, I go to my data structure, I say, okay, the first element of my data structure tells me where that array is. So I've got a pointer, I'll dereference my pointer. It's got an array of function pointers. So I'll go find the function pointer that I'm interested in, the one that tells me about, say, function g. I will grab that function pointer out, and then I can call that function. I have to make sure I've provided all of the relevant parameters before I call the function, but that much is identical to everything we've done before. So as long as we're sure that we place the same function in the same place in the array, or we put the location of the array in the same place in our data structure, for every class, we'll always know where we can find this function. We'll know which function we want to call, even if we don't actually know what that function is. So our polymorphism has two parts. One is that we're inheriting pieces of data from our hierarchy. This is really a form of abstraction that doesn't actually require any coding. The other is that we're using function pointers to allow us to inherit functions. Before we hard-coded our functions into our code, so we always called a specific function when we got to a specific line of code, but with function pointers, we're able to choose which function we run at runtime, not at compile time. When we put all of this together, we can actually implement polymorphism.