Module 4, Interfaces for Abstraction, Topic 1.1, Polymorphism. Polymorphism is a property very commonly associated with object oriented programming. It's the ability for an object to have different forms depending on the context. Okay, so what does that mean, different forms? That could mean a lot of things, but what it typically means is you can have a function or method with one name, area. And it does one thing for one object and another thing for another type of object, okay? So for instance take area, okay? If you want to compute the area of a rectangle, that's base times height. You're going to compute the area of a triangle as one-half base times height. A function name is going to do two different things depending on the context. If you're doing it with respect to a rectangle or with respect to a triangle, so that's what polymorphism is. So you would say area is polymorphic because it can do two different things depending on the context. So another way to think about it is that these two area implementations, they are at a high level of abstraction. They're identical. What they do is they compute the area, right? No matter what the object is, if it's a rectangle or if it's a triangle, the area is what's computed. So at a high level, forgetting the detail, they do the same thing. At the low level and how they actually compute the area and they are different, right? So really polymorphism is a way of establishing an extraction. These things are the same at the high level of extraction. But underneath they're different, right? So that's what we want to allow. It's useful for a lot of reasons. So we need Golang to have some type of support for polymorphism. So what I'll first describe is how polymorphism is usually implemented in traditional object oriented languages. So one thing that is usually used in object oriented languages to support polymophism is inheritance, and Golang does not have inheritance, and so I'll just say that again, Golang does not have inheritance. Inheritance is where you get a series of classes, and they have this class, subclass, superclass relationship, or sometimes you call it parent and child class, parent class, child class. So the superclass is the top level class, and the subclass extends from the superclass. And the subclass inherits the methods and data of the superclass. So as an example, maybe I've got a speaker superclass, and a speaker is supposed to represent everything that can speak, all right? Anything that can make noises, okay, you call that that a speaker. Now, underneath speaker, a subclass of that might be cat and it might be dog right? because cats can speak. They can make noise. Dogs can make noise. So maybe I've got this subclass cat, subclass dog. Both subclasses of this superclass speaker. And cat and dog will both inherit the properties of the superclass. So my superclass speaker, let's say it has a method called speak. And that just prints out whatever noise the creature makes. So speaker, since it's generic, and the superclass, its speak method will just print out noise, arbitrary noise because it's generic. But then the subclasses cat, dog, they'll also have a speak method. They'll inherit it from the speaker superclass. So they get the same properties, they extend down. So cat and dog are different forms of speaker. And this is where the polymorphism, they're different forms of each other, this is where polymorphism concepts come into play. And remember that Go doesn't have inheritance. Now, inheritance is one thing that you use in a regular object oriented language to support polymorphism, but you also, on top of that, you're going to need another property, overriding. The ability to override a method. So a method is overridden, a subclass overrides a method when it redefines a method that it inherits from the superclass. So in the example we're talking about here, you've got the superclass speaker. And under that you've got the subclass cat and subclass dog. And speaker has this speak method and cat and dog inherit the speak method too. But without overriding the speak method, the cat speak method and the dog speak method do exactly what the superclass, what the speaker's speak method does. They just print out noise, right? Which is arbitrary. So what you want is for the cat speak method to print out meow, and the dog speaker method to print out woof. So what happens is, that's called overriding. The cat subclass will redefine the speak method to print out what it wants, meow, right? And then the dog subclass will redefine it to print out what it wants, woof. So now the speaker class, the speaker superclass, it has its speak method, and cat also the speak method, dog also the speak method. But the cat speak and the dog speak do two different things, okay? So cat and dog classes have overridden the definition of the speak method with their own new definition of the speak method. So now you can say speak is polymorphic. Because speak, it has two different implementations for each class. So speak in the context of the cat, it'll print meow. Context of the dog, it'll print woof. But the idea is to support polymorphism which you normally see in object oriented language, you see inheritance, and then you also see the ability to override a method. So both the subclasses inherit the speak method, but then they can override it and define it the way they want. And one thing to note is that they actually use the same, even though they're overriding the method, they use the same signature. So this function signature is, the method signature is the same. So this method speak, it has the same name, in both cat and dog class, it has the same arguments and the same return types. So the signature will stay the same and you'd call it polymorphic in that case. Thank you.