380 likes | 500 Views
Object Oriented Programming. Lecture 2: Inheritance, Polymorphism, First Design pattern, Interface, Exceptions, Enumeration Types www2.hh.se/staff/jebe/oop2006/. Abstract Data types . We have seen that we can define new data types by creating new classes
E N D
Object Oriented Programming Lecture 2: Inheritance, Polymorphism, First Design pattern, Interface, Exceptions, Enumeration Types www2.hh.se/staff/jebe/oop2006/
Abstract Data types • We have seen that we can define new data types by creating new classes • A Class implements a Contractual Interface (the public parts of the class) • A Class has a state representation (variables should preferrably be private) • The implementation of the class • Implement the methods (accessors,mutators) • Implement methods for testing (repOk())
The Rational Class Desired functionality? (The contractual interface, ie the methods required) Constructors (establish the invariant): Rational(), Rational(int num), Rational(int num,int den) Arithmetic operations (methods): Plus(Rational a, Rational b) Minus(Rational a, Rational b) Times(Rational a, Rational b) Div(Rational a, Rational b) Other methods: toString(), equals(Object x), compareTo(Object x), repOk()
The Rational Class The implementation: Class Rational{ private int num; private int den; public Rational(){ this(0,1); } public Rational(int num, int den){ if(den == 0) throw ArithmeticException(”Zero denominator”); else{ this.num = den<0 ? –num,num this.den = Math.abs(den); simplify(); } } } State representation, hidden (encapsulated) Make sure the invariant is established!!
Extending Rationals to Complex Numbers • Complex numbers is an extension of Rational numbers • The real and imaginary components are Rationals! (1/2 + j1/2) • Complex arithmetic can be formed as a composite of Rational arithmetic (1/2 + j1/2) + (1/2 +j1/2) = (1/1 + j1/1) • The idea: We let Complex inherit Rational properties by extending the Rational Class
Extending to Complex Numbers public class Complex extends Rational{ //State representation private Rational real; private Rational imag; /** * Constructor for injecting Rational Complex vector components */ public Complex(Rational re, Rational im){ real = re; imag = im; } /** * Arithmetic Plus for Complex valued numbers */ public Complex plus(Complex c1, Complex c2){ return new Complex(plus(this.real,c.real()),plus(this.im,c.im())); } ... ... } Plus in Complex overloads the inherited plus in Class Rational
Recapitulation • When we create software models of ”real world systems”, we use Classes to define: • Abstract Data Types (immutable, variables for representing the abstract data) • Objects (mutable, instance variables that hold a state, methods implements the algorithms) • In Java - Integer, Float, Double (Wrapper classes) are example of immutables • Wrapper Classes are used to ”wrap” primitive datatypes into objects when needed
Recapitulation • In both cases important terms are: • Hiding the implementation (encapsulation) • Prevents misuse • Programming to an interface (Abstraction) • Modularity, Extendability, Reusability... • Establishing and preserving the invariant • Objects must be in a legal state after creation and after manipulation by a method • The equals method • To compare State equality of objects
Interfaces • Interface is a special type of Class • An Interface declares only abstract methods that must be defined in a class • Thus, an interface has no implemented methods itself – methods are defined in the implementing class • Only constants are allowed to be specified • Interfaces can inherit from other Interfaces • Super Interfaces and Sub Interfaces
Interface Drawable{ public int aValue = 1; public void draw(Graphics g); public int getWidth(); public int getHeight(); } Public Class Square implements Drawable{ int xSide,ySide,posX,posY; public void draw() { g.drawRect(posX,posY,xSide,ySide); } public int getWidth() { return ySide; } public int getHeight() { return xSide; } } Interface Example Constants allowed
Abstract Classes • An abstract class has at least one method implemented • Other methods can be abstract • Thus, and abstract class is a class with partial implementation • Like with an Interface, abstract methods must be implemented by the class that extends the abstract class
public abstract class Shape { protected Point location; protected Shape(Point loc) { location = loc; } public void move(int dx,int dy){location.move(dx,dy);} public abstract void draw(); } Public Class Square extends Drawable{ int xSide,ySide; public Square(int x,int y) { super(new Point(x,y));} public void draw() { g.drawRect((int)location.getX(), (int)location.getY(), xSide, ySide); } public int getWidth() { return ySide; } public int getHeight() { return xSide; } } Abstract Class Example
Polymorphism • The term polymorphic origins from Greek • Poly ≈ many • Morphos ≈ forms/shapes • Roughly, polymorphic objects are objects with features of a similar kind • That is - objects that shares an interface but has different algorithms
Example - Polymorphic shapes in a drawing program Common functionality for shapes... Shape Circle Square Rectangle ...how to draw a shape is defined in each specific object of shape type
Conversion between types • Conversion of a subtype to a supertype is called widening • Widening is always allowed to do • Conversion of a supertype to a subtype is called narrowing (downcasting) • Allowed at compile time, not always safe • Dynamic binding • The specific method is bound at runtime • In the shape example, method “draw” is bound to a specific shape type during run time • Let us see an example from an old exam...
A few things about Throwables & Exceptions • Exceptions are unexpected or faulty conditions in a program • When a fault occurs, an exception can be thrown and the normal program flow is interrupted • Three kinds of Throwables: • Error (severe!) • RuntimeException (for example ”array out of bounds”) • Exception (User defined exception should extend this)
Exceptions Serious Fault! OutOfMemoryError Thrown By JVM! Error ArithmeticException AssertionError Throwable ClassCastException RuntimeException IndexOutOfBoundsException NullpointerException Exception Io-Exception Any program!
Catching Exceptions Exceptions are caught & handled with a ”try-catch-clause”: Try{ a = b[i]; }catch (ArrayOutOfBoundsException e){ ”exception handling code here...” }finally{...clean up before leaving} (...finally is not necessary) User defined exceptions must extend class Exception: MyVeryOwnException extends Exception{ super(”A terrible error has occured!”); }
Throwing Exceptions • Most Exceptions are thrown by the JVM • But Exceptions can also be thrown anywhere in a program: Public int example(void) throws MyException{ ”method code...” throw new MyException(); } • Method calls to methods that has a throws statement must be encapsulated with ”try-catch” clause • The exception should be handled in ”catch” or be thrown to the object that was calling the method.
A new type Pen – Mutable Object What functionality do we want when using a pen(interface)? Constructor pen() Methods for changing the state of a pen(instance methods) void lift() void push() void move(double d) void turn(double alpha) Methods for assigning a drawing area to our pen void setPaper(Paper p)
Pen is a mutable object Pen thePen; ... public void recLine(int n, double length){ if (n==0) thePen.move(length); else{ int m = n-1; double shorter = length/3.0; double alpha = Math.PI/3; recLine(m,shorter); thePen.turn(-alpha); recLine(m,shorter); thePen.turn(2*alpha); recLine(m,shorter); thePen.turn(-alpha); recLine(m,shorter); } } Modifies the state of the pen itself! Pen is mutable
Let’s take a look at:move(double d) public void move(double d){ double oldx = x; double oldy = y; x = Math.min(x+d*Math.cos(alpha),paper.width()); y = Math.min(y+d*Math.sin(alpha),paper.height()); if(down) paper.drawLine((int)oldx,(int)oldy,(int)x,(int)y); }
Our first design pattern:Observer-Observable • Now, let’s examine the properties of a Paper. width A paper is a Canvas that has height and width dimensions in pixels. It also has a paint method to show the lines drawn by the Pen. height Canvas is an AWT component The view of a paper!
Paper (Model) Add a new line Width Height Add Observer Register changes Notify the Observers Paperview (View) Override the paint method so that it paints the state of the model (lines) Define the method update so a change in the model will be reflected in the view Observer – ObservableSeparation of model and view
Extending Observable • The Observable class implements methods for keeping and interacting with a set of Observers • Adding Observers to the Set • Notifying Observers of changes by calling the Observers update method • By extending Paper with Observable we will have access to all necessary methods • We only need to know which are the Observers
The Paper Class: Observable public class Paper extends Observable{ private Vector lines; private int width, height; … public Paper(int width, int height){ this.width = width; this.height = height; lines = new Vector(); } public void drawLine(int a, int b, int c, int d){ lines.add(new Line(a,b,c,d)); setChanged(); notifyObservers(); } ... We have added a line... Register the change in Observer! Notify the Observers!
The PaperView Class public class PaperView extends Canvas implements Observer{ private Paper paperModel; public PaperView(Paper p){ paperModel = p; paperModel.addObserver(this); … } public void update(Observable o, Object arg){ try{Thread.sleep(200);}catch(Exception e){} repaint(); } public void paint(Graphics g){ Iterator iter = paperModel.iterator(); while(iter.hasNext()){ Line line = (Line)iter.next(); g.drawLine(line.v, line.w, line.x, line.y); } } } Called when notifying observers! How we paint the lines!
The Java I/O Framework • The I/O framework is designed to be flexible and easy to configure • Java has two main types of I/O: • Stream IO • Supports reading/writing sequentially • A stream can only be open for read or write, not both • Random Access I/O • Reading and writing at any position in a file • File I/O can be open both for read/write • We focus at Stream I/O • Two kinds of streams: bytes or charachter
I/O Byte Streams • The basic I/O streams are: • Input Stream • read(); - reads byte • read(byte[] a); - reads byte array • read(byte[] a, int off, int len); - reads part of byte array • skip(long n); - skips over n bytes • close(); - closes the stream • OutputStream • write(b); - writes byte • write(byte[] a); - writes byte array • write(byte[] a, int off, int len); - writes part of byte array • close(); - closes the stream
Reading from files • FileInputStream/FileOutputstream are sub classes of Input/OutputStream byte streams (overloads the methods) • But byte streams are hardly convenient to use directly, requires ”low-level manipulation” • Bitmasking and conversion • This kind of ”low-level” is rarely necessary • Most data are represented by Objects
Buffered Streams • BufferedInputStream and BufferedOutputStream (extends java.io.FilterInputStream) • Reads data via an internal buffer • BufferedReader and BufferedWriter (extends java.io.Reader) • Abstract streams for reading String/Charachter data • Can be used to read entire Strings
Object serialization • Java supports Object serialization • Objects can be passed as arguments to a stream • The objects are transparently serialized to a sequence of bytes • Objects must implement Serializable interface (java.io.Serializable) • ObjectInputStream and ObjectOutPutStream • FileInputStream/FileOutPutStream as arguments for file access
Enumeration Types • Enumeration types: • A finite set of distinct values • Example of Enumerated types: • Date = Mon|Tue|Wed|Thu|Fri|Sat|sun • Direction = North|East|South|West • We can use the Enumerated Types like any other type in our program • Ex. Date d = Monday; • The Enumerated types should be typesafe
Enumerated types • Some languages like C/C++ support enumerated types... • In C or C++, we would write: enum Date {Mon,Tue,Wed,Thu,Fri,Sat,Sun}; Date day1 = Tue; Date day2 = Fri; If(day1 == day2){....} • Untill Java 1.5 was released, Java didn’t support typesafe enumerated types • Before 1.5 a common (but bad) solution: Treat enumeration types as static int constants.
A Type safe Idiom • Type-Safe Enumeration Idiom • Each value will be distinct (unique) • A printable, descriptive name rather that just an Integer number • Let’s look at two examples: • An ”unordered” Type-Safe Enumeration • An ”ordered” Type-Safe Enumeration
Typesafe enumeration in Java 1.5 Public class Card{ public enum Rank { Deuce, Three, Four, Five, Six, Seven, Eight, Nine, Ten, Jack, Queen, King, Ace} public enum Suit{ Clubs, Diamonds, Hearts, Spades } private final Rank rank; private final Suit suit; private Card(Rank r, Suit s){ rank = r; suit = s; } public toString(); }
So far in the course... • We have defined: • Classes and Objects • Interface and Abstract classes • Inheritance and Polymorhpism • Mutable and Immutable objects • A First Design pattern • Exceptions • Enumeration types
That was it for today... • Pen and Paper example as an exercise next week • Type safe enum can be read about in JDK 5.0 documentation • Next week: • More design patterns • The Collections Framework • Etc...