Transcript Document
Java Review 3
Java Wrapper Classes
• In Java, the term wrapper class commonly refers to a set of Java
classes that “objectify” the primitive Java types.
– That is, for each primitive type, there is a corresponding Java “Wrapper” class
that represents that type.
– e.g. the wrapper for the int type is the Integer class.
• Wrapper Classes are based upon the well-known software engineering
design pattern called the Wrapper pattern.
– A design pattern is a template solution to a common problem. It describes
the problem and identifies the recommended solution(s) to that problem.
– Because design patterns deal with common problems, they are often quite
abstract!
Wrapper Design Pattern
– Some code (the client) needs a class to use a certain interface (which it does not
use).
• The problem:
– e.g. we want to store an int in a Vector, but Vectors do not accept primitive
types.
• The Solution:
– We create another class that wraps the underlying class/type and provides an
appropriate interface for the client.
– e.g. we create an Integer class that subclasses Object (as all classes do),
allowing us to store wrapped int’s in Vectors.
Example that will not work
import java.util.Vector;
public class MyApp {
public static void main(String[] args) {
int myValue = 2;
Vector myVector = new Vector();
The compiler detects
myVector.addElement(myValue);
an error here
for (int x=0; x < myVector.size(); x++) {
System.out.println(“Value: “ + myVector.get(x));
}
}
}
Example that will work
import java.util.Vector;
public class MyApp {
Here we wrap the
public static void main(String[] args) {
int in the Integer
int myValue = 2;
class
Vector myVector = new Vector();
myVector.addElement(new Integer(myValue));
for (int x=0; x < myVector.size(); x++) {
System.out.println(“Value: “ + myVector.get(x));
}
}
}
Java Wrapper Classes
Object
Boolean
Byte
Short
Void
Number
String
Character
Integer
Long
Float
Double
Some Useful Methods
• The Java Wrapper Classes include various useful methods:
– Getting a value from a String
e.g. int
value = Integer.parseInt(“33”);
sets value to 33.
– Converting a value to a String:
e.g. String
str = Double.toString(33.34);
sets str to the String “33.34”.
– Getting a wrapper class instance for a value:
e.g. Integer
obj = Integer.getInteger(“12”);
creates a new Integer object with value 12 and makes obj refer to that object.
Some Useful Methods
– Getting the maximum permitted int value
e.g. int
value = Integer.MAX_VALUE;
sets value to 2147483647.
– Getting the minimum permitted int value
e.g. int
value = Integer.MIN_VALUE;
sets value to -2147483647.
– Getting the value in an Integer object
e.g. int
value = new Integer(545).intValue();
sets value to 545.
Reading a Double
import java.io.*;
class MyProgram {
public static void main(String[] args) {
BufferedReader in = new BufferedReader(
new InputStreamReader(System.in));
String line = null;
System.out.println("Input Something:" );
try {
line = in.readLine();
} catch (IOException ie) {
System.out.println("Exception caught: " + ie);
}
try {
double value = Double.parseDouble(line);
System.out.println("Value: " + value);
} catch (NumberFormatException nfe) {
System.out.println("You didn't enter a double number");
}
}
}
Interfaces in Java
• In Object-Oriented terms, the interface of a class is the set of public
methods and data members of that class.
– These methods and data members describe how external code (I.e. other
classes) can interact with the class.
– Once a class is made publicly available for use, great care is required when
changing that classes interface.
• E.g. consider how annoyed you would be if Sun changed the interface of the
System class from System.out to System.cout…
• Java supports the definition of interfaces independent of
implementation of that interface.
– A Java interface is a named collection of method definitions (without
implementation). An interface can also include constant declarations.
– In Java, we define an interface using the interface keyword.
Example Interface
• Let us consider a general security service for web
applications.
– We don’t always know how we wish to validate users, so we cannot
implement a general user validation algorithm.
– So, we create an interface that describes what a security service
should do, and leave it to the developer of a specific application to
implement a particular security service.
interface SecurityService {
public boolean validateUser(String uid, String pwd);
public static final String ADMIN_USERNAME = “Admin”;
}
Interfaces in Java
• The definition of the methods described in a Java interface is the
responsibility of any class that implements that interface.
• If a class implements an interface, then it must include definitions for
all of the methods described in that interface.
– If you do not include definitions for all the methods, the class will not compile!
• A powerful feature of Java interfaces is that they can be implemented
in more than one class!
– For example, our SecurityService interface could be implemented as:
• A DatabaseSecurityService, which looks validates the username and password
against a database table, or
• A SimpleSecurityService, which validates the username and password against
hardcoded values for the username and password.
Interface Example
interface SecurityService {
public boolean validateUser(String uid, String pwd);
public static final String ADMIN_USERNAME = “Admin”;
}
class SimpleSecurityService implements SecurityService {
public boolean validateUser(String uid, String pwd) {
if (uid.equals(ADMIN_USERNAME) &&
pwd.equals(“god”)) {
return true;
}
return false;
}
}
Using Interfaces + Implementations
• Java interfaces can be used as types.
– For example:
SecurityService service;
• Variables or attributes whose type is an interface can be used to
reference any class the implements that interface.
– For example:
SecurityService service = new SimpleSecurityService();
• When an object is cast as an interface, only those methods declared in
the interface may be accessed.
– For example:
boolean valid = service.validateUser(“rem”,
“hi”);
A simple login program
import java.io.*;
class MyProgram {
public static String readUserInput() {
BufferedReader in = new BufferedReader(
new InputStreamReader(System.in));
try {
return in.readLine();
} catch (IOException ie) {
System.out.println("Exception caught: " + ie);
}
return null;
}
A simple login program
public static void main(String[] args) {
System.out.print(“Username:”);
String username = readUserInput();
System.out.print(“Password:”);
String password = readUserInput();
SecurityService service = new SimpleSecurityService();
if (service.validateUser(username, password)) {
System.out.println(“Valid User”);
} else {
System.out.println(“Invalid User”);
}
}
}
Some Comments…
• Another way in which we could have coded this example is through
inheritance and abstract classes.
class SecurityService {
public abstract boolean validateUser(String uid, String pwd);
public static final String ADMIN_USERNAME = “Admin”;
}
class SimpleSecurityService extends SecurityService {
public boolean validateUser(String uid, String pwd) {
if (uid.equals(ADMIN_USERNAME) && pwd.equals(“god”)) {
return true;
}
return false;
}
So, what is the need for interfaces?
• It is not always possible for us to use inheritance to deliver the
required interface.
– Remember: Java supports only single inheritance. That is, a class has exactly
one parent class.
• Whilst a class can have only one parent class, it can implement many
interfaces.
– A class includes both private and public methods and attributes.
– Java interfaces only define what methods must be implemented, not how to
implement them!
– So, we can write classes that subclass some parent class and implement one or
more interfaces!
– But when is this useful?
Another Example
• Lets consider an alarm clock service.
– This service notifies objects after a certain amount of time has
passed.
– It is implemented through two components:
• An AlarmClock class that implements the service, and
• A Sleeper interface that classes wishing to use the service must implement.
– Whenever an object wishes to sleep, it contacts an alarm clock
instance requesting that it be allowed to sleep for a specified time.
– Once that specified time has passed, the alarm clock tells the
sleeping object to “wake up”.
The AlarmClock class
import java.util.ArrayList;
class AlarmClock {
public static void letMeSleepFor(Sleeper sleeper, long time) {
new AlarmThread(sleeper, time).start();
}
}
The AlarmThread class
class AlarmThread extends Thread {
private Sleeper sleeper;
private long time;
public AlarmThread(Sleeper sleeper, long time) {
this.sleeper = sleeper;
this.time = time;
}
public void run() {
try {
sleep(time);
} catch (Exception e) {
System.out.println(“Failed to sleep”);
}
sleeper.wakeUp();
}
}
The Sleeper interface
interface Sleeper {
public static final long ONE_MINUTE = 60000;
public static final long ONE_SECOND = 1000;
public void wakeUp();
}
public class TestSleeper implements Sleeper {
private int iterations;
public TestSleeper() {
iterations = 0;
}
public void wakeUp() {
Iterations++;
System.out.println("Woken up for the " + iterations + " time.");
AlarmClock.letMeSleepFor(this, ONE_SECOND);
}
}
The Applet POC
• So, what happens when we want an Applet to use this
service?
class ClockApplet extends Applet implements Sleeper {
// . . .
public void wakeUp() {
repaint();
AlarmClock.letMeSleepFor(ONE_MINUTE);
}
// . . .
}
• Obviously, we could not use inheritance here…