InheritanceIn Java, you may create subclasses that reuse and extend another class, so that the subclass inherits (has direct access to) certain members (variables & methods) of its superclass. (A Java subclass is like a C++ derived class).
Why is inheritance useful? The design of a program is better when you create classes for more general features, and subclasses for more detailed features. We'll see some examples of this later.
What's different about subclasses from a regular class?
when an object of a subclass is instantiated, all of the instance variables in the superclass (and its superclass, etc.) are allocated memory along with the subclass' instance variables
non-private* methods in its superclass (and its superclass, etc.) may be called on a subclass object, as well as the subclass' (non-private) methods
when inside a subclass instance method, the superclass (non-private) methods may be called (if the superclass method is not overriden in the subclass)
when inside a subclass instance method, the superclass (non-private) variables may be directly accessed (unless the subclass has a variable with the same name)
Differences from C++:
Java does NOT support multiple inheritance, i.e., each class may only haveone superclass (unlike C++).
Java allows implementing more than one interface (see p. 16).
Every Java class may be subclassed unless it is declared as final.
The default superclass for all classes isjava.lang.Object (details later)
*Non-private methods include public, protected or no access specifier (protected superclass members are accessible by methods of a subclass in the same or different package and non-subclasses in the same package)
Defining a Subclass
In the class heading, add the extends class: class subclass-id extends superclass-id
Optional: You may define the class as public
Examples:
public class SuperClass{
int packageVar;
public int publicVar;
private int privateVar;
protected int protectedVar;
} // end class SuperClass
public class SubClass1 extends SuperClass{
void someMethod(){
packageVar = 0; // OK if in same package
publicVar = 0; // OK
privateVar = 0; // Error
protectedVar = 0; // OK
}
} // end class SubClass1
// In another package:
public class SubClass2 extends SuperClass{
void someMethod(){
packageVar = 0; // Error
publicVar = 0; // OK
privateVar = 0; // Error
protectedVar = 0; // OK
}
} // end class SubClass
public class Main{
public static void main( String [] args ){
SubClass1 sub1 = new SubClass1();
sub1.packageVar = 0; // Error
sub1.publicVar = 0; // OK
sub1.privateVar = 0; // Error
sub1.protectedVar = 0; // Error
SubClass2 sub2 = new SubClass2();
sub2.packageVar = 0; // Error
sub2.publicVar = 0; // OK
sub2.privateVar = 0; // Error
sub2.protectedVar = 0; // Error
} // end main
} // end class Main
NOTE: When no access specifier is given for a class, method or variable, then it can only be accessed by all methods in the same package.
Inside a Subclass:
In the subclass' constructor(s) you may call a superclass constructor just by doing (must be thefirst statement in the subclass' constructor): super( parameters);
NOTE: If you DON'T explicitly call the superclass constructor, then the JVM will try to call its default constructor (which may not exist)!
You may call a superclass non-private method if no method in the subclass has the same name by calling as if it’s in the same class
You may override a superclass method in the subclass (defining it with the exact same name and same parameters)-- this triggers polymorphism(read more about polymorphism HERE)
If the superclass has the same name method as in the subclass, to call it, do: super.method-id(parameters)
You may assign a subclass object (reference) to a superclass object variable
When a subclass constructor passes a parameter up to the superclass constructor via the superkeyword, the parameter cannot be a class-scope instance variable of the subclass because the subclass hasn't been constructed yet. Example extending the Grandparent class on next page:
public class BadParent extends Grandparent{
private int data=1;
public BadParent(){
super(data); // Error: can't pass data
}
} // end class BadParent
public class Grandparent{
protected int data;
public Grandparent(int i){
data=i;
} // end Grandparent constructor
public void display(){
System.out.println("Grandparent display "+data);
} // end display method
} // end Grandparent class
public class Parent extends Grandparent{
protected int data; // different from Grandparent's
public Parent( int i ){
super( i+1 ); // calls Grandparent constructor
data=i;
} // end Parent constructor
public void display(){
System.out.println("Parent display "+data);
} // end display method
} //end Parent class
public class Child extends Parent{
protected int data; // different from Parent's
public Child( int i ){
super( i+1 ); // calls Parent constructor
data = i;
} // end Child constructor
public void display(){
System.out.println("Child display" + this.data);
System.out.println("Parent data = " +
super.data);
System.out.println("Grandparent data= " +
((Grandparent)this).data );
super.display();
// Note: Can't call Grandparent's display()
// from here even with casting
} // end display method
} // end Child class
Note: (Grandparent) in the above example is casting the Child reference to its Grandparent.
In another class and file:
public class TryInheritance
{
public static void main( String[] args )
{
Grandparent g = new Grandparent( 100 );
Parent p1 = new Parent( 10 );
Parent p2;
Child c1 = new Child( 1 );
Child c2;
p2 = c1; // example of assigning a subclass obj. to superclass var.
if( p2 instanceof Child )//always check
c2 = (Child) p2;
//NOTE: if you downcast and it isn't an instance,
// an exception will be thrown
g.display();// displays "Grandparent display 100"
p1.display();// displays "Parent display 10"
p2.display();// displays "Child display 1", etc.
c1.display();// displays "Child display 1", etc.
} // end main
} // end TryInheritance