SDSU CS 596 Client-Server Programming
Java Inheritance

[To Lecture Notes Index]
San Diego State University -- This page last updated January 31, 1996
----------

Contents of Java Inheritance Lecture

    1. Inheritance
      1. This and Super
    2. Static Method
    3. Class Modifiers - abstract, final, public
      1. Constructors
    4. Interfaces
    5. Exceptions and Methods
      1. Exceptional Exceptions
    6. Class Names, Packages and Import

Inheritance

class  Parent  
{
	int  parentVariable;

	public  void  parentFunction()  
	{
		System.out.println(  "Parent Function"  );
	}

	public  void  overRideMe()  
	{
		System.out.println(  "In Parent"  );
	}
}

class  Child  extends  Parent  
{
	public  void  overRideMe()  
	{
		System.out.println(  "In Child"  );
	}
}

class  Inheritance  
{
	public static void main( String args[] ) 
	{
		Parent  Polymorphism  =  new Child();
		Polymorphism.overRideMe();
		Polymorphism.parentFunction();
	}
}
Output
In Child
Parent Function

This and Super


this
refers to the current object
type is the class containing the currently executing method

super
refers to the superclass
class  Parent  {
	String  name  =  "Parent";    }

class  Child  extends  Parent  {
	String  name  =  "Child";

	public  void  print()  {
		System.out.println(  name  );
		System.out.println(  this.name  );
		System.out.println(  super.name  );
		System.out.println(  Parent.name  );
		System.out.println(  ((Parent)this).name  );
	}
}

class  SuperThis  {
	public static void main( String args[] ) {

		Child  whoAmI  =  new Child();
		whoAmI.print();
	}
}
Output
Child
Child
Parent
Parent
Parent
More This

class  Parent  {
	String  name  =  "Parent";

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

class  Child  extends  Parent  {
	String  name  =  "Child";

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

}

class  SuperThis  {
	public static void main( String args[] )   {
		Parent  polymorphism  =  new Child();
		polymorphism.thisFunction();

		polymorphism  =  new Parent();
		polymorphism.thisFunction();

	}
}

Output
Child
Parent
This is static?

class  Parent  {
	String  name  =  "Parent";

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

class  Child  extends  Parent  {

	String  name  =  "Child";
}

class  StaticThis  {

	public static void main( String args[] ) {

		Parent  parentType  =  new Child();

		parentType.thisFunction();

		Child  childType  =  new Child();

		childType.thisFunction();
	}
}

Output
Parent
Parent
Real Polymorphism?

class  Parent  {

	public  void  fancy()  {
		whichOne();
	}

	public  void  whichOne()  {
		System.out.println(  "Parent"  );
	}
}

class  Child  extends  Parent  {
	public  void  whichOne()  {
		System.out.println(  "Child"  );
	}
}

class  VirtualFunctionsByDefault  {

	public static void main( String args[] )   {

		Parent  polymorphism  =  new Child();

		polymorphism.fancy();

		polymorphism  =  new Parent();

		polymorphism.fancy();
	}
}
Output
Child
Parent
Class Object

All classes inherit from Object
class Parent {
int size;
}

Is short hand for
class Parent extends Object {
int size;
}
class  Parent  {
	int  size;
}

class  TestObject  {

	public static void main( String args[] ) {

		Parent  watchThis  =  new Parent();

		int  myHash  =  watchThis.hashCode();  

		System.out.println(  myHash  );

			// Where does hashCode come from?
	}
}

Static Method


class  Parent  {

	public  static  void  classFunction()  {
		System.out.println(  "In Parent"  );
	}
}

class  Child  extends  Parent  {

	public  static  void  classFunction()  {
		System.out.println(  "In Child"  );
	}
}

class  StaticTest  {

	public static void main( String args[] ) {

		Parent  finalExam  =  new Child();

		finalExam.classFunction();

		Parent.classFunction();
	}
}
Output
In Parent
In Parent


Class Modifiers - abstract, final, public

final  class  EndOfTheLine  {

