CS 163 Lecture-Module #06:
Language Elements Related to Inheritance


significant example of inheritance:
the Exception hierarchy
class Exception
  class RunTimeException extends Exception
    class ArithmeticException extends RunTimeException
    class IndexOutOfBoundsException extends RunTimeException
      class ArrayIndexOutOfBoundsException extends IndexOutOfBoundsException
      class StringIndexOutOfBoundsException
                extends IndexOutOfBoundsException
    class NullPointerException extends RunTimeException
    ...
  class InterruptedException extends Exception
  class IOException extends Exception
    class FileNotFoundException extends IOException
    class SocketException extends IOException
  ...
http://java.sun.com/j2se/1.4/docs/api/java/lang/Exception.html

"Errors are particularly serious system problems that generally should not be caught. Exceptions are caused by problems that should be caught and processed during program execution to make a program more robust."
: "Java How to Program" by Dietel & Dietel
if some code such as  readLine()  or  monsters[i].move()
might generate an Exception,
you can handle it as follows:
m() {
  ...
  try {
    for( int i = 0; i ... ) {
      monsters[i].move();
      
    readLine(...
    ...
    }
  catch( exception_class e ) {
      // put code in this block to handle exception
      // e.g. simply:
      e.printStackTrace();
      }
  ...
  }
class-extension/inheritance, polymorphism involved because e.g. suppose want to catch ArrayIndexOutOfBoundsException  and  StringIndexOutOfBoundsException

what's caught is Exception whose class is precisely what's specified
e.g.  IndexOutOfBoundsException  here
or any subclass of that
thus would catch ArrayIndexOutOfBoundsException  and  StringIndexOutOfBoundsException

how do Exceptions arise?
source-code for  readLine()  has and you could have:
throw new exception_class(message_string);
e.g.:
if( denominator == 0 )
  

actually system can throw some exceptions for you e.g. in:


throw  inside  try-block clearly goes to corresponding  catch-block
if have  catch (appropriate_exception_class ...
otherwise  throw  inside method  and goes to  catch-block for the  try-block containing the 
e.g. suppose have the following:
...
main(...)
  {
  try {
    ...
    m();
    ...
    }
  catch ( exception_class2 e) { ...}
  ...
  }
if inside  m()  exception_class there doesn't include ArithmeticException, while in  main()  here exception_class2 does, then


do you have to catch Exceptions? 
if it's not clear what happens to exceptions, systems not entirely reliable
many Exceptions must be caught
or at least acknowledged:
method-header can have: 
but doing this all the time would be tedious
so you don't have to do this for sub-classes of 
called 
all other exceptions called "checked"



another application of polymorphism:
consider the way varying numbers of  Faces are stored
deleting and recreating arrays of them
an alternative is to use class  which Java API provides
functionality of array but size not restricted
capacity increases when add more elements
store additional element via   
    can store any object in  ArrayList
get element at index i via   
use:
instead of declaration  Face[] faces_array ... ;
    have:
    ArrayList faces_arrlst = new ArrayList();
instead of allocation  faces_array = new Face[num];
    have:
    faces_arrlst.clear();
instead of assignment  faces_array[index] = ...
    have:
    faces_arrlst.add(...);
instead of use/access  ...faces_array[i]...
    have:
    ...( faces_arrlst.get(i))...
but  ArrayList.get()  returns type  because as far as  ArrayList  is concerned,
what was stored was  Object
ArrayList  doesn't know if stored  Face  or  Monster  or  String  or ??
so need 

further capabilities of  ArrayList: size(), add(index, Object), remove(index), set(index, Object), ...

for example,
how might count number of  FaceSmilingBabyHairs in  ArrayList?
    int count_of_FaceSmilingBabyHair_ss = 0;
    for ( int i = 0; i < faces_arrlst.size(); i++ )
        if ( faces_arrlst.get(i)  FaceSmilingBabyHair )
            count_of_FaceSmilingBabyHair_ss++;
also e.g. in  life.java

No, you do not need to use |ArrayList| for your project.



sounds like you can handle class-objects nicely
in collections such as  ArrayList  which automatically adjust size depending on how much you store in them
can you handle non-class things similarly?
ArrayList al = new ArrayList();
al.add(57);    // 
the problem is that  int 57  isn't an 
similarly can't handle  booleans,  doubles, rest of primitive types as objects
to address situations such as this, Java provides 
enabling you to 'wrap' any desired primitive value in an object
names of these classes are:

construct an object of such a class from an appropriate primitive value
e.g.:



|interface|

interface  is just 
an interface to promise will have the methods listed for it
e.g.:
public interface KeyListener {
    public void keyTyped(KeyEvent ke);
    public void keyPressed(KeyEvent ke);
    public void keyReleased(KeyEvent ke);
    }

public interface Comparable {
    public int compareTo(Object o);
        /* Compares this object with the specified object for order.
         * Returns a negative integer, zero, or a positive integer as this
         * object is less than, equal to, or greater than the specified
         * object.
         */
    }

public interface Enumeration {
    public boolean hasMoreElements();
        // Tests if this enumeration contains more elements.

    public Object nextElement();
        // Returns the next element of this enumeration if this enumeration
        // object has at least one more element to provide.
    }

public interface MouseListener {
    public void mousePressed(MouseEvent me);
    public void mouseClicked(MouseEvent me);
    public void mouseReleased(MouseEvent me);
    public void mouseEntered(MouseEvent me);
    public void mouseExited(MouseEvent me);
    }

public interface List {
    public void add(Object o);
    public boolean contains(Object o);
    public Object get(int index);
    public boolean isEmpty();
    public int size();
    . . .
    }

public interface Shape {
    public boolean contains(double x, double y);
    public boolean contains(Point2D p);
    public Rectangle getBounds();
    public boolean intersects(Rectangle2D r);
    . . .
    }

classes implementing  interface List  include  ArrayList,  LinkedList,  Vector
classes implementing  interface Comparable  include  BigDecimal,  BigInteger,  Date,  String
classes implementing  interface Shape  include  Line2D,  Polygon,  Rectangle

intriguingly, can still declare reference variables of  interface-type
usable only for storing objects of real/'concrete' classes which implement the  interface
e.g.:





abstract

note that an  interface  provides no implementation
suppose want a scheme like interface
where want sub-classes to implement methods,
but willing to provide some implementations.
then write this class with those implemented methods
and qualify remaining unimplemented methods with 
this class also qualified 
other classes  extend  this as usual, must implement those unimplemented methods
(otherwise the derived classes in turn are abstract)
e.g. that primitive  attack()  in  class Monster  is

really should be simply unimplemented:
abstract class Monster {
  ...
  final void move() {
    x += dx;  y += dy; }
  abstract void attack();
  }

class Hobgoblin extends Monster {
  ...
  void attack() {
    player.life -= damaging_amount;
    }
  }

class Leprechaun extends Monster {
  ...
  void attack() {
    player.gold -= pilfering_amount;
    }
  }
could instead define a do-nothing  Monster.attack()
but that's dangerous, appearing to provide some functionality when really not

abstract method different:
with method really absent, not just empty,
system can avoid failures of inaction

an effect of having such an abstract method
is  the specific class
because method has no body that could be executed
e.g.:
    Monster r = new Monster(XUL, YUL, FIELDSIZE);        // ?OK?
    r.attack();    
    thus  new Monster(...)  actually disallowed
but can instantiate subclasses that provide the method
this is OK here:
consider that really any  Monster  is 
if a class is normal and can be instantiated, called 
(this contrast clarifies the term "abstract")

as above with  interface,
intriguingly, can declare reference variables of abstract class-type
usable only for storing objects of (concrete) sub-types
thus even if  class Monster  is  abstract,
could still do the following:
Monster [] monsters = new Monster[26];
. . .
monster[i].move();
monster[i].attack();
for another example, consider last version of code for instructors problem,
instrs_inherit.java ,
want to unify code further:
want to move repeated statement(s):
        if ( stress() > respect() )
                cope();
into  receive_email()  in class CollegeTeacher
but class CollegeTeacher  has no method cope()
(this was a deficiency all along in earlier versions
instrs_compos.java  and  instrs_inherit.java:
'generic'  CollegeTeacher's general 'framework' is OK
but no method for coping

could define a do-nothing  cope():
class CollegeTeacher { ...
    void cope() 

but that may be ~~dangerous, doing nothing when something may be expected
instead, more explicitly have an   cope()  with no body, just "":
        public abstract void cope();
class CollegeTeacher  must also be qualified 
instrs_abstr.java

note interaction of abstract and  (polymorphism):
inside new  CollegeTeacher.receive_email()  invocation of  cope()  can't invoke  CollegeTeacher.cope()  because 
must dynamically dispatch  cope()  of current object --
actually stored in automatically-defined method-object-variable 
get invocation of  Professor.cope()  or  AsstProf.cope()  or ...

in fact dynamic dispatch applies to more method-invocations than may be clear at first glance at this code:
also there inside  CollegeTeacher.receive_email(),
system   respect()
according to object stored in  this
even though  receive_email()  is inside  CollegeTeacher  and  CollegeTeacher  does have a fully defined method respect()
thus  Professor's   respect()  invoked if  this  inside  CollegeTeacher.receive_email()  is  a  Professor
similarly for  stress()  which  Instructor  overrides





summary of this lecture-module

aspects of Java related to inheritance:


(Copyright © 2008 by Hugh McGuire   — for thoughts about this, see   http://www.cis.gvsu.edu/~mcguire/teaching/copyright_thoughts.html .)