This tutorial demonstrates the basics of class inheritance in Java. There are three classes in three files that are used by the main method of BasicClass to demonstrate how inheritance works. BasicClass overrides the toString() method of Object, which is overriden by each of its descendants (NumberedClass and LetteredClass).
Each of the three classes also provide a method that cannot be overridden or inherited by other classes, because it is marked final. Of note is that even when a descendant is referenced as or cast to its ancestor class, the overridden methods will also be invoked, and not the originals in the ancestor.
package edu.rutgers.sakai.java.inheritance; /** * A very simple class to be extended by other classes. * * @author Robert Moore */ public class BasicClass { /** * A unique value for this object. */ protected Object value; public BasicClass(Object value){ this.value = value; } /** * Overrides {@code Object#toString()} and returns the string "Basic (?)" * instead, where ? is the String representation of this object's value. */ @Override public String toString() { return "Basic (" + this.value.toString() + ")"; } /** * Returns a string that is unique to {@code BasicClass}. This method cannot * be overridden by descendants because it is a {@code final} method. * * @return the string "Unique to Basic". */ public final String basicOnly() { return "Unique to Basic"; } /** * A main method for demonstrating inheritance using the * {@code LetteredClass} and {@code NumberedClass} classes as well as * {@code BasicClass}. * * @param args * ignored. */ public static void main(String[] args) { BasicClass basic = new BasicClass(Float.valueOf(1.4f)); NumberedClass numbered = new NumberedClass(Integer.valueOf(5)); LetteredClass lettered = new LetteredClass(Character.valueOf('F')); // We can assign an object to a reference of any of its ancestors, but // we will only // have access to the ancestor methods. BasicClass letteredBasic = lettered; BasicClass numberedBasic = numbered; // When we concatenate an object with a String, it automatically calls // toString() on the object System.out.println("B: " + basic.toString()); System.out.println("B: " + basic.basicOnly()); System.out.println(); // The next 3 lines will print out the NumberedClass.toString() value System.out.println("N: " + numbered.toString()); System.out.println("NB: " + numberedBasic.toString()); System.out.println("(B)N: " + ((BasicClass) numbered).toString()); // The basicOnly() method always comes from the BasicClass, and cannot // be overridden System.out.println("N: " + numbered.basicOnly()); System.out.println("NB: " + numberedBasic.basicOnly()); // This method only exists in the descendant (NumberedClass), so cannot // be called either by numberedBasic or a cast to a BasicClass System.out.println("N: " + numbered.descendantOnly()); System.out.println(); // The next 3 lines will print out the NumberedClass.toString() value System.out.println("L: " + lettered.toString()); System.out.println("LB: " + letteredBasic.toString()); System.out.println("(B)L: " + ((BasicClass) lettered).toString()); // The basicOnly() method always comes from the BasicClass, and cannot // be overridden System.out.println("L: " + lettered.basicOnly()); System.out.println("LB: " + letteredBasic.basicOnly()); // This method only exists in the descendant (LetteredClass), so cannot // be called either by letteredBasic or a cast to a BasicClass System.out.println("L: " + lettered.descendantOnly()); } }
package edu.rutgers.sakai.java.inheritance; /** * A simple class that keeps an integer value. {@code NumberedClass} is * a descendant of {@code BasicClass}. It overrides the {@code tostring()} method * to output the number it was created with. * @author Robert Moore * */ public class NumberedClass extends BasicClass { /** * Creates a new {@code NumberedClass} object with a specific integer value. * @param number the number to use for this object. */ public NumberedClass(final Integer number){ super(number); } /** * Returns the string "Numbered (#)", where # is the number the object was created with. * Overrides {@link BasicClass#toString()}. */ @Override public String toString(){ return "Numbered (" + this.value.toString() + ")"; } /** * Returns a string that is unique to {@code NumberedClass}. This method cannot be overridden * by descendants because it is a {@code final} method. * @return the string "Unique to Numbered". */ public final String descendantOnly(){ return "Unique to Numbered"; } }
package edu.rutgers.sakai.java.inheritance; /** * A simple class that keeps a char value. {@code LetteredClass} is * a descendant of {@code BasicClass}. It overrides the {@code tostring()} method * to output the char it was created with. * @author Robert Moore * */ public class LetteredClass extends BasicClass { /** * Creates a new {@code LetteredClass} object with a specific char value. * @param letter the char to use for this object. */ public LetteredClass(final Character letter){ super(letter); } /** * Returns the string "Lettered (?)", where ? is the char the object was created with. * Overrides {@link BasicClass#toString()}. */ @Override public String toString(){ return "Lettered (" + this.value.toString() + ")"; } /** * Returns a string that is unique to {@code LetteredClass}. This method cannot be overridden * by descendants because it is a {@code final} method. * @return the string "Unique to Lettered". */ public final String descendantOnly(){ return "Unique to Lettered"; } }