	int  noSubclassPossible;
	public  void  aFunction()  {
		System.out.println(  "Hi Mom"  );
	}
}

abstract  class  NoObjects  {

	int  noObjectPossible;
	public  void  aFunction()  {
		System.out.println(  "Hi Mom"  );
	}

	public  abstract  void  subClassMustImplement(  int  foo  );
}

public  class  Bar  	{	//  Must be in file called  Bar.java

	int  canBeAccessedFromOtherPackages;
	public  void  aFunction()  {
		System.out.println(  "Hi Mom"  );
	}
}

class  NoModifier  {	// Can be accessed from this package only

	int  whatDoesThisMean;
	public  void  aFunction()  {
		System.out.println(  "Hi Mom"  );
	}
}

Abstract Classes
abstract  class  NoObjects  {

	int  noDirectObjectPossible  =  5;

	public  void  aFunction()  {
		System.out.println(  "Hi Mom"  );
	}

	public  abstract  void  subClassMustImplement(  int  foo  );
}

class Concrete  extends  NoObjects  {

	public  void  subClassMustImplement(  int  foo  )  {
		System.out.println(  "In Concrete"  );
	}
}

class  AbstractClasses  {

	public static void main( String args[] ) {
		NoObjects  useful  =  new  Concrete();
		Concrete  thisWorks  =  new  Concrete();

		useful.subClassMustImplement( 10 );
		System.out.println(  thisWorks.noDirectObjectPossible  );
	}
}
Output
In Concrete
5
Inheritance and Final

final  class  EndOfTheLine  {

	int  noSubclassPossible;

	public  void  aFunction()  {
		System.out.println(  "Hi Mom"  );
	}
}
class  ThisWillNotWork  extends  EndOfTheLine   {
	int  ohNo;
}

Does not compile

Final Method

A final can not be overwritten
class  Parent  {

	public  final  void  theEnd()  {
		System.out.println(  "This is it"  );
	}

	public  void  normal()  {
		System.out.println(  "In parent"  );
	}
}

class  Child  extends  Parent  {

	public  void  theEnd()  	{			// Compile Error
		System.out.println(  "Two Ends?"  );
	}

	public  void  normal()  {
		System.out.println(  "In Child"  );
	}
}

Constructors

class  ConstructorExample  {

	public  ConstructorExample( )  {
		System.out.println(  "In constructor - no argument"  );
	};

	public  ConstructorExample( int  size)  {
		System.out.println(  "In constructor - one argument" );
	};

	public  void  ConstructorExample( )  {
		System.out.println(  " return type means it is ");
			System.out.println(  "not a constructor "  );
	};
}

class TestConstructor  {

	public static void main( String args[] ) {
		System.out.println( " Start main " );

		ConstructorExample  test  =  new ConstructorExample( );
		ConstructorExample  x  =  new ConstructorExample(5);

		System.out.println( " Done with Constructors " );
		test.ConstructorExample ();
	}
}
Output
Start main
In constructor - no argument
In constructor - one argument
Done with Constructors
return type means it is
not a constructor
Constructors and Inheritance
class  Parent  {

	public  Parent()  {
		System.out.println(  "In Parent"  );
	}
}

class  Child  extends  Parent  {

	public  Child()  {
		System.out.println(  "In Child"  );
	}
}

class  Constructors  {

	public static void main( String args[] ) {
		System.out.println(  "Construct Parent"  );
		Parent  polymorphism  =  new Parent();

		System.out.println(  "Construct Child"  );
		Child  care  =  new Child();
	}
}

Output
Construct Parent
In Parent
Construct Child
In Parent
In Child
Implicit Constructors

If a class has no constructor compiler generates an implicit constructor with no arguments
class  ImplicitConstructorOnly  {
	int  size  =  5;
}

class  OneConstructor  {

