Java 18 Polymorphism

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
hello welcome back in this segment we're going to talk about polymorphism in Java and I'm reluctant to start this discussion by saying this word because everybody looks at it and thinks that's nothing that they can relate to and freak out so don't think about that word it is the title of the segment and I'll explain that word again only at the end when we already know what it really does so let's start out by reviewing where we were a couple of segments ago we were talking about the inheritance hierarchy where we decided that a dog is our animal and other things could be an animal so this is is a and this is the inheritance relationship between classes so the dog class extends the animal class and we'll go back and look at the code for for the dog and the animal and we'll add the cat class so that we actually have a hierarchy okay now here's the Declaration of a reference variable to something that to something of type dog and we can make an instance of the dog class and assign it to that reference variable and here's a reference variable of type cat and creation of a new cat object and also similarly an animal now this is the part that's new a dog is an animal so this assignment is valid the datatype of the pet variable is animal because a dog is animal we can assign dog to the variable pet similarly we could assign the a cat object to the variable whose data type is is is animal because a cat is an animal we can assign a cat object to an animal reference variable and what couldn't we do well we can't assign something that isn't an animal to that reference variable so this is the first step in understanding polymorphism that word that I wasn't going to say I want us to go right away to the code and let's go back and forth between the slides and the code so that you don't get lost in the abstract concepts of it okay so here we are and this is the code that we had before for an animal and the animal class extends object we can take that out now because we know that if we don't put extends there that the parent class is object and we can also take this out Java puts it in there for us this is a call to the object constructor method and as soon as you understand that Java puts it there people don't bother anymore so this is a very simple class it has one instance variable to weight one constructor an accessor and mutator and a two string method and with then we made the dog class and the dog extends animal that's the dog is our animal relationship and we noticed that a dog has a name to make a dog you pass in the weight and the name immediately call the constructor of the parent class an access err and a mutator for the name variable and a two string method that calls the parents two string method I added a cat class using exactly the same format so a cat has a name as well and it also has a variable called neutered so an instance of the cat class could be neutered true or neutered false so here's what it takes to make a cat you passing the weight the name of the cat and true or false if the cats neutered or not called the parent constructor which is a call to the animal constructor you might notice that the all of this is the same except the accessor for neutered instead of get neutered we're going to call that is neutered so we could say if my cat dot is neutered and it would return true or false so there's a light difference in the naming convention for boolean instance variables the rest of this is the same so none of this is surprising but I would like you to enter this class as you go along so that you can play with the relationships between cat animal and dog animals so this would be a good place to pause and enter the cat class into your code now let's go to the test inheritance and this is the same we had before we made an object of type dog and we changed its name we changed its weight and we printed out the dog Max is the most common name for a dog in the United States I you never know what you're going to learn in these videos let's make a cat what does it take to make a cat do you remember the weight the name and whether he's neutered or not I'll say that fluffy is neutered and let's clean out the cat just to make sure that we have what we want okay here's fluffy a space would have helped there neutered is true and fluffy is an animal weighing 12 12 okay I'm gonna go and find out why I'm printing out the weight twice that would probably be in animal nope oh I was demonstrating in the previous one that we could call the constructors that were inherited I mean the methods that were inherited including get weight so that's probably also in the dog class and there it is we don't need to print out the weight because we did that work in the parent to string methods okay so build and test that makes more sense now okay so we've demonstrated making a dog and making a cat and we made an animal and now we want to look at if we declare a reference variable of type pet we can say pet gets what can be assigned they're an object that is a dog an object that is a cat an object that is an animal so let's say fluffy fluffy is an object of type cat and it can be assigned to a reference variable of animal you might notice that the opposite is not true if you had a reference variable of type cat you could not assign an animal do we have an animal around anymore my pet and this won't compile you would have to say that an animal is a cat and that doesn't make sense but you can say that a cat is an animal that one does make sense I'm going to take that out now let's do system.out tip line of pet and they'll say pet gets max which is a dog system.out.print line of Max and I'm gonna go and change the no that's okay let's just run that and make sure that printing out the pet okay printing out the pet might be printing out a cat or a dog or an animal so we plant we printed out fluffy first and then max that's let's take this in very small steps this is the first step you can have a reference variable of a parent class and assign an object of one of the subclasses if you're seeing that happen then it's time to go to the next the next page okay when you assign an object to a reference variable this is the same as passing an object to a method so think of this method here we've defined a public static void foo and it takes an animal okay when you call this method what can you pass to it think of this a method signature as what does the what does the that should say method darn it what does the method want you to pass in this method wants an animal okay so I can pass it an animal can I pass it a dog or a cat yes so it's it's like an assignment when you pass something to this variable I could pass a dog or a cat so let's go and do that in the code small steps so what I did is I defined a method called foo right after the end of the main that takes an animal and this compiles and does nothing but we can demonstrate that we can compile a call to this method passing in a dog here's where the dog max is declared and a cat here's where fluffy is declared and an animal so it's the same as the assignment of fluffy to pet we have fluffy assigned to an animal reference here so passing the cat object to an animal parameter is is pretty much the same so in keep adding this to your code and it will be comfortable with for you if you if you see it working okay inside of this method I have a an animal and if I type animal dot what pops up all of the things that are available in the animal class including get wait and set wait and the things that are inherited from object one of the things that's inherited is the two string method and if I call the two string method from animal let's print that out and I'll just put a little on a note here that says I'm in fooled so we won't get it mixed up with the other outputs so my question here was who's to string method is being called if I pass in a dog who's to string method is being called and when we hover over that it seems to indicate that the animal to string method is the one that's mentioned here the one in the animal class so when I run this when I passed in a dog I wind up calling the two string method of the dog class if I pass in a cat there's that spaceman I'm calling the cat if I pass in an animal so this method call could be any of three different methods it could be the animals to string method the cat or the dog if our inheritance hierarchy were were bigger it could be a call to any of those two string methods in in the animal inheritance hierarchy so let's go back to the slides and I'll explain to you why this is happening so I want to tell you about the concept of compile-time type versus runtime type the compile time type of a variable is easy look at this declaration here animal pet pet has the data type of animal now we're going to assign that variable a dog object so when we get to this line of code the compile time type of pet is animal but at run time what kind of an animal do we actually have what kind of a thing is this right now on this line of code and at runtime the object that we have here is data type dog so when we use this object to call a method at runtime we do something called dynamic method binding and we're going to look in the dog class for the to string method so in our code when we passed a cat here then at runtime the animal is a cat but at compile time the animal is a data type animal so compile time of this variable is different from the runtime type of that variable when we hover over this and it says you're calling the animals to string be careful with that it compiles because the animal class has a two string method but at runtime it's not the animals two string method that's going to be called it's the runtime types two string method that will be called so if we passed in a dog it will be dog if we passed in a cat will be cat and so on so compile-time type and runtime type the compile time type how you declared the variable and at runtime what kind of an object do you actually have when you get there I said that about four times maybe it's monotonous but this one you have to you really have to get this one let's go back to the slides okay I kind of forgot I had this slide in here because it's the same thing that I said I already said four times so inside of the fool method we have the compile time type is animal and the run time type we don't know we don't know until someone calls it so looking at this method foo we don't even know what kind of an object we're working with we only know something about it we know that it either is an animal object or it inherits from it is an object that inherits from animal so we know something about the object that gets into this method but we don't know what kind of an object it is it might be time to start thinking about the power of this we can write a method now that takes an animal and a year later if we add the bird class to the animal hierarchy could we pass a bird to this method a bird object or an iguana object if it inherits from animal we can pass it to this method so this method could be accepting objects of a type that we haven't even thought of yet and if a year later we think of a whole bunch more animals to add to our animal hierarchy then this method will still work okay so we've got this issue inside of the method foo where the parameter data type is animal how can we find out inside of this method what kind of an animal we have so we're introducing here the instance of operator it's an operator it looks like a method call because it's a big long word but it has no capital letters in it on the left the left hand operand is a reference variable and the right hand operand is the name of a class it evaluates to a boolean so inside of this method that takes an animal we can say if my pet instance of cat and that will evaluate to true or false if the caller of the method passed in a cat it will be true if the caller passed in a dog it will be false so we can check if it's a cat and we can do some cat-like stuff here we can check if it's a dog and we can do some doglike stuff here we cannot check to see if it's something that it cannot possibly be so the instance of operator won't let you check to see if something that is our animal is a string so the compiler knows that the animal class does not inherit from string so something that is our animal cannot possibly be a string and it won't let you check that it will let you check if it's a dog because if it's a cat it would also let you check if it were an animal so my pet instance of animal would be a valid thing except it will always return true so if something is a animal instance of animal will always be true so if it's if it happens to be at run time a dog instance of animal will be true if it happens to be a cat instance of animal will also be true that seems counterintuitive but that's how the instance of operator works let's go to the code and just try that so inside of the full method we can say animal instance of cat so inside of food I'm a cat whoops and you have to spell instance correctly I and s T a and C E okay if it changes color it's probably right my typing is so bad today I'm going to do a copy-paste and ask if it's an instance of a dog in foo I'm a dog and then I'm gonna ask just to demonstrate what I said at the end of the last looking at the slide I'm an animal so let's run this and see what it does so the first time we're in foo it says I'm a dog we passed in max so this evaluates to false this evaluates to true and I'm an animal evaluates to true instance of animal evaluates to true so we can find out in here we can ask the object what it is using the instance of operator and if we type animal instance of string this will not compile animal cannot be resolved to a type let me just make sure that that's the error message that that wasn't the error message I was hoping for here's the error message incompatible conditional operand types animal and string so something whose datatype his compile-time type is animal you cannot ask if it's a string it won't compile that's that's the error message I want it so I'm just going to delete that okay the next thing we're going to look at is the override of the equals method so you know how to override the to string method the object class gives us a two string method and we say thanks but know things we want to string in our classes that make sense for our particular classes so we also inherit a method called equals and we want to override that one as well it it allows us to define when an object is equal to another object so when our two dogs equal you get to decide that by defining the equals method inside of the dog class and when we override a method remember that we have to override we have to use the signature of the method we inherit so we inherit from the object class an equals method that has the object as the parameter so here's our here's our eventual objective we're gonna go into the code in a second but this is what we want someone who's the user of the dog class to say they I want them to say max dot equals R over and it will evaluate to true or false and whether that method evaluates to true or false is up to us we define the Wells method we decide when two dogs are equal so let's go and look at doing that overriding the equals method okay so let's go into the dog class and a dog has a name and a weight first of all what we want to do I'll do it up here so it's it might be a little bit easier to see it won't go off the bottom public boolean equals and it takes an object always call my objects obj I don't know why it doesn't compile because we haven't returned anything yet okay this is how I would like the method to work the phone rings again okay so I think all dogs are equal so it would be a very good thing to do is just return true all the time this little green thing says we are overriding the equals method we if you get one of those then that's a good sign well of course I was being facetious all dogs are not equal we should compare something to make sure that they are equal before we return true so I'll declare a boolean results I'll assume that the dogs are not equal and then instead of returning true all the time I'll return the result and then in the middle we will decide what it means for two dogs to be equal well if their weights are equal and their name their names are equal then the dogs are equal we could say that we could say that if their weights are equal then they're equal so let's start out with that one let's say if the two dogs weights are equal then the result is true okay so what are the two dogs that we have to work with in here remember the expression on the slide if max dot equals R over so the two dogs Max and Rover how do we address those two dogs in here one is passed in as the object and one is this the object that gets us into the equals method so max is this and we could say this dot weight how about get weight because we're going to use the method inherited from the parent class is equal to so that would be max in the expression max dot equals R over obj is weight okay so the second dog that's passed is passed in here as obj and it doesn't compile I knew it wouldn't let's look at the error message here obj let's well darn it let's call get weight and I'll get the error message that I want it okay the method get weight is undefined for the type object what we passed in a dog someone who's calling this is going to pass in a dog and we want to call the get weight method from that dog but it won't let us because the compile time typeof obj is an object so your first inclination will be well why don't we change the data type here to dog so that that would work and we could let's try it and see what happens okay now it compiles but we lost our little green here this is not an override of the equals method that we inherited so our objective is to override the equals method that means we must put object here and then that raises a problem because the datatype object doesn't have a get weight method okay so first of all let's put up at the top a lot of people do this if obj instance of dog and now I'm going to invert the invert the logic if not return false they're not equal if you're comparing a dog to a horse they're not equal so a lot of people choose to do this at the beginning of the equals method they check to see if the object being passed in is the appropriate type if you're comparing a dog to a horse the answer is they're not equal so if not object instance of dog return false do that right at the beginning so that you will only return true ever if you have a dog object and you'll only get to this part of the code if you have a dog object so the reason I told you about that is because we have this problem down here we have an object that we know now it must be a dog but it won't compile because the compile time type of obj is object but we know that the runtime type is dog or we would have left the method up here so if we get down here what we're going to do is we're going to downcast this reference variable to be a dog so we looked at casting variables when we were working with primitives you can down cast a double to an int for example and we're going to downcast this object to be a dog so here's the cast operator it still doesn't compile but we get a different message the problem now is that the dot operator has a higher precedence than the cast operator so this syntax takes a little bit getting used to let's look at what we just did down cast the object to be a dog reference so you're telling the compiler I know that the compile time typeof obj is object but at runtime I really know I have a dog so the data type here according to the compiler the data type that's highlighted there is now a dog object and the dog object has a get weight method so now what we've done let's summarize what our equals method has done we check to see if the dog passed in the object passed in is a dog if it is then we check that the weight of this dog is equal to the weight of the dog passed in and if it is then our result will be true otherwise we'll return well will return a result in any case but we would have returned false if the weights are not the same let's go and test our equals method so I need two dogs I've got one dog here called max do I have another dog anywhere No so let's just make another dog up here here's Rover gets new dog and I'm gonna say that this dog weighs 35 and his name is over I don't know why I'm using uppercase for dogs names so what we can say now is if max dot equals Rover then I'll put a message xn r over r equal otherwise accent over our not equal so let's run that make sure it works and then we'll think about it for a minute okay max and Rover are not equal let's change the weight to 34 and run it again max and Rover are equal okay they're equal by our definition and our definition is the equals method that we put in the dog class okay let's think about it we passed in Rover who's compile-time type is dog what datatype does the equals method want well it pops up conveniently and says it wants an object is a dog an object yes everything is an object in Java except the primitives so we can pass anything into that equals method we can pass a dog and a cat and a bird and anything else we have including string a random number generator anything that is object but what we really wrote that method or is to compare to dog objects and determine if they're equal okay think about that the upcast happened implicitly we passed a dog object to a reference variable of type object we passed the dog to an object and that was an implicit upcast a reference variable upcast and inside of the equals method in the dog class we needed to do an explicit downcast so we can downcast this object to a dog it works the same way casting of variables works the same way with objects as it does with primitives and upcast happens implicitly and a downcast must be written explicitly so this is a downcast the only reason we had to do the downcast is because we were required to use the object compile type here okay so this is kind of important I there's there's something here that I guess I'll have to tell you I haven't really explained why not just use dog here and then not worry about this downcast other classes are expecting that you have overridden the equals method and when they call your equals method they will expect the data type of the parameter to be object so this is a pretty hard rule that you in your classes you should be overriding the to string method that you inherit and you should be overriding the equals method that you inherit okay let's let's look at a summary of what we've done in in this segment we talked about the compile time type versus the run time type so you satisfy the compiler first that means that the code must compile and then when it runs you can figure out what kind of an object you have at runtime and work with that the point there it was exemplified by the downcast of the dog object so we downcast the object compile time type to the dog data type and then we called the get wait method from the dog so we satisfied the compiler by doing the downcast and then we called the get wait method so that at runtime we would actually be calling a method from the dog object dynamic method binding is the concept that we looked at in this segment you call the method from the object that you actually have not from the method of the compile time class or the compile time type what we've what what we've added to our repertoire of things we can do is that we can now write methods that take different kinds of objects based on the data type of the parameter and our example was you can write a method that takes an animal and then you can pass into it anything that is an animal and you can then later on add classes that are an animal and pass them to that method and that method will still work even for data types that you hadn't considered when you wrote the method originally and I said I wouldn't use this word too much until we got to it but this is one of the definitions of polymorphism so what is polymorphism it literally it means many shapes but for me a better definition is more practical of what you can actually do and I think a better definition of polymorphism in Java is something around where you can say we can write code without even knowing exactly what kinds of objects we have and the power of that is that you can then later on pass different kinds of objects to the same method and I hate to say animal processing but you can write a method that does animal processing and then pass different kinds of animals to it we also looked at the instance of operator in this segment and you can use that to find out what kind of an object you have at runtime so what is the runtime type and we overrode the equals method and this is going to become something that you should do in every class you create create a definition of what does it mean when something equals something else so you should always be overriding the equals method and that was the first time we saw the down cast of a reference variable okay this was a lot to take in but this is an important one and we'll have an exercise on on this pretty soon I'll see you in the next video
Info
Channel: Colin Archibald
Views: 10,268
Rating: undefined out of 5
Keywords: Java, 18, Polymorphism
Id: KZS30FfM064
Channel Id: undefined
Length: 41min 20sec (2480 seconds)
Published: Tue Aug 21 2012
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.