Joel's Three Questions
Is it a valid Object?
Will it compile?
What will get run?
When you construct each object you do something like this:
SimpleTurtle fred = new Turtle(myWorld); //REMOVEDe 1
The first type (in this case SimpleTurtle) is called the 'static type' and the second type (in this case Turtle) is the 'dynamic type'. You don't need to memorize these terms (you may call them first/last types, left/right types, anything), but I will reference them in this description. Also when I use the term defined in the 'static type' or defined in a certain class then I mean written in the body of the code of that class.
Normally you call a method something like this:
fred.square(25); //REMOVEDe 2
So you need to ask your three questions. I'll run through them here, but I suggest you go over each one in detail using real examples. Opening up Dr. Java and writing simple classes to test would be a good idea.
1.) Is it a valid Object?
To answer this, you need to look at the constructor (REMOVEDe 1).
If any of these rules fail, then it will not compile and the error will be on REMOVEDe 1.
- Rule 1a) The 'dynamic type' must be equal to or a child of the 'static type' otherwise it will not compile.
- Rule 1b) The 'dynamic type' must have matching constructor defined or it must be defined in one of its parents. It may be defined in more then one of its ancestors.
- Rule 1c) The 'dynamic type' must not be abstract. It does not matter if the 'static type' is abstract.
2.) Will it compile?
Now look at the actual method call (REMOVEDe 2).
- Rule 2a) The method call must be defined in the 'static type' or above. It DOES NOT MATTER if it is in the 'dynamic type' or not (except with casting see rule 2b). It will not compile if the method call is not defined in the 'static type'.
- Rule 2b) You can force a method call to compile by casting it to an object that does contain this method. This is very dangerous and should only be done if you are absolutely sure that the object you are casting is eligible to be cast into that new type. You can only cast as low as the 'dynamic type' and above. If you go below the dynamic type, you will get a runtime error.
3.) What will get run?
- Rule 3a) It will run the constructor code defined in the 'dynamic type'. If the constructor not defined in the 'dynamic type' (remember according to rule 1b it doesn't have to), then it will look up the ancestry chain (starting with they 'dynamic type') until it finds a class that has the defined constructor.
- Rule 3b) It will run the method code defined in the 'dynamic type'. If the method is not defined in the 'dynamic type' (remember according to compile rule 2a it doesn't have to), then it will look up the ancestry chain (starting with they 'dynamic type') until it finds a class that has the defined method.
*It is guaranteed to find it because it is required to be in the 'static type' and the 'static type' must be equal to or higher then the 'dynamic type'
- Rule 3c) If the object is null, then you will get a NullPointerException.
*These questions were first posed and answered by Joel Uthe. If a mistake is found then they may be altered, but only with the permission of the reigning Head TA, reigning Professor, and the majority of the TA staff. All credit should be given to Joel Uthe when teaching or discussing these rules.
Link to this Page