Inheritance

allows a software developer to derive a new class from an existing one.

 

All Java Objects automatically inherit methods from Object

 

All objects have Object as a superclass.

 

    

Object Methods

Action

equals()

returns true if and only if both object references point to the same object

finalize()

Called by the garbage collector on an object when garbage collection determines that there are no more references to the object.

getClass()

Returns the runtime class of an object

hashCode()

Returns a hash code value for the object

notify()

Wakes up a single thread that is waiting on this object

notifyAll()

Wakes up all threads that are waiting on this object

toString()

Returns a string representation of the object.

wait()

Causes current thread to wait until another thread invokes the notify() method or the notifyAll() method for this object.

wait(long timeout)

Causes current thread to wait until either another thread invokes the notify() method or the notifyAll() method for this object, or a specified amount of time has elapsed.

 

 

 

Example:  Object used in a program

 

public class ObjectTest

{ 

    public static void main (String [] args)

    {

        Object obj1, obj2;

        obj1 = new Object();                  

        obj2 = new Object();

        if (obj1.equals(obj2))                

            System.out.println(" obj1 equals obj2 ");

        else

            System.out.println(" obj1 not equal to obj2 "); // not equal

       

        System.out.println(obj1);              // java.lang.Object@feea60f7

        System.out.println(obj2);              // java.lang.Object@feea6100

        System.out.println(obj1.getClass());   // class java.lang.Object

       

        String str1 = new String("CSC212");   

        String str2 = new String("CSC212");

        if (str1.equals(str2))                  

            System.out.println(" str1 equals str2 "); // equals

        else

            System.out.println("str1 not equal to str2 ");

        System.out.println(str1);              // CSC212

        System.out.println(str2);              // CSC212

        System.out.println(str1.getClass());   // class java.lang.String

        }

}

 

 

Inheritance Class Hierarchies

 

                Inherited attributes and methods are passed down from parent to child.

            A class can only have one parent.

            A parent can have one or more children.

            When a child becomes a parent, its children will receive all the capabilities

                        of the parent

                        and the parent’s parents. 

This chain continues until the root Object.

           

           

 

           

                                                                                                                                                                                                                         

The parent class has properties common to all subclasses.

 

The child inherits everything from the parent

 

The child can have additional methods and attributes to handle more specialized situations.

 

During the execution of a program, the child can be used in place of the parent (substitutability rule).

 

The parent cannot substitute for the child.

 

 

 

 

 

Superclass (a.k.a. base class, parent class)

The Person class below can be used as a superclass

 

public class Person

{

    private String name, address;

    private static int count = 0;

    private int privateID;

    protected int protectedID;

 

    public Person(String aName, String anAddress)   // constructor

    {

        name = aName;

        address = anAddress;

        count++;

        privateID = protectedID = count;

    }

      

    public void nameAndAddress() 

    {

        System.out.println(name + " " + address);   

    }

    public int getPrivateID() {return privateID;}

    public int getProtectedID() {return protectedID;}

    public static int getCount() {return count;}

}

 

 

 

Subclass  (a.k.a. derived class, extended class, child class)

 

            The subclass gets all the capabilities of the superclass

by using the extends keyword

 

 

Creating a subclass

 

public class Employee extends Person {}

 

·        Employee can do everything a Person can do.

·        Employee can also do everything an Object can do.

 

 

 

Subclasses and the use of extends and super keywords

 

public class Employee extends Person

{

    private static int count = 0; // count “hides” count of Person

    private String occupation;

    private int ID;

 

    public Employee(String aName, String anAddress, String occupation)

    {

        super(aName, anAddress);

        this.occupation = occupation;

        ID = ++count;       

    }

    public void job()  {System.out.println(occupation); }

    public int getID() {return ID; }

    public static int getCount() {return count;}

}

 

 

super reference to a constructor

 

Constructors are NEVER inherited, and they have no return type.

When a subclass is created, the constructor of the class extended is called first. 

 

When the superclass constructor requires parameters, use a super reference for the constructor.

 

 

 

Usage of Employee and Person classes

 

 

public class TestPerson

{

 

