Class families and inheritence

Example: Bank account

How inheritence works

Scope and disambiguation in class inheritence

Everything is an object: reflection

Every class in Java is a subclass of the base class named Object. Please see its reference documentation.

Java allows us to see class properties and inheritence structure, through a series of reflection methods inherited from Object class:

    > CreditAccount c=new CreditAccount("a","b",5000);
    > c.getClass().getName()
    "CreditAccount"
    > c.getClass().getSuperclass().getName()
    "BankAccount"
    > c.getClass().getSuperclass().getSuperclass().getName()
    "java.lang.Object"

Type compatibility

A subclass of a class passes (accepted) as an instance of the superclass(es). e.g.

    BankAccount c=new CreditAccount("a","b",5000);

Exercise: Library resources

Write a class to represent the abstract notion of Resource in a library, e.g. our university library contains resources such as books, DVDs, etc. The resource class must be able to store the title of the resource, its library call-no (a string), its availability status (a boolean indicating whethet the resource is borrowed out or available at library), and id of the library patron who has borrowed it (a string). The Resource class must have methods to inquire its availablility, and also to borrow and return the resource by a patron.

Then write a Book class, which additionally stores the name of book's -single- author, hence have an according constructor.

Exercise solution

    class Resource {
      String title, callNo,borrowedBy;
      boolean available;

      Resource(String title, String callNo) {
        this.title=title;
        this.callNo=callNo;
        available=true;
      }

      boolean isAvailable() {return available;}

      void borrow(String byWho) throws Exception {
        if (available) {
          available=false;
          borrowedBy=byWho;
        } else
          throw new Exception("Already taken");
      }

      void returnResource(){
        available=true;
      }
    }

    class Book extends Resource {
      String author;

      Book(String title, String author, String callNo) {
        super(title,callNo);
        this.author=author;
      }
    }

Polymorphism, and its absence in Java

Motivating Example: Geometric shapes

How to do

    class Shape {
     double area() throws Exception {
       throw new Exception("I cannot compute such an abstraction!");
     }
    }

    class Circle extends Shape {
        double radius;
        Circle(double radius) {this.radius=radius;}
        double area() {return Math.PI*radius*radius;}
    }

The above code is not very good since the area method throws an exception, which looks quite unnecessary!

Interfaces

Example: Shape interface

Interface type compatibility

Similar to subclassing, interfaces are used as types:

    > Shape[] shapes={new Circle(5), new Square(10)};
    > shapes[0].area()
    > shapes[1].area()
    > shapes[0].radius //Java thinks it is a Shape!!
        Static Error: No field in Shape has name 'radius'

Typecasting

Java allows a method for casting types, ie. assuming type of something as differnt than what is declared, which is to be used exceptionally. If you ever need to use this, it probably is a symptom of bad design in your software!

typecasting is done by putting a new type in front of an object in paranthesis, for example:

    > Shape[] shapes={new Circle(5), new Square(10)};
    > shapes[0].radius
    Static Error: No field in Shape has name 'radius'
    > ((Circle)shapes[0]).radius //valid typecasting
    5.0
    > ((Circle)shapes[1]).radius  //invalid typecasting
    java.lang.ClassCastException: From Square to Circle

Note that this usage prevents Java from catching errors, since typecasting errors cannot be captured in compile time!

Polymorphism with interfaces: Shapes in 2 or 3 dimensions

    interface Shape {
        double area();
    }
    interface Shape3D {
        double volume();
    }
    class Sphere implements Shape, Shape3D {
        double radius;
        Sphere (double radius) {this.radius=radius;}
        public double area() {
            return 4*Math.PI*radius*radius;
        } 
        public double volume() {
            return (4/3)*Math.PI*radius*radius*radius;
        }
    }

Note that Sphere is polymorphic, i.e. it can be used in place of a Shape or Shape3D:

    Shape3D[] shapes3d={new Sphere(5)};
    Shape[] shapes={new Circle(5), new Square(10), new Sphere(15)};

Exercise: Placeable shapes

The shapes we have defined are not placed in any coordinate system. In this exercise we want to implements shapes which supports placement, only for two dimensions. Placement must be done by setting the position and angle of the shape, and getting them as well. Write an interface named Placeable2D, and improve the Square class to implement this interface.

Solution

    interface Placeable2D {
      void setPosition(double x, double y);
      void setAngle(double angle);
      double getPositionX();
      double getPositionY();
      double getAngle();
    }

    class Square implements Shape, Placeable2D {
        double side;
        double xpos, ypos, angle;
        Square(double side) {this.side=side;}
        public double area() {return side*side;} //this method must be present!!
        public void setPosition(double x, double y) { xpos=x; ypos=y;}
        public void setAngle(double angle) { this.angle=angle;}
        public double getPositionX() {return xpos;}
        public double getPositionY() {return ypos;}
        public double getAngle() {return angle;}

    }

Case study: Stack with linked list

A linked list is a mutable list which is structured as a chain. Each element in the linked list stores data for an item, and the -reference of- next element in the list.

A stack is a data structure which works as a LIFO (last-in-first-out) queue.

In this example we will implement a stack interface with a linked list. This program can store only integers as data items.

The stack interface

    interface IntegerStack {
        void push(int data);
        boolean isEmpty();
        int pop();
    }

The linked list

