public class InheritanceCompositionChallenge {
private static int result;
public static void main(String... doYourBest) {
Character homer = new Homer();
homer.drink();
new Character().drink();
((Homer)homer).strangleBart();
Character character = new Character();
System.out.println(result);
((Homer)character).strangleBart();
}
static class Character {
Character() {
result++;
}
void drink() {
System.out.println("Drink");
}
}
static class Homer extends Character {
Lung lung = new Lung();
void strangleBart() {
System.out.println("Why you little!");
}
void drink() {
System.out.println("Drink beer");
lung.damageLungs();
}
}
static class Lung {
void damageLungs() {
System.out.println("Soon you will need a transplant");
}
}
}
Which is the output after running the main method?
A)
Drink
Drink
Why you little!
2
Exception in thread "main" java.lang.ClassCastException:....
B)
Drink beer
Soon you will need a transplant
Drink
Why you little!
Exception in thread "main" java.lang.ClassCastException:....
C)
Drink beer
Soon you will need a transplant
Drink
Why you little!
3
Exception in thread "main" java.lang.ClassCastException:....
D)
Drink beer
Soon you will need a transplant
Drink
Why you little!
2
Why you little!
What just happened?
The correct output from the inheritance challenge is C:
Drink beer
Soon you will need a transplant
Drink
Why you little!
3
Exception in thread "main" java.lang.ClassCastException:....
To understand why, simply examine the code, starting from the top:
Character homer = new Homer();
homer.drink();
Since we instantiate the object with Homer, the Homer method implementation will be executed, producing the following output:
Drink beer
Soon you will need a transplant
Then, we invoke the drink()
method directly from the Character
class.
new Character().drink();
We will have the following output:
Drink beer
At this line we use casting and invoke the strangleBart()
method normally:
((Homer)homer).strangleBart();
Then we ask for the resulting output:
System.out.println(result);
Since we know the super
constructor always has to be invoked, we just have to count how many times Character
or Homer
was instantiated. Now we know the output will be 3
.
Finally, we try to invoke a method from a misused casting:
((Homer) character).strangleBart();
We tried to convert the class type and implementation of Character
, so a ClassCastException
will be thrown. (This is because there is no Homer
information in the Character
class.)
Video challenge! Debugging the Java inheritance example
Debugging is one of the easiest ways to fully absorb programming concepts while also improving your code. In this video you can follow along while I debug and explain the Java inheritance challenge.
Common mistakes with inheritance
- Writing inheritance code before thinking it through carefully.
- Using inheritance when composition is a better option.
- Not taking advantage of polymorphism when using inheritance.
- Using inheritance when the "is a" test doesn't pass.
What to remember about Java inheritance
- When instantiating a superclass with the subclass, the subclass instantiation will be considered.
- In order to decide whether to use inheritance, ask yourself whether the child class really is a specialized type of the parent (the "is a" test).
- The
super
reserved word will be added automatically in your constructor if you don't declare it yourself. - If you have the parent class type and the instantiation of the subclass for this type, you may cast it to the subclass.
- If the superclass has a constructor receiving at least one parameter, you must invoke this
super
constructor in the subclass passing the required parameter.
Learn more about Java
- Get more quick code tips: Read all of Rafael's articles in the InfoWorld Java Challengers series.
- See the Java 101 Java inheritance tutorial for a complete introduction to using the
extends
keyword andObject
superclass in Java programs. - See "Java tip: Inheritance relationships in JPA and Hibernate" for a quick guide to choosing a Java inheritance strategy that supports data persistence.
- If you liked debugging Java inheritance, check out other videos in Rafael's Java Challengers video playlist.
- Find even more Java Challengers on Rafael's Java Challengers blog and in his book, with more than 70 code challenges.
This story, "Java inheritance vs. composition: How to choose" was originally published by JavaWorld.