    public static void main(String [] args) {

 

        Person aPerson = new Person("John", "Chicago");   

        aPerson.nameAndAddress();                  // John Chicago    

        System.out.println(aPerson.getPrivateID()); // 1

        System.out.println(aPerson.getProtectedID());// 1

        // Person has all the capabilities of an Object

        System.out.println(aPerson);           // Person@ff14a83f          

        System.out.println(aPerson.getClass());// class Person

  

 

        Employee anEmployee = new Employee("Jim","Skokie","Programmer"); 

 

        // Employee has all the capabilities of person and Object

        anEmployee.nameAndAddress();               // Jim Skokie

        System.out.println(anEmployee.getPrivateID());  // 2

        System.out.println(anEmployee.getProtectedID());// 2

        System.out.println(anEmployee);            // Employee@ff14bc9b

        System.out.println(anEmployee.getClass()); // class Employee

 

 

        if (aPerson.equals(anEmployee))            // NOT the same            

            System.out.println(" the same");

        else

            System.out.println(" NOT the same");

 

        // employee also has its own methods

        anEmployee.job();                       // Programmer

   

        // Employee class has a static method.

        System.out.println(anEmployee.getCount()); // 1

 

        // Person class has a static method.

        System.out.println(aPerson.getCount());    // 2

      

    }

}

 

 

Override

 

occurs when a class redefines a method that was implemented in a parent class.

 

 

 

 

Override those inherited methods that do not work the way they should.

 

Implement a method with the same signature as the parent.

 

Notes: The access modifier can be kept the same or strengthened (but not weakened)

The return type does not have to be the same as the method overridden.

           

 

 

 

Override example and use of super:

 

public class Person

{

    private String name, address;

    public Person() {  // constructor

        name = "John";

        address = "Chicago";

    }

    public String nameAndAddress()  {

        return (name + " " + address);   

    }

}

 

public class Employee extends Person 

{

private String occupation;

    public Employee(String occupation)

    {

        this.occupation = occupation;

    }

    public String nameAndAddress() 

    {

        String result = super.nameAndAddress();  

   // super is an invocation of parent method 

        result += occupation;

        return result;

    }

 }

 

 

public class TestPerson

{

    public static void main(String [] args)

   {

          Person   x = new Person();

          Employee y = new Employee(" Programmer");

          x.nameAndAddress();       // John Chicago

          y.nameAndAddress();       // John Chicago Programmer

          // invokes overridden method in Employee

          // not the method in Person

         }

     }

 

 

 

 

 

Frequently overridden methods of Object

 

 

 

            equals()           Modified to return true if both references refer to the same type of object

                                    and the objects have selected content which is identical 

                                    The equals() method is called by Java methods which search for identical objects.         

 

            toString()        Modified to return content from the selected object

                                    The toString() method is invoked by (System.out.println(Object));.

 

 

 

 

 

Substitution principle  -- An object of a subclass can be used wherever the parent is used.

 

 

 

public class TestPerson2

{

    public static void main(String [] args)

    {

        Employee emp1 = new Employee("Jack","Summit","Programmer");

        Employee emp2 = new Employee("Casey", "Oak Brook", "Systems Analyst");

        Person   per1 = new Person("Pete","Schaumberg" );

        Person   per2 = new Person("Mark", "Park Ridge");

 

        // a form of polymorphism -- subclass can be used where its superclass is used

        per1 = emp1;  // will compile substitute child for parent

 

        // the parent cannot subsitute for the more specialized child

        emp2 = per2;  // will not compile -- incompatible types

    }

}     

 

 

 

Subclasses do not have automatic access to all data inherited from the superclass

 

 

public class Employee extends Person {

. . .

. . .

    public void increaseProtectedID ()

    {

        protectedID++;  // allowed protected modifier in Person

 

    }

    public void increasePrivateID ()

    {

        privateID++;  // not allowed private modifier in Person

    }

}

   

 

Visibility Modifiers

 

Visibility Modifiers (least to most restrictive)

Accessible by

public

any other class

protected

any subclass or any class in the same package

no modifier

any class within the same package

private

only by the owning class

 

 

In order for the subclass to access the attributes of the parent, visibility should be protected. 

 

 

 

Visibility modifier of an override can be broadened but not weakened.

 

public class SuperClass

{

    protected int x = 1;

    protected int y = 2;

    protected int getX(){return x;}

    protected int getY(){return y;}

}

 

class SubClass extends SuperClass

{

    public  int getX(){return x + 10;}  // will compile (broaden access)

    private int getY(){return y + 10;}  // will not compile (weakened access)

}

 

 

 

 

