the compiler doesn't know or care if the object returned by the get() method will be an instance of an Animal, or an instance of some subclass of Animal when the program is actually ran. All it cares about is that it is at least an Animal
Right, is this in a way analogous to a folder system in a GUI? (I should probably stay away from using GUI as examples with this but it seemed to fit....) The highest most 'folder' (or parent class) that could work for the example is used by the compiler
Animal animal = animalList.get(i);
Within this analogy sub-folders (Sub-Classes / Child-Classes) are irrelevant to the compiler, It can sort these out after. Initially it just checks the highest level is correct, that animalList.get(i);
is an Animal. An example for a higher level class might be life form, Animal might be a lower class than life form, although I'm not sure that if LifeForm was being used and Animal was an extension of LifeForm, would Pig then be an extension of Animal? (Can you have 'nested' extensions?) Perhaps I'm wobbling a bit off topic there...
So, at "runtime", Java now knows that the object
retrieved by the get() method is not just an Animal, but a Pig. So when it
performs method calls on the animal variable, it knows to call the methods
associated to the Pig class, not the Animal class
We / The Java program will know this because we're going to use the
if(animal instanceof Pig)
Statement.... without this statement would it know? Or rather, this statement is just to enable us to return certain thing's based on what class / object is returned by the list....
So at RunTime the animal is what ever sub-class was entered by the user, cow / sheep / pig... So for example say the PigClass had a method called makeBacon(), at what point could we use
I'm assuming that this is somehow wrong, because it would be a bit odd to have all the pig's, cow's and sheep to be called 'animal'.
At compile-time, they are all variables of type: A. But at runtime, their real types are known, and the methods for their real types are used, instead of the methods for type: A.
Tell me if that makes sense.
It really does make sense, I think that I understand how the logic work's within the examples given and on a more general level. There are still some uncertainties about details though, such as the makeBacon() example above.
I'm looking at the code at the moment (for the FarmClass) and at the bottom of the createAnimal method there is the :
animalList.add(tempAnimal);
System.out.println("The " + tempAnimal.getName() + " says "
+ tempAnimal.getSound());
section. Now, we've created a new Animal with the promptUser() method.
String animal = scan.nextLine();
So that's created a new String called Animal, so it's not actually created an Animal, just a String called Animal that represents the type of animal that they would like to create. Then the promptUser() method returns this String.
So referencing the main method FarmMain we have the creation of the FarmClass with
FarmClass myFarm = new FarmClass();
Then we move into the while loop - which creates a String called userAnimal from the promptUser method.
this means that the animal String from the promptUser method is now userAnimal.
Then we use the userAnimal String variable in the if statement to validate and if user has entered break clause the program will end.
However if they have entered a correct Animal (one that we have) into the userAnimal String the program will move onto the createAnimal method. I'm a little unsure here actually with how the variable userAnimal and promptUser animal is being passed around.
In the main method the userAnimal is created from the promptUser method - so the animal String variable from promptUser is replaced by the user defined userAnimal.... But in the FarmClass our createAnimal method has an input of String Animal - this input is the animal variable from the promptUser class, that is now the userAnimal.
So - the animal variable still exists within the FarmClass - but it's value has been replaced by the value input by the user. This happens before the code from the createAnimal method is processed, so by the time the process get's to createAnimal the variable animal
is the animal that was input by the user. We can use the animal variable in the createAnimal class because it's returned by it's method.
So now we're in the createAnimal class, the user having specified which they'd like to create. We create a tempAnimal and assign it's value to null. This is because we've already used the variable animal in the class (as input) so need to have another variable that can be used within the createAnimal class. Although tempAnimal is of type Animal where as animal is a String - so hmm. So what is tempAnimal at the stage of
Animal tempAnimal = null;
It's value is null - but is it an 'animal' ? Has this in some way declared an abstract class? I know it's not with the 'new' operator, but still. So at this point is tempAnimal an Animal, and because it's abstract its value is null?
Anyway, tempAnimal is then assigned to the relevant object depending on the String input by the user in the promptUser method.
After this has been assigned (or custom error returned) we use
animalList.add(tempAnimal);
to add this newly created animal to our list....
So tempAnimal is added to the list, but because it's either a sheep, cow or pig, these are what value the list will return if say
is used... So does Java convert them as it's putting them into the list or as it's pulling them out? (Does that even matter?) I'm just curious as to whether the list is
animalList[0] = tempAnimal
animalList[1] = tempAnimal
animalList[2] = tempAnimal
animalList[3] = tempAnimal
and then when we call animalList.get(3) java pulls tempAnimal, knows that it's a sheep and presents it to us as a sheep. Or if it converts them on the way in and the list would look like
animalList(0) = pig
animalList(1) = sheep
animalList(2) = cow
animalList(3) = pig
I'm pretty sure that the nomenclatures wrong there - but I hope the point translates... If it's irrelevent then fair enough!
So that's where I think I'm at, I think that the concept of not being able to create an animal from a dog, but dog from an animal makes sense. Hopefully I've explained myself well enough to highlight any confusions though. Sorry it's a bit of an essay