Easy to Learn Java: Programming Articles, Examples and Tips

Start with Java in a few days with Java Lessons or Lectures


Code Examples

Java Tools

More Java Tools!

Java Forum

All Java Tips


Submit News
Search the site here...
Search the JavaFAQ.nu
1000 Java Tips ebook

1000 Java Tips - Click here for the high resolution copy!1000 Java Tips - Click here for the high resolution copy!

Java Screensaver, take it here

Free "1000 Java Tips" eBook is here! It is huge collection of big and small Java programming articles and tips. Please take your copy here.

Take your copy of free "Java Technology Screensaver"!.

Easy Java Lecture 13-2 Inheritance in Java. Teach/learn online

JavaFAQ Home » Java Lectures by Anatoliy Malyarenko Go to all tips in Java Lectures by Anatoliy Malyarenko

Bookmark and Share


by: Anatoliy Malyarenko


  • Contents of the lecture.
  • Understanding inheritance.
  • Overriding methods.
  • Being a descendent of Object.
  • Writing final classes and methods.
  • Writing abstract classes and methods.
  • Implementing nested classes.

Managing inheritance

Recall that the extends clause declares that your class is a subclass of another. You can specify only one superclass for your class (Java does not support multiple class inheritance), and even though you can omit the extends clause from your class declaration, your class has a superclass. So, every class in Java has one and only one immediate superclass. This statement leads to the question, "Where does it all begin?"

As depicted in the following figure, the top-most class, the class from which all other classes are derived, is the Object class defined in java.lang.

The Object class defines and implements behaviour that every class in the Java system needs. It is the most general of all classes. Its immediate subclasses, and other classes near top of the hierarchy, implement general behaviour; classes near the bottom of the hierarchy provide for more specialised behaviour.

Definition 1. A subclass is a class that extends another class. A subclass inherits state and behaviour from all of its ancestors. The term "superclass" refers to a class's direct ancestor as well as to all of its ascendant classes.

What members does a superclass inherit?

A subclass inherits all of the members in its superclass that are accessible to that subclass unless the subclass explicitly hides a member variable or overrides a method. Note that constructors are not members and are not inherited by subclasses. The following list itemises the members that are inherited by a subclass:

  • Subclasses inherit those superclass members declared as public or protected.
  • Subclasses inherit those superclass members declared with no access specifier as long as the subclass is in the same package as the superclass.
  • Subclasses don't inherit a superclass's member if the subclass declares a member with the same name. In the case of member variables, the member variable in the subclass hides the one in the superclass. In the case of methods, the method in the subclass overrides the one in the superclass.

Creating a subclass can be as simple as including the extends clause in your class declaration.

However, you usually have to make other provisions in your code when subclassing a class, such as overriding methods or providing implementations for abstract methods.

Hiding member variables

As mentioned before, member variables defined in the subclass hide member variables that have the same name in the superclass.

One interesting feature of Java member variables is that a class can access a hidden member variable through its superclass. Consider the following superclass and subclass pair:


class Super {
    Number aNumber;
class Subbie extends Super {
    Float aNumber;

The aNumber variable in Subbie hides aNumber in Super. But you can access Super's aNumber from Subbie with



super is a Java language keyword that allows a method to refer to hidden variables and overridden methods of the superclass.

Overriding methods

The ability of a subclass to override a method in its superclass allows a class to inherit from a superclass whose behaviour is "close enough" and then override methods as needed.

For example, all classes are descendants of the Object class. Object contains the toString method, which returns a String object containing the name of the object's class and its hash code. Most, if not all, classes will want to override this method and print out something meaningful for that class.

Let's resurrect the Stack class example and override the toString method. The output of toString should be a textual representation of the object. For the Stack class, a list of the items in the stack would be appropriate.


public class Stack {
   private Vector items;
   // code for Stack's methods and constructor
   //not shown
   // overrides Object's toString method