Additional Modifiers that affect Inheritance

 

Modifer

Result

final

no subclasses can be created

abstract

No object of this class can be created

Subclasses must implement code

 

 

 
Final Classes

 

          If a class defines itself as final, then no other class can extend it.

 

public final class Manager extends Employee

{

    double salary;

}

 

public class BossOfBosses extends Manager  // will not compile

{

      public BossOfBosses() // cannot inherit from final

      }

}

 

 

 

Abstract Classes

 

         

Abstract classes contain one or more methods without an implemented procedure (abstract method)

 

When the abstract class is used for inheritance, the abstract methods act as “place holders” for concepts that should be implemented.

 

public class Person

{

    private String name, address;

    public Person(String aName, String anAddress) {  // constructor

        name = aName;

        address = anAddress;

    }

    public String getName() {return name;}

    public String getAddress() {return address;}

}

 

public abstract class Employee extends Person   // abstract class

{

    private String occupation;

 

    public Employee (String name, String address, String occupation)

    {

        super(name, address);  // super keyword invokes parent constructor

        this.occupation = occupation;

    }

    public abstract double pay();  // abstract method

 }

 

 

Although abstract classes cannot be instantiated they can be inherited by the “extends” keyword. 

          The inheriting class can then override the abstract method with code appropriate to the class.

 

public class Clerk extends Employee

{

    double hourlyRate;

    int hours;

 

    public Clerk (String name, String address,

              String employeeType, double hourlyRate,

              int hours)

   {

        super (name, address, employeeType);

        this.hourlyRate = hourlyRate;

        this.hours = hours;

    }

   public double pay()   // must implement abstract methods

   {

        double result = hourlyRate * hours;

        if (hours > 40)

            result += (hours - 40) * hourlyRate * .5;   

        return result;

    };

}

 

 

If the inheriting class does not define all its methods, then it also is an abstract class

The override for Manager pay will be different from that of the clerk

 

public class Manager extends Employee

{

    double salary;

 

    public Manager (String name,String address,

           String employeeType, double salary)

    {

        super (name, address, employeeType);

        this.salary = salary;

    }

   public double pay()   // must implement the abstract method

   {

        return salary;

   };

  }

 

The clerk and the manager each have a pay() method with a different implementation

 

import java.text.*;  

public class TestEmployee

{

  public static void main(String [] args)

  {

     NumberFormat currency = NumberFormat.getCurrencyInstance();

     Clerk clerk = new Clerk("Pete", "Burbank","Payroll Clerk", 8.50,40);

     System.out.println("This week the Payroll clerk gets paid "

                        + currency.format(clerk.pay()));

     Manager manager = new Manager("Tim", "WestWorld","PayRoll Manager", 4000.00);

     System.out.println("This month the Payroll Manager gets "

                          + currency.format(manager.pay()));

   }

}

 

          /* prints

This week the Payroll clerk gets paid $340.00

This month the Payroll Manager gets $4,000.00

*/

 

 

 

Dynamic Binding -- Super reference searches parentage for most recent version of the called method

 

public class SuperClass

{

    private   int x = 3;

    private   int y = 2;

    private   int z = 1;

    protected int getX(){return x;}

    protected int getY(){return y;}

    protected int getZ(){return z;}

}

 

 

public class SubClass extends SuperClass

{

    public int getX(){return super.getX() + 30;} // to SuperClass

    public int getY(){return super.getY() + 20;} // to SuperClass

}

 

public class SubSubClass extends SubClass

{

    public int getX(){return super.getX() + 300;} // to SubClass

 

}

 

public class TestSuperClass

{

    public static void main(String [] args)

   {

        SubSubClass ssc = new SubSubClass();

        System.out.println(ssc.getZ());     // 1

        System.out.println(ssc.getY());     // 22

        System.out.println(ssc.getX());     // 333

    }

}

 

 

 

         

Polymorphism  --

 

the characteristic of assigning different meaning or usage to something in different contexts – specifically, to allow an entity such as a variable, a function or an object to have more than one form. 

 

            Within Java, polymorphism is made possible by

1.      Overriding inherited methods.

2.      Implementing empty methods of interfaces.

         

 

 

 

Interface

 

 

interface Talk

{

  void speak();

  void echo(String s);

  final static String HI = "Hello ";

}

 

 

