I'm trying to learn more about inheritance and abstract classes, and in doing so I have stumbled upon a problem. Although I know ( -or- at least think I know) how to 'fix' the problem, I would like to know what is causing it.
The problem arises as follows:
I have three classes; Character (abstract), Monster (abstract) and Goblin (concrete) - with inheritance hierarchy, Character <-- Monster <-- Goblin (parent left, child right). The (abstract) Character class declares two abstract methods fight(Character opponent) and move(int distance). These methods are implemented in the concrete class Goblin (with identical method signatures). When I try to compile the Goblin class, the compiler complains, stating that the Goblin class is not abstract and does not override the abstract method fight(adventure.Character) in the adventure.Character class.
Now to fix this, I can add an import statement (import adventure.Character .
Why do I need to do this?
Isn't the Character class imported via inheritance from the Monster class?
Code and compiler output below.
$ javac adventure/monsters/Goblin.java adventure/monsters/Goblin.java:5: adventure.monsters.Goblin is not abstract and does not override abstract method fight(adventure.Character) in adventure.Character public class Goblin extends Monster ^ 1 error
I think what is happening is that you named your class, Character. So, if you don't import it, Java is accidentally compiling it against java.lang.Character, which means that you overloaded the fight() method. This, in turn, means that you never implemented the abstract fight() method.
You have obviously worked out how to inherit correctly. Simply copying the abstract method into Monster doesn't make much difference; you get an error message about not implementing method from Monster. Look closely at the parameters for Monster; they require a Character, and you need an import to get at the Character class.
The real problem is that the Sun compiler doesn't always give good error messages.
Joined: Oct 13, 2005
. . . But I forgot about java.lang.Character. Shows how much confusion you can get by naming of things!
Joined: Sep 25, 2008
Thanks for the help guys.
What caused the confusion was the careless naming of my class 'Character'.
So, two things to note from all of this:
1. Subclasses do **not** inherit their corresponding superclass' import statements. If you want to use something outside of the local package, you must import it -- no exceptions.
2. Be careful not to name classes with existing class names from implicitly imported packages; such as java.lang.*
Changing the class name 'Character' to 'Creature' (as well as all references to Character) and importing the Creature class fixed this problem.