3.Inheritance
Extending Classes
The keyword extends indicates that you are making a new class that derives from an existing class
The existing class is called the superclass, base class, or parent class
The new class is called subclass, derived class or child class
A subclass can add fields and it can add or override methods of the superclass
However, inheritance can never take away any fields or methods
The call using super must be the first statement in the constructor for the subclass
The super keyword has two meanings: to invoke a superclass method, and to invoke a superclass constructor
class Employee
{
public Employee(String n, double s) { ... }
public double getSalary() { ... }
}
class Manager extends Employee
{
public Manager(String n, double s, double b) {
super(n, s); // Invoke Employee's superclass constructor
}
public double getSalary() {
double baseSalary = super.getSalary();
return baseSalary + bonus;
}
}
Employee emp = new Employee("Carl", 80000);
Manager boss = new Manager("Harry", 150000);
e = emp;
e = boss;
e.getSalary(); // picks getSalary of Manager
Polymorphism
The fact that an object variable (such as the variable e) can refer to multiple actual types is called polymorphism
Automatically selecting the appropriate method at runtime is called dynamic binding
In Java, object variables are polymorphic, A variable of type Employee can refer to an object of type Employee or its any subclass (Manager)
However superclass variable e could call only superclass methods, even when it points to subclass Manager object
You cannot assign a superclass reference to a subclass variable, since subclass variable could not invoke subclass specific methods on superclass object
When you override a method, the subclass method must be at least as visible as the superclass method. In particular, if the superclass method is public, then the subclass method must also be declared as public.
It is a common error to accidentally omit the public specifier for the subclass method. Then the compiler complains that you try to supply a weaker access privilege
Preventing Inheritance: Final Classes and Methods
Classes that cannot be extended are called final classes (e.g. String class)
You can also make a specific method in a class final. No subclass can override that method
If a class is declared as final, only the methods, not the fields, are automatically final
Efficiency : Dynamic binding has more overhead than static binding, hence slower.
Safety : Full control that invoked method by base class reference would not change the behavior (by sub class method override)
final class Executive extends Manager
{
...
}
class Employee
{
public final String getName() { ... }
}
Casting
Casting is done to use an object in its full capacity after its actual type has been forgotten by variable of super class
Casting is done to invoke subclass method i.e. not present in superclass
Casts are commonly used with generic containers such as ArrayList class from Object type to specific type
You can cast only within an inheritance hierarchy
Use instanceof to check before casting from a superclass to a subclass
Compile-time error for out of inheritance hierarchy casting
Runtime error for casting superclass as subclass
Employee e1 = new Employee("Carl", 80000);
Employee e2 = new Manager("Harry", 150000);
Manager m = null;
if (e2 instanceof Manager) { \\ Check to ensure casting is done for valid case, otherwise exception could be thrown
m = (Manager) e2;
m = (Manager) e1; \\ This will throw Java runtime exception and needs to catch the exception
Date d = (Date) e1; \\ This will give Java compile-time error because Date is not a subclass of Employee
Abstract Classes
Abstract Method does not have an implementation only signature
Abstract Method are required if no default implementation is available in super class
A class with one or more abstract method must be abstract class
Abstract class cannot be instantiated, however variables could be created
Abstract class could have zero abstract methods
Abstract class could have concrete data and methods
Subclass define abstract methods
Subclass which defines all abstract methods is not abstract class
Subclass which define some (not all) abstract methods is abstract class as well
abstract class X {
public abstract show() { ... }
public String getName() { return name;}
private String name;
}
class Y extends X {...}
X x = new Y();
Protected Access
Restrict superclass method access to subclass
Allow subclass method to access superclass field
Subclass object could only access subclass object's superclass field, not of other superclass objects
clone method of Object class is good example of protected method
private - Visible to class only
public - Visible to the world
protected - Visible to all subclasses (including other packages)
default - Visible to the package. No modifiers are needed
Multiple Inheritance
When one class extends more than one classes then this is called multiple inheritance.
For example: Class C extends class A and B then this type of inheritance is known as multiple inheritance.
Java doesn’t allow multiple inheritance to prevent the ambiguity by Diamond problem
class A {}
class B {}
class C extends A,B () // Multiple inheritance is not supported in java
Diamond Problem
Suppose multiple inheritance class D extends both classes B & C
Lets assume class B & C both extend from class A and override a method in A in their own way
Because D is extending both B & C so if D wants to use the same method which method would be called (the overridden method of B or the overridden method of C).
Ambiguity. That’s the main reason why Java doesn’t support multiple inheritance.
Implement multiple interface in a class
A class can implement any number of interfaces. In this case there is no ambiguity even though both the interfaces are having same method.
Why? Because methods in an interface are always abstract by default, which doesn’t let them give their implementation (or method definition ) in interface itself.
interface X { public void myMethod(); }
interface Y { public void myMethod(); }
class JavaExample implements X, Y { public void myMethod() { System.out.println("Implementing more than one interfaces"); } public static void main(String args[]){ JavaExample obj = new JavaExample(); obj.myMethod(); } }
Interface with Default Method
Java 8 supports default methods where interfaces can provide default implementation of methods.
And a class can implement two or more interfaces.
In case both the implemented interfaces contain default methods with same method signature, the implementing class should explicitly specify which default method is to be used or it should override the default method.
If we remove implementation of default method from “TestClass”, we get compiler error.
// A simple Java program to demonstrate multiple
// inheritance through default methods.
interface PI1
{
// default method
default void show()
{
System.out.println("Default PI1");
}
}
interface PI2
{
// Default method
default void show()
{
System.out.println("Default PI2");
}
}
// Implementation class code
class TestClass implements PI1, PI2
{
// Overriding default show method
public void show()
{
// use super keyword to call the show
// method of PI1 interface
PI1.super.show();
// use super keyword to call the show
// method of PI2 interface
PI2.super.show();
}
public static void main(String args[])
{
TestClass d = new TestClass();
d.show();
}
}
If there is a diamond through interfaces, then there is no issue if none of the middle interfaces provide implementation of root interface.
If they provide implementation, then implementation can be accessed as above using super keyword.
// A simple Java program to demonstrate how diamond
// problem is handled in case of default methods
interface GPI
{
// default method
default void show()
{
System.out.println("Default GPI");
}
}
interface PI1 extends GPI { }
interface PI2 extends GPI { }
// Implementation class code
class TestClass implements PI1, PI2
{
public static void main(String args[])
{
TestClass d = new TestClass();
d.show();
}
}
Object: The Cosmic Superclass
The Object class is the ultimate ancestor - every class in Java extends Object (However you never write it)
Variable of type Object could be used to refer objects of any type
The equals method in Object class tests whether two objects point to same memory
Override equals() method if you wanna define your equality of object
Override toString() method for printed representation of class
Whenever object is concatenated to String using the "+" operator, Java compiler invoke toString method
Object class defines the toString() to print class name and memory location of object
toString() method is great debugging tool for traces
class X extends Object
Object o = new X();
X x = (X) o; // Object of X could be used after the casting
class X {
public boolean equals (Object other) {
if (this == other) return true; \\ point to same objects
if (other == null) return false;
if (getClass() != other.getClass()) return false; \\ both objects must belong to same class
if (!super.equals(other)) return false; \\ subclass should call for superclass check
X ox = (X) other;
return name,equals(ox.name);
}
public String toString() {
return super.toString() + getClass.getName() + " (name=" + name + " )";
}
}
String message = "Message " + x;
Methods
java.lang.Object
Class getClass() - returns a class object that contains information about the object
boolean equals(Object otherObject) - compares if the objects point to the same memory
Object clone() - creates a clone of object by allocating memory and copy current object to new object by memory copy
String toString() - returns a string that represents the value of this object
java.lang.Class
String getName() - returns the name of this class
Class getSuperClass() - returns the superclass of this class as a Class object
ArrayList
Array lists are array like objects that can grow and shrink automatically without you needing to write any code
Array are a feature of Java language with array type T[] for each element type T
ArrayList class is a library class defined in java.util package, which holds elements of type Object
Setting ArrayList initial capacity is optional
ArrayList like arrays are zero based
ArrayList set() should be called only for existing index to replace, for adding use add() instead
On rare occasions, array lists are useful for heterogeneous collections
Consider using linkedlist for element operations (add\remove) in middle of array list
ArrayList arr = new ArrayList();
arr.ensureCapacity(100); // set initial capacity - this is optional
arr.add(new X());
ArrayList arr2 = new ArrayList(100); \\ pass initial capacity
arr2.size();
arr2.trimToSize(); \\ This trims the memory block to holds current no of elements and garbage collector reclaim excess memory
arr.set(i, boss); \\ a[i] = boss;
Employee e = (Employee) arr.get(i); \\ cast since return type is Object
X[] a = new X[arr.size()];
arr.toArray(a); \\ Convert array list to array when you are done adding elements to array list
int n = arr.size()/2;
arr.add(n, e); \\ Insert element in the middle of list
arr.remove(n); \\ Removes element from the middle of list
java.util.ArrayList
ArrayList() - constructs an empty array list
ArrayList(ini initialCapacity) - constructs an empty array list with specified capacity
boolean add(Object obj) - appends an element at the end of array list, Always returns true
int size() - returns the no of elements currently stored in the array list
void ensureCapacity(int capacity) - ensures that the array list has the capacity to store the given number of elements without relocating its internal storage array
void trimToSize() - reduces the storage capacity of the array list to its current size
void set(int index, Object obj) - puts a value in the array list at specified index, overwriting previous element
Object get(index i) - gets the value stored at a specified index
void add(int index, Object obj) - shifts up elements to insert an element
void remove(int index) - removes an element and shoft down all the elements above it
Object Wrappers
There is a class (Integer) corresponding to the basic type e.g. int.
These classes are called object wrappers
The wrapper classes are final (can't override the toString() method)
You also cannot change the values you store in the object wrapper
list.add(new Double(3.14));
double x = ((Double) list.get(n)).doubleValue();
java.lang.Integer
int intValue() - return the value of Integer object as an int
The Class CLASS
The Java runtime system always maintains what is called runtime type identification on all objects
This information keeps track of the class to which each object belongs
Runtime type information is used by the virtual machine to select the correct methods to execute
The class that golds this information is called Class
The getClass() method in the Object class returns as instance of Class type
if (e.getClass() == Employee.class) ...
e.getClass().newInstance(); \\ Creates instance with default constructor
java.lang.Class
static Class forName(String className) - returns the Class object representing the class with name className
Object newInstance() - returns a new instance of this class
Design Hints for Inheritance
Place common operations and fields in the superclass
Don't use protected fields, instead protected methods are useful
Use inheritance to model the "is-a" relationship
Don't use inheritance unless all inherited methods make sense
Use polymorphism, not type information