	OneConstructor(  String  message  )  {
		System.out.println(  message  );
	}
}

class  TwoConstructors  {
	TwoConstructors  (  String  message  )  {
		System.out.println(  message  );
	}

	TwoConstructors  (  )  {
		System.out.println(  "No argument Constructor"  );
	}
}

class  Constructors  {

	public static void main( String args[] ) {
	ImplicitConstructorOnly  ok  =  new  ImplicitConstructorOnly();

	TwoConstructors  alsoOk  =  new  TwoConstructors();

	OneConstructor  compileError  =  new  OneConstructor();
	}
}

Calling Other Constructors
class  Parent  {

	public  Parent(  )  {
		System.out.println(  "In Parent, No Argument"  );
	}

	public  Parent(  String  message  )  {
		System.out.println(  "In Parent"  +  message  );
	}
}

class  Child  extends  Parent  {

	public  Child( String  message,  int  value  )  {
		this(  message  );                // if occurs must be first
		System.out.println(  "In Child"  );
	}

	public  Child( String  message  )  {
		super(  message  );		// if occurs must be first
		System.out.println(  "In Child"  +  message  );
	}
}

class  Constructors  {
	public static void main( String args[] ) {
		System.out.println(  "Construct Child"  );
		Child  care  =  new Child( "Start from Child", 5 );
	}
}
Output
Construct Child
In ParentStart from Child
In ChildStart from Child
In Child
Implicit Call to Parent Constructor
class  Parent  {

	public  Parent(  )  {
		System.out.println(  "In Parent, No Argument"  );
	}

	public  Parent(  String  message  )  {
		System.out.println(  "In Parent"  +  message  );
	}
}

class  Child  extends  Parent  {

	public  Child( String  message,  int  value  )  {
		this(  message  );		// overrides implicit call
		System.out.println(  "In Child"  );
	}

	public  Child( String  message  )  {
		System.out.println(  "In Child"  +  message  );
	}
}

class  Constructors  {

	public static void main( String args[] ) {
		System.out.println(  "Construct Child"  );
		Child  care  =  new Child( "Start from Child", 5 );
	}
}
Output
Construct Child
In Parent, No Argument
In ChildStart from Child
In Child
Finalize - Destructor of Sorts

Automatic storage management handles reclaiming objects and arrays that are no longer needed by a running program

When an object is determined to no longer be needed it may be reclaimed, unless it has a finalize method

If a class has a finalize method, the method is executed. The object is reclaimed the next time it is determined the object is no longer needed

The finalize method is never called more than once for an object
Finalize Example
class  Death  {
	int  myId;

	public  Death  ( int  sequenceNumber)  {
		myId  =  sequenceNumber;  }

	public  void  finalize( )  {
		System.out.println(  myId  );    }
}

class  Finalization  {
	public static void main( String args[] ) {

		Death  sampleObject;
		for (  int  k = 0;  k < 5;  k++ )
			sampleObject  =  new Death(  k  );
	}
}
No Output
class  FinalizationForced  {
	public static void main( String args[] ) {

		Death  sampleObject;

		for (  int  k = 0;  k < 5;  k++ )
			sampleObject  =  new Death(  k  );

		System.gc();
		System.runFinalization();  }
}
Output
0
1
2
3
4

Interfaces


All interface variables are static and final

In file Flyer.java:
public  interface  Flyer  {
		public  boolean  hasWings();
}


In file test.java:
interface  Mammal  {

	static  boolean  hasLungs  =  true;
	public  boolean  hasLegs();
}

interface  Noisy  extends  Mammal  {

	public  boolean  hasBark();
}

class  Dog  implements  Noisy  {

	public  boolean  hasLegs() {
		return true;
	}

	public  boolean  hasBark()  {
		return true;
	}
}
// file test.java continued

class  Bird  implements  Mammal,  Flyer  {

	public  boolean  hasLegs(){
		return true;
	}

	public  boolean  hasWings()  {
		return true;
	}
}

class  InterfaceExample  {

