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
- Inheritance
- This and Super
- Static Method
- Class Modifiers - abstract, final, public
- Constructors
- Interfaces
- Exceptions and Methods
- Exceptional Exceptions
- Class Names, Packages and Import
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
- 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?
}
}
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
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" );
}
}
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
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
}
}
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
}
}
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");
}
}
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.