Given:
Here is a sample problem (from Oracle mock exam):
What is the result?
A. elm elm elm elm
B. tree elm elm elm
C. tree elm tree elm
D. tree elm elm tree
E. Compilation fails.
F. An exception is thrown at runtime.
The stated answer in D, however, I would have thought B. I would have figured that the call to (new Elem().getTree())) would have return elm, not tree.
To make the explanation simple, Elm instance reuses Tree's getTree method.
When getTree is executed, the Tree's tree variable is used as this "tree" is in the Tree's class.
Generally speaking, you can have another class OakTree extends Tree. But OakTree does not have its own tree="oak" instance.
So, when OakTree calls the getTree(), it executes Tree's getTree() method. Since OakTree does not have its own tree="oak", it uses Tree's "tree".
Polymorphism does not apply to variables.
Try this modified example:
The getTree() method will print out "elm".
Why? Because when getTree is reused by Elm, it calls the overrided getmyOwnTree. When Elm's getmyOwnTree is called, it prints out "elm".
Himai Minh wrote:To make the explanation simple, Elm instance reuses Tree's getTree method.
When getTree is executed, the Tree's tree variable is used as this "tree" is in the Tree's class.
Generally speaking, you can have another class OakTree extends Tree. But OakTree does not have its own tree="oak" instance.
So, when OakTree calls the getTree(), it executes Tree's getTree() method. Since OakTree does not have its own tree="oak", it uses Tree's "tree".
Polymorphism does not apply to variables.
Try this modified example:
The getTree() method will print out "elm".
Why? Because when getTree is reused by Elm, it calls the overrided getmyOwnTree. When Elm's getmyOwnTree is called, it prints out "elm".
I actually have a question about why the third output string named tree derives the value "elm".
If I am following correctly, Elm.java starts by instantiating an Elm object and calling Elm's go method with another instantiated Tree (base class) object that is named t inside the go method. As a result, inside the go method, two objects are accessible. Both have instance variables named tree. Why does it choose to use Elm's tree variable over the Tree class' tree variable?
Is it because referencing only the word tree is like saying this.tree? Whereas to maybe access Tree's tree variable would require a qualifier such as super.tree or t.tree? Thanks for bringing up the original question.
In the previous example, it prints out tree elm elm elm from the go method.
The first one outputs tree from the invocation t.getTree().
Since t is a tree, it calls getTree and getTree calls getmyOwnTree.
The most interesting invocation is new Elm().getTree().
The Elm instances inherits getTree. This getTree calls getmyOwnTree of Elm's version.
In the Elm's getmyOwnTree, the "return tree" returns the Elm's tree.
Why getmyOwnTree in Elm choose "elm" to return instead of "tree" ?
It is because Elm's getmyOwnTree overrides its parent's method. That means Elm behaves differently than its parent.
Let's go back to the original example:
When Elm instance calls getTree(), it reuses its parent's getTree method. So, this Elm instance should behaves in the same way as its parent. Therefore, it returns "tree" instead of "elm".
Summary: a child inherits a method meaning that this child behaves in the same way as its parent. A child overrides a method meaning that this child behaves differently than its parents.
Himai Minh wrote:In the previous example, it prints out tree elm elm elm from the go method.
The first one outputs tree from the invocation t.getTree().
Since t is a tree, it calls getTree and getTree calls getmyOwnTree.
The most interesting invocation is new Elm().getTree().
The Elm instances inherits getTree. This getTree calls getmyOwnTree of Elm's version.
In the Elm's getmyOwnTree, the "return tree" returns the Elm's tree.
Why getmyOwnTree in Elm choose "elm" to return instead of "tree" ?
It is because Elm's getmyOwnTree overrides its parent's method. That means Elm behaves differently than its parent.
Let's go back to the original example:
When Elm instance calls getTree(), it reuses its parent's getTree method. So, this Elm instance should behaves in the same way as its parent. Therefore, it returns "tree" instead of "elm".
Summary: a child inherits a method meaning that this child behaves in the same way as its parent. A child overrides a method meaning that this child behaves differently than its parents.
That is a good way to describe it. I guess I get confused because even though Elm is a superclass of tree, I see it that when you create an instance of Elm, there is only one object created (an Elm instance), and so there is only one method of getTree(), which seems to 'belong' to Elem since it was inherited. So only if Elm provided an overridden verison of getTree() would it return tree="elm", but since it did not override it, it would call the parent class.
In the original example - the third output string +tree+ produced "elm ".
So did this produce "elm " because:
The go method was called using an Elm object, and the Elm object's tree variable was set to "elm "? Is that why the third string produced "elm "?