	public static void main( String args[] )   {

		Bird  robin  =  new  Bird();
		Flyer  crow  =  new  Bird();
		Noisy  fido  =  new  Dog();
		Mammal  fifi  =  new  Noisy();		//Compiler Error

		robin.hasLegs();
		robin.hasWings();
		boolean test  =  robin.hasLungs;
		crow.hasLegs();		//Compile Error
	}
}

Exceptions and Methods


If a method explicitly throws an exception, it must either have throws in the function interface or catch the exception
class  SimpleExceptionDoneWrong  {

	public  void  compute(  )	{

		throw  new  Exception(  "Bad programmer" ); //Compile error
	}

	public  void  politeCompute(  )  throws  Exception	{   //Ok

		throw  new  Exception(  "Catch anyone?"  );
	}

	public  void  safeCompute(  )	{	// Ok

		try  {
			throw  new  Exception(  "Catch anyone?"  );

		} catch  (Exception  e)  { 
			 // Do the right thing here 
		}
	}
}


Exceptions and Methods - Continued

If method A calls method B that throws an exception, then A must either catch the exception or have a throws in the function interface
class  SimpleException{

	public  void  compute( ) throws Exception  {
		throw  new  Exception(  "Bad programmer"  );
	}

	public  void  callCompute()  throws Exception	{	// OK
		compute();
	}

	public  void  handleTheException()	{		// OK

		try  {
			compute();
		} catch  (  Exception  e  )  {
			System.err.println( " Math Error"  +  e.getMessage() );
		}
	}

	public  void  thisDoesNotCompile()	{
		compute();			// Compile Error
	}
}

Exceptional Exceptions


ArithmeticException and ArrayIndexOutOfBoundsException do not follow the rules given above for exceptions
class  SimpleExceptionOK  {

	public  void  compute(  )  {//OK

		throw  new  ArithmeticException(  "this works"  );
	}

	public  void  moreCompute(  )  {//OK

		throw new ArrayIndexOutOfBoundsException( "this works");
	}
}


Class Names, Packages and Import


Each class belongs to a "package"

A package has a public name space

A package defines the full name of a class

Standard packages
java.applet java.awt.peer java.net
java.awt java.io java.util
java.awt.image java.lang sun.tools.debug

Example - PrintStream

PrintStream is in the java.io package

The full name of the class is java.io.PrintStream
class Output {

	public static void main( String args[] ) {
		java.io.PrintStream  out  =  System.out;
		out.print(  "Look Mom, No System" );
	}
}
Import Statement

The import statement allows you to shorten class names
import  java.io.PrintStream;

class Output {

	public static void main( String args[] ) {
		PrintStream  out  =  System.out;
		out.print(  "Look Mom, No System" );
	}
}

import  java.io.*;

class Output {

	public static void main( String args[] ) {
		PrintStream  out  =  System.out;
		out.print(  "Look Mom, No System" );
	}
}

Default Import

All classes in the java.lang are imported in all programs by default
Placing a class in a package
package  sdsu.roger;

public  class  Sample  {
	public  void  hello()  {
		System.out.println( "Hello for package sdsu.roger" );
	}
}

Place program in file named "Sample.java"

Place file "Sample.java" in directory called "roger"

Place directory "roger" in directory called "sdsu"

Place directory "sdsu" anywhere you like, "~whitney/java/classes"

Make sure that "~whitney/myJava" in the CLASSPATH environment variable
setenv CLASSPATH
'.:/opt/java/classes:/home/ma/whitney/java/classes'
Place the following class anywhere you like and compile
import  sdsu.roger.Sample;

class TestPackage {

	public static void main( String args[] ) {
		Sample  me  =  new  Sample();
		me.hello();
	}
}

Package Notes

If a class has no declared package, it is in the unnamed package

CLASSPATH needs to point to the root directory containing the binaries of packages

The above example also put the source code there. There is no need to have both binaries and source code in the same location. In fact it might be a very bad idea.

----------