·        An interface defines a list of methods but does not implement them.

·        The methods have names, parameters and return type but no procedural code.

·        A class that implements an interface must implement all the methods defined in the interface.

·        An interface can be implemented by any class anywhere in the class hierarchy.

·        An interface can also declare constants (static and final).

·        All methods and constants are public

·        An interface may extend an interface.

 

 

Differences between Interface and abstract class

  • An interface cannot implement any methods, but an abstract class can.
  • An interface is not part of the class hierarchy. Unrelated classes can implement the same interface.
  • A class can implement more than one interface
  • A class can have only one superclass (there is no multiple inheritance).

 

 

 

Example of a class that Implements an Interface

 

public class Person implements Talk

{

    protected String name;

    protected String address;

 

    public Person(String name, String address)

    {

        this.name = name;

        this.address = address;

    }

    public void printName( ) {System.out.println(name);}

    public void printAddress( ) {System.out.println(address);}

 

    // when implementing an interface, be sure to define all the

    // methods in the interface

 

 public void speak() {System.out.println(HI + "I'm a Manager ");}   

 public void echo(String s) {System.out.println(s);}

}

 

 

Any class can use the interface

 

public class Dog implements Talk

{

    private String says = new String("Bow wow");

    public String toString()

    {

        return new String("I am a dog");

    }

    public void speak ()

    {

        System.out.println(says);

    }

    public void echo(String s)

    {

        System.out.println(says + " " + s);

    }

    public void bestFood()

   {

        System.out.println("Alpo");

    }

       }

 

 

 

An interface name can be used as an object reference variable

 

A reference can point to any object of any class that implements the interface

Casting can be used to reference specific methods of the containing class

 

 

public class Speakers

{

    public void instanceTest (Talk obj)

   {

        if (obj instanceof Dog) {

            Dog dog = (Dog) obj;

            dog.bestFood();

            }

        else if (obj instanceof Person) 

            ((Person) obj).printName();

    }

    public static void main(String [] args)

    {

        Speakers s1 = new Speakers();

        Person p = new Person("Jim", "Lincolnwood");

        p.speak();               // Hello I'm a Manager

        p.echo("Time to eat"); // Time to eat

        Dog d = new Dog();  

        d.speak();             // Bow wow

        d.echo("cats");        // Bow wow cats

        s1.instanceTest(p);      // Jim

        s1.instanceTest(d);      // Alpo

   }

} 

 

 

Multiple Inheritance – not allowed but Multiple interfaces are

 

A Java class can only extend one class (single inheritance) but it can implement multiple interfaces          

 

 

interface Opinion

{

  void giveOpinion();

}

 

The multiple interfaces are a comma-separated list following the implements keyword

 

public class Person implements Talk, Opinion

{

    protected String name;

    protected String address;

 

    public Person(String name, String address)

    {

        this.name = name;

        this.address = address;

    }

 public String getName( ) { return name;}

 public void speak() {System.out.println(HI + "I'm a Manager ");}   

 public void echo(String s) {System.out.println(s);}

 public void giveOpinion() { System.out.println("Thumbs up!");}

}

 

 

 

 

Interfaces can also inherit

 

interface Opinion extends Talk

{

  void giveOpinion();

}

 

 

public class Person implements Opinion

{

    protected String name;

    protected String address;

 

    public Person(String name, String address)

   {

        this.name = name;

        this.address = address;

    }

 public String getName( ) { return name;}

 public void speak() {System.out.println(HI + "I'm a Manager ");}   

 public void echo(String s) {System.out.println(s);}

 public void giveOpinion() { System.out.println("Thumbs up!");}

}

 

 

 

The Comparable  interface

 

interface Comparable

{

int compareTo(Object other);

}

 

            The Comparable interface is

      • part of the Java System – you don’t have to define one of your own.
      • called by sort routines when comparing objects.

           

 

            The compareTo method must be able to compare two objects and

return an indicator specifying which one is larger.

 

x.compareTo(y);

 

            x returns a negative number if smaller than y

            x returns a positive number if greater than y

            x return a zero if it is equal to y

 

Since the value the of the number does not matter, it is possible to compare employees by employee ID

 

public int compareTo(Object otherObject) {

      Employee other = (Employee) otherObject;

      return (ID – other.ID);

 }

 

 

The comparison could be on any fields that can be ordered – height, salary, age, etc.