   public String toString() {
      int n = items.size();
      StringBuffer result = new StringBuffer();
      for (int i = 0; i < n; i++) {
         if (i < n-1) result.append(",");
      return result.toString();

The return type, method name, and number and type of the parameters for the overriding method must match those in the overridden method. The overriding method can have a different throws clause as long as it doesn't declare any types not declared by the throws clause in the overridden method.

Also, the access specifier for the overriding method can allow more access than the overridden method, but not less. For example, a protected method in the superclass can be made public but not private.

Calling the overridden method

Sometimes, you don't want to completely override a method. Rather, you want to add more functionality to it. To do this, simply call the overridden method using the super keyword.
For example,



Methods a subclass cannot override

A subclass cannot override methods that are declared final in the superclass (by definition, final methods cannot be overridden). If you attempt to override a final method, the compiler displays an error message similar to the following and refuses to compile the program:

FinalTest.java:7: Final methods can't be overridden.
Method void iamfinal() is final in class ClassWithFinalMethod.
void iamfinal() {
1 error

Also, a subclass cannot override methods that are declared static in the superclass. In other words, a subclass cannot override a class method. A subclass can hide a static method in the superclass by declaring a static method in the subclass with the same signature as the static method in the superclass.

Being a descendent of Object

The Object class sits at the top of the class hierarchy tree in the Java platform. Every class in the Java system is a descendent, direct or indirect, of the Object class. This class defines the basic state and behaviour that all objects must have, such as the ability to compare oneself to another object, to convert to a string, to wait on a condition variable, to notify other objects that a condition variable has changed, and to return the class of the object.

Your classes may want to override the following Object methods. The equals/hashCode are listed together as they must be overridden together.

  • clone
  • equals/hashCode
  • finalize
  • toString

Your class cannot override these Object methods (they are final):

  • getClass
  • notify
  • notifyAll
  • wait

The clone method

You use the clone method to create an object from an existing object. To create a clone, you write:



Object's implementation of this method checks to see if the object on which clone was invoked implements the Cloneable interface, and throws a CloneNotSupportedException if it does not. Note that Object itself does not implement Cloneable, so subclasses of Object that don't explicitly implement the interface are not cloneable.

If the object on which clone was invoked does implement the Cloneable interface, Object's implementation of the clone method creates an object of the same type as the original object and initialises the new object's member variables to have the same values as the original object's corresponding member variables.

The simplest way to make your class cloneable then, is to add implements Cloneable to your class's declaration. For some classes the default behaviour of Object's clone method works just fine. Other classes need to override clone to get correct behaviour.

Consider the Stack class, which contains a member variable that refers to a Vector. If Stack relies on Object's implementation of clone, then the original stack and its clone will refer to the same vector. Changing one stack will change the other, which is undesirable behaviour.

Here then is an appropriate implementation of clone for our Stack class, which clones the vector to ensure that the original stack and its clone do not refer to the same vector (changes are indicated with a change in font):


public class Stack implements Cloneable {
   private Vector items;
   // code for Stack's methods and constructor not shown

   protected Object clone() {
      try {
         Stack s = (Stack)super.clone(); // clone the stack
            s.items = (Vector)items.clone(); // clone the vector
         return s; // return the clone
      } catch (CloneNotSupportedException e) {
         // this shouldn't happen because Stack is Cloneable
         throw new InternalError();

The implementation for Stack's clone method is relatively simple: It calls super.clone, which Stack inherits from Object and which creates and initialises an instance of the correct type. At this point, the original stack and its clone refer to the same vector. Next the method clones the vector.

Be careful: clone should never use new to create the clone and should not call constructors. Instead, the method should call super.clone, which creates an object of the correct type and allows the hierarchy of superclasses to perform the copying necessary to get a proper clone.

The equals and hashCode methods

You must override the equals and hashCode methods together.
The equals method compares two objects for equality and returns true if they are equal. The equals method provided in the Object class uses the identity function to determine if objects are equal (if the objects compared are the exact same object the method returns true).

However, for some classes, two distinct objects of that type might be considered equal if they contain the same information. Consider this code that tests two Integers, one and anotherOne, for equality:


Integer one = new Integer(1);
anotherOne = new Integer(1);

if (one.equals(anotherOne))
    System.out.println("objects are equal");

This program displays objects are equal even though one and anotherOne reference two distinct objects. They are considered equal because the objects compared contain the same integer value.

Your classes should only override the equals method if the identity function is not appropriate for your class. If you override equals, then override hashCode as well.

The value returned by hashCode is an int that maps an object into a bucket in a hash table. An object must always produce the same hash code. However, objects can share hash codes (they aren't necessarily unique). Writing a "correct" hashing function is easy -- always return the same hash code for the same object. Writing an "efficient" hashing function, one that provides a sufficient distribution of objects over the buckets, is difficult.

Even so, the hashing function for some classes is relatively obvious. For example, an obvious hash code for an Integer object is its integer value.

The finalize method

The Object class provides a method, finalize, that cleans up an object before it is garbage collected. This method's role during garbage collection was discussed previously. The finalize method is called automatically by the system and most classes you write do
not need to override it. So you can generally ignore this method.

The toString method

Object's toString method returns a String representation of the object. You can use toString along with System.out.println to display a text representation of an object, such as the current thread:



The String representation for an object depends entirely on the object. The String representation of an Integer object is the integer value displayed as text. The String representation of a Thread object contains various attributes about the thread, such as its name and priority. For example, the previous line of code displays the following output:


The toString method is very useful for debugging. It behooves you to override this method in all your classes.

The getClass method

The getClass method is a final method that returns a runtime representation of the class of an object. This method returns a Class object.

Once you have a Class object you can query it for various information about the class, such as its name, its superclass, and the names of the interfaces that it implements. The following method gets and displays the class name of an object:


void PrintClassName(Object obj) {
   System.out.println("The Object's class is " +

One handy use of a Class object is to create a new instance of a class without knowing what the class is at compile time. The following sample method creates a new instance of the same class as obj, which can be any class that inherits from Object (which means that it could be any class):


Object createNewInstanceOf(Object obj) {
    return obj.getClass().newInstance();

Part II continues here...

 Printer Friendly Page  Printer Friendly Page
 Send to a Friend  Send to a Friend

.. Bookmark and Share

Search here again if you need more info!
Custom Search

Home Code Examples Java Forum All Java Tips Books Submit News, Code... Search... Offshore Software Tech Doodling

RSS feed Java FAQ RSS feed Java FAQ News     

    RSS feed Java Forums RSS feed Java Forums

All logos and trademarks in this site are property of their respective owner. The comments are property of their posters, all the rest 1999-2006 by Java FAQs Daily Tips.

Interactive software released under GNU GPL, Code Credits, Privacy Policy