520 likes | 622 Views
UMass Lowell Computer Science 91.460 Java and Distributed Computing Prof. Karen Daniels Fall, 2000. Lecture 12 Java Fundamentals Exception Handling Objects/Classes:Polymorphism Backup Material Mon. 10/2/00. Homework #3. HW# Assigned Due Content.
E N D
UMass Lowell Computer Science 91.460Java and Distributed ComputingProf. Karen DanielsFall, 2000 Lecture 12 Java Fundamentals Exception Handling Objects/Classes:Polymorphism Backup Material Mon. 10/2/00
Homework #3 HW# Assigned DueContent 1 Fri, 9/8 Fri, 9/15 Part 1 Mon, 9/18 Part 2 2 Fri, 9/15 Fri, 9/22 Part 1 & Part 2 3 Fri, 9/22 Fri, 9/29 Part 1 & Part 2 Homework #4 will be assigned on Fri., 10/6 (skipping one week due to test) Homework is due at the start of lecture on the due date.
Exam 1 Topics not covered: Exception Handling & Files/Streams Format: Multiple choice
Java Fundamentals Exception Handling (much of this material is from Java2: The Complete Reference)
Exception Handling Remember try, catch, throw, exception handling from C++? • Exception: • Is a Run-Time Error :“abnormal condition that arises in a code sequence at run time” • Java treats exceptions in Object-Oriented way • Exception is an object describing an error condition • When error condition occurs, exception object is created and thrown in method where error occurs • Method may: • catch the exception and handle it • pass it on: throw it up to invoking method Java Exception Handling Keywords: try, catch, throw, throws, finally
Exception Handling try{ // Block of code that may generate errors } catch ( ExceptionType1 exOb ) { // Exception handler for ExceptionType1 } catch (ExceptionType2 exOb ) { // Exception handler for ExceptionType2 } //... finally{ // Block of code to be executed before try block ends }
Exception Handling:Class Casting & Null Pointer Example This is a contrived example. Output: B’s foo Class cast exception in casting q to a in polyInit() Null pointer exception in polyInit() public class PolyTest { public static void main(String args[]) { B b = new B(); Object c = new Object(); polyInit(b); polyInit(c); } public static void polyInit(Object q){ // (Could use parameter variable of type A) A a = null; try{ // (Alternatively,could use instanceof to test if q is of type A -- see later slide) a = (A)q; } catch(ClassCastException ccex) { System.out.println("Class cast exception in casting q to a in polyInit()");} try{ a.foo(); } catch(NullPointerException npex) { System.out.println("Null pointer exception in polyInit()");} } } class A { public void foo() { System.out.println("A's foo"); } } class B extends A { public void foo() { System.out.println("B's foo"); } }
Exception Handling:Class Casting & Null Pointer Example public class PolyTest { public static void main(String args[]) { B b = new B(); Object c = new Object(); polyInit(b); polyInit(c); } public static void polyInit(Object q){ A a = null; try{ a = (A)q; a.foo(); } catch(ClassCastException ccex) { System.out.println("Class cast exception in casting q to a in polyInit()");} catch(NullPointerException npex) { System.out.println("Null pointer exception in polyInit()");} } } class A { public void foo() { System.out.println("A's foo"); } } class B extends A { public void foo() { System.out.println("B's foo"); } } Multiple statements in try block Multiple catch clauses
Exception Handling:Class Casting & Null Pointer Example Output: B’s foo Class cast exception in casting q to a in polyInit() main(): Class cast exception in casting q to a in polyInit() Exception in thread “main” java.lang.NullPointerException: at PolyTest2.polyInit(PolyTest2.java:17) at PolyTest2.main(PolyTest2.java:11) public class PolyTest2 { public static void main(String args[]) { B b = new B(); B d = null; Object c = new Object(); try{ polyInit(b); polyInit(c); } catch (ClassCastException ccex) { System.out.println("main(): Class cast exception in casting q to a in polyInit()");} polyInit(d); } public static void polyInit(Object q) throws ClassCastException, NullPointerException{ A a = null; try{ a = (A)q; a.foo(); } catch(ClassCastException ccex) { System.out.println("Class cast exception in casting q to a in polyInit()"); throw ccex; } }} class A { public void foo() { System.out.println("A's foo"); } } class B extends A { public void foo() { System.out.println("B's foo"); } } Catch exception again Throw exceptions up one level Throw ClassCastException NullPointerException is not caught
Exception Handling:File I/O Example try{ output.close( ); } catch (IOException ioex) { JOptionPane.showMessageDialog(null, “Error closing file”, “Error”, JOptionPane.ERROR_MESSAGE); }
Exception Handling: Some Built-in Exceptions ExceptionMeaning • ArithmeticException • ArrayIndexOutOfBoundsException • NullPointerException • ClassCastException • ClassNotFoundException • SecurityException • InterruptedException • IOException • Arithmetic error (e.g. Divide-by-0) • Array index out of bounds • Invalid use of null reference • Invalid cast • Class not found • Attempt to violate security • A thread has been interrupted by another thread • Problem with a file I/O operation
Java Fundamentals Objects/Classes: Polymorphism
A Motivation...Polymorphic Graphics Static Resource Array within Resource Class
A B “Casting” between Objects • Explicit reference casts between types related by inheritance: • If class A is extended by class B, and myA is a reference to an A and myB is a reference to a B: • myA = (A) myB, and myB = (B) myA are valid casts • Don’t need to (but can) cast from a subclass to a superclass reference (e.g., myA = myB does not need the explicit cast) • Casting from a supertype reference to a subtype reference is potentially dangerous • If the supertype reference is not actually referring to an instance of the specified subclass, a runtime exception will be thrown • This can be avoided by doing an instanceof test prior to the cast • if (myA instanceof B) { myB = (B) myA; } Casting from subtype reference to supertype reference does not remove subtype members, just “hide” them
Polymorphism • Allows for the specific behavior of certain method invocations to be determined at run-time based on the specific subclass to which it belongs • Does not require compile-time knowledge of types (at the point of use) • Used with inheritance • Subclass instances are accessed via superclass references
Polymorphism • Allows instances of different classes to be treated as if they were instances of the same (super) class • Can, for example, perform the same operation on each object in a list of different types of objects • Specific action depends on the specific type of the object at run-time • Greatly enhances the extensibility of a program • Can add derived classes very easily
Realizing Polymorphism • Superclass declares (and possibly defines) a method • One or more subclasses override the superclass method • A superclass reference is used at the point of invocation • The actual instance referred to might be a subclass instance • At run-time, depending on the actual type of the instance, the appropriate method is executed
Automobile maxSpeed: int GetMaxSpeed( ) Yugo Lexus maxSpeed: int maxSpeed: static int GetMaxSpeed( ) foo( ) GetMaxSpeed( ) foo( ) Polymorphism Example Object different from automobile Inheritance tree using Unified Modeling Language (UML)
Polymorphism Example public class Automobile extends Object { int maxSpeed = 55; // can be static public int GetMaxSpeed() { return maxSpeed; } // cannot be static // need not be abstract public static void main(String args[ ]) { // see later slide } }
Polymorphism Example class Lexus extends Automobile { static int maxSpeed = 85; // can be non-static public int GetMaxSpeed() { return maxSpeed; } // must not be static public void foo() { System.out.println("In Lexus foo()"); } } class Yugo extends Automobile { int maxSpeed = 35; // can be static public int GetMaxSpeed() { return maxSpeed; } // must not be static public void foo() {System.out.println("In Yugo foo()"); } }
Polymorphism Example Automobile A1 = new Lexus(); Automobile A2 = new Yugo(); A1 A2 Lexus Yugo Lexus Implementation Yugo Implementation Non-static behavior decided at runtime
Polymorphism Example public static void main(String args[ ]) // for class Automobile { Automobile myAutos[ ] = new Automobile[3]; myAutos[0] = new Automobile(); myAutos[1] = new Lexus(); // see next slide myAutos[2] = new Yugo(); // see next slide for (int i = 0; i < myAutos.length; i++) { System.out.println("Max Speed ="+ myAutos[i].GetMaxSpeed()); //myAutos[i].foo(); // Will generate compiler error // Because automobile does not have a foo method! if (myAutos[i] instanceof Lexus) ((Lexus) myAutos[i]).foo(); if (myAutos[i] instanceof Yugo) ((Yugo) myAutos[i]).foo(); }} Output: Max Speed = 55 Max Speed = 85 Max Speed = 35
Polymorphism vs a switch • A switch is a multiple-select control structure • Execute a behavior based on a condition • The problem with switches (and nested if's) is that you have to know AT COMPILE TIME all of the selection conditions and subsequent behavior AT THE LOCATION of the multiple selection • Polymorphism presents a multiple select behavior in which you don't need to know at compile time either the specific selection conditions (i.e., the class type) or the subsequent behavior
Java Fundamentals Objects/Classes: Backup Material
Backup Topics • this keyword and this() • constructors and super() • finalizers (destructors) • nested (inner) classes • abstract classes • interfaces • class Object • garbage collection • operator new • command line arguments • packages • adding strings
Referencing this • ‘this’ is an explicit reference to the instance of a class on which a (non-static) method is invoked for use within that method • Can think of a (non-static) method as having an implicit first argument ("this") • Can be used to solve naming conflicts between parameters and instance variables • E.g., this.name = name • Static methods have no "this" reference • They are not (always) invoked on an instance
Example of using this public class MyClass { private final static int MAX_NUM_INSTANCES = 100; private static MyClass myClassInstances[]; private static int numInstances; static { myClassInstances = new MyClass[MAX_NUM_INSTANCES ]; numInstances = 0; } ... public MyClass() { /* do stuff as desired */ RememberInstance(this); } private void RememberInstance(MyClass myClassRef) { if (numInstances < MAX_NUM_INSTANCES ) { myClassInstances[numInstances++] = myClassRef; } } ... }
Constructors and super( ) • Constructors are not inherited • Default (null) superclass constructor is called implicitly before all subclass constructors • (and their superclass null constructors in turn) • Superclass constructors can be called explicitly using the super keyword • Must be the first executable statement in the subclass constructor
this() and super() • Provide mechanisms to explicitly invoke a constructor from within another constructor of the same class (this()) or a subclass (super()) • If present, either super() or this() must be the first call in a constructor (only one can be present) • Must contain an appropriate list of arguments to match a corresponding constructor in the appropriate class
Example of this() and super() public class Box { private double top, left, bottom, right; public Box(Point top_left, double bottom, double right) { top = top_left.y(); left = top_left.x(); this.bottom = bottom; this.right = right; } public Box(double x, double y, double width, double height) { this(Point(x, y), right-left, bottom-top); } } public class MyBox extends Box { private int boxColor; public MyBox(double x, double y, double width, double height, int color) { super(x, y, width, height); boxColor = color; } }
Finalizers (Destructors) • Class Object defines a finalizer • void finalize(); • Gets invoked by garbage collector • Programmer-defined classes can override finalize • Used to “clean up” • For example, release (non-memory) system resources (such as bitmaps, graphics media) • Not as important as in C or C++
Finalizers (Destructors) • Question: If an object is no longer referenced, but it references some other object, does Java automatically clean up that reference when the object is garbage collected? This reference is removed A B Is this one?
Finalizers (Destructors) • If you define a finalize method for your class, it: • Should be declared protected • Should be the only one • Should invoke the superclass finalizer as its last step (i.e., super.finalize()) • Can be explicitly invoked (like any other method) • Does not initiate garbage collection • An object can be “saved” in a finalizer by creating a reference to it
Finalizer (Destructor) Examples public class MyClass { private final static int MAX_NUM_INSTANCES = 100; private static MyClass myClassInstances[]; private static int numInstances; static { myClassInstances = new MyClass[MAX_NUM_INSTANCES ]; numInstances = 0; } ... public MyClass() { /* do stuff as desired */ RememberInstance(this); } protected void finalize() { // decrement numInstances, delete ref from myClassInstances (to include compacting the array) } ... }
Nested Classes • Nested class = class within a class • Scope of nested class is bounded by scope of enclosing class • Nested class has access to members (even private) of enclosing class • Enclosing class does not have access to members of nested class • Static nested class: not often used • Inner class (non-static): used often for GUIs to handle events • We’ll use these for GUIs and also for Jini
Inheritance vs Nesting • Scope: • A non-static nested class is known only within scope of enclosing class • A subclass can be known outside its superclass • Access: • A nested class can access members (even private ones) of enclosing class • A subclass cannot directly access private members of its superclass
abstract Classes • An abstract class is designed to be a superclass only • Not designed to have any instances (no objects of the generic type represented by that class) • Example: class Resource vs class Airport and class Plane • Syntax: abstract class className { // classBody }
abstract Classes • An abstract class can have certain state and behavior that is common to subclasses • Otherwise, we would use an interface • If a class extends an abstract class and does not define an abstract method in that abstract class, it is also abstract • An abstract class can have non-abstract methods and instance variables • A class with abstract methods must be declared abstract • [A concrete class is one that can have instances]
abstract Class Example abstract class Resource { private Point2D location; private String name; protected Resource(Point2D pt, String name) { /* do stuff as desired */ } abstract public void Draw(Graphics gc); } public class Airplane extends Resource { private boolean loadedStatus; public Airplane(Point2D pt, String name) { super(pt, name); loadedStatus = false; } public void Draw(Graphics gc) { // do stuff, possibly with loadedStatus } }
interfaces • An interface defines a collection of methods (is a collection of method signatures) • A class implements an interface • An interface can also define constants (final static data) • Interfaces are abstract (all their method declarations are publicabstract) • Interfaces can be imported (like classes) • Syntax: modifiers interface InterfaceName extendsClause { // interface body }
interfaces (concluded) • A class can implement one or more interfaces (sets of method specs) • Must implement every method in the interface • Else, becomes an abstract class • Used in place of an abstract class that does not provide any implementation • Are normally defined in files of their own (just like public classes) • Presents an “is-a” relationship like inheritance • Can be used to define related constants (like including a “constants.h” file in C/C++)
class Object • Parent class for all Java classes • Every class inherits the methods and data members of class Object • For example, String Object.toString() – convert an instance of a derived class to a String • Normally redefined by each class • Called by automatic conversion (e.g., concatenation of a string with an object)
Garbage Collection • When an object has no more references, it is marked for collection • Applies to both applications and applets • System.gc – suggest that the system do garbage collection • Runs as a separate thread • No telling when it might do its thing
Operator new • All (actually, most) objects are created with new • new allocates memory • Provides space for a copy of the class’ instance variables • new initializes the object • Invokes the appropriate constructor • new returns a reference to the new object • Special cases: String and arrays
Using new with Arrays • You can declare an array • String airportNames[]; • You can initialize an array by listing elements • String airportNames[] = { “SFO”, “BOS”, “LAX” }; • You can initialize an array with new • String airportNames[] = new String[10]; • Note that this creates an array of references to Strings
Command Line Arguments • class Test { public static void main(String[] args) { ... } } • Invocation: java Test This is a test • Command line arguments are placed into the parameter of the main method • The first argument after the className is placed into the 0th element of the String array and so on • I.e., args[0] is set to “This”, args[1] to “is”, ...
package Definition • A package is a set of related classes • A package is a mechanism for finding classes (and interfaces) • I.e., it is a directory mechanism • A package helps others use your classes • A package provides a namespace • [Classes are put into the no name package by default]
Making a package • Build the class with public methods • So that it can be used by classes outside of your package • Put the class into a package • Add a package statement to (top of) the class definition file • Syntax: package packageName; • Compile the class and place it into the appropriate directory structure (with the -d compiler switch) • The classes directory
import Statements • Mechanism for helping the compiler find other classes • Becomes a shorthand mechanism • Can refer to class by simple name rather than full “path” • Not required if can guarantee that all needed .class files in the same directory
import Statements (concluded) • Three forms: • import packageName.className; • import packageName.interfaceName; • import packageName.*;