A linked list is a class itself, but it also requires each piece of the chain to be represented as an object.

    interface IntegerStack { 
     void push(int item); 
     int pop() throws Exception; 
    } 

    class IntegerLinkedList implements IntegerStack { 
     Item head; 

     public void push(int data) { 
      if (head==null) 
       head=new Item(data); 
      else 
       head=new Item(data,head); 
     } 

     public int pop() throws Exception { 
      if (head==null) 
       throw new Exception("List is empty"); 
      else { 
       int retval=head.data; 
       head=head.next; 
       return retval;
      } 
     } 
    } 

    class Item { 
     Item next; 
     int data; 
     Item(int data) { this.data=data; } 
     Item(int data, Item next) { this.data=data; this.next=next;} 
    }

    class Tester {
      public static void main(String[] args) {
        IntegerStack s=new IntegerLinkedList();
        s.push(1);
        s.push(2);
        try {
          System.out.println(s.pop());
          System.out.println(s.pop());
        } catch (Exception e) {
          System.out.println(e);
        }
      }
    }

HOME EXERCISE 1

Write a Cone class which implements Shape and Shape3D interfaces.

HOME EXERCISE 2

Consider the products in an e-commerce store for computers and home electronics. Any product in this store have some basic data such as price and name. Write a Product class to represent these common features.

Computers and laptop computers are products. But also there are some information such as CPU name (eg. "intel pentium5", or "AMD Centrino"), and RAM capacity (in GBs, eg. 4). Laptop computers are, of course, computers. But they are in addition mobile devices, similar to media players or mobile phones. In out system such mobile devices must support a "Mobile" interface as follows:

    interface Mobile {
        int batteryTime(); //in minutes
        double weight(); //in kg
    }

Write the Product, Computer, and Laptop classes to support the above specifications. Note that no method is imposed in the design specification.

What types are Laptop class compatible with?

BONUS TRACKS

Following subjects will not be covered in the exam!

File I/O (input/output)

A file can store a variety of content, such as binary data (music) or human readable data (text, or HTML).

Following is an example of reading and writing human readable files:

    import java.io.FileReader;
    import java.io.FileWriter;
    import java.io.BufferedReader;
    import java.io.PrintWriter;
    import java.io.IOException;

    class FileIOTester {
      public static void main(String[] args){
        try {
          PrintWriter output = new PrintWriter(new FileWriter("file.txt"));
          output.println("Hello");
          output.close();

          BufferedReader input = new BufferedReader(new FileReader("file.txt"));
          String line;
          while ((line = input.readLine()) != null) {
            System.out.println("Read:"+line);
          }
          input.close();
        } catch(IOException e) {
          System.out.println(e);
        }
      }
    }

Object serialization

A Java object can be represented (i.e. frozen in its current state) as a sequence of bytes. The following example prints out those bytes to console:

    import java.io.ObjectOutputStream;
    import java.io.ObjectInputStream;
    String[] arr={"abc","def"};
    ObjectOutputStream so = new ObjectOutputStream(System.out);
    so.writeObject(arr);

Object serialization and persistence to file

One way of keeping such representation persistently is to store it in a file:

    import java.io.FileInputStream;
    import java.io.FileOutputStream;
    import java.io.ObjectOutputStream;
    import java.io.ObjectInputStream;

    class SerializationTester {
      public static void main(String[] args) {
        try {
          String[] arr={"abc","def"};
          ObjectOutputStream so = new ObjectOutputStream(new FileOutputStream("file.txt"));
          so.writeObject(arr);
        } catch(Exception e) {}

        try {
          ObjectInputStream so = new ObjectInputStream(new FileInputStream("file.txt"));
          String[] s=(String[])(so.readObject());
          for (int i=0;i<s.length;i++)
            System.out.println(s[i]);
        } catch(Exception e) {}

      }
    }

Creating serializable classes

All you need to do is to declare that your class implements Serializable interface, and make sure that all data fields are objects whose classes support Serializable (almost all Java library classes do):

    import java.io.Serializable;
    class Square implements Shape, Serializable {
     ...
    }

Example: shape store

    import java.io.FileInputStream;
    import java.io.FileOutputStream;
    import java.io.ObjectOutputStream;
    import java.io.ObjectInputStream;
    import java.io.Serializable;

    class ShapeStore implements Serializable{
      public static void main(String[] args) {
        ShapeStore store;
        try {
          ObjectInputStream so = new ObjectInputStream(new FileInputStream("shapestore.txt"));
          store=(ShapeStore)so.readObject();
        } catch(Exception e) {
          store=new ShapeStore(30);
        }
        System.out.println(store);
        if (args[0].equals("Circle")) {
          System.out.println("adding a circle");
          store.addShape(new Circle(Double.parseDouble(args[1])));
        }
        try {
          ObjectOutputStream so = new ObjectOutputStream(new FileOutputStream("shapestore.txt"));
          so.writeObject(store);
        } catch(Exception e) {
          System.out.println(e);
        }

      }
      Shape[] shapes;
      int stored;
      ShapeStore(int capacity){
        shapes=new Shape[capacity];
        stored=0;
      }
      void addShape(Shape s) {
         shapes[stored++]=s;
      }
      public String toString() {
        return String.format("Store with %d shapes",stored);
      }
    }

Home Exercise: A library

Implement a library class which can store multiple resources, and persists itself onto file system.