230 likes | 374 Views
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 N D
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; publicclass MyApp { publicstaticvoid main(String[] args) { int myValue = 2; Vector myVector = new Vector(); myVector.addElement(myValue); for (int x=0; x < myVector.size(); x++) { System.out.println(“Value: “ + myVector.get(x)); } } } The compiler detects an error here
Example that will work import java.util.Vector; publicclass MyApp { publicstaticvoid main(String[] args) { int myValue = 2; Vector myVector = new Vector(); myVector.addElement(new Integer(myValue)); for (int x=0; x < myVector.size(); x++) { System.out.println(“Value: “ + myVector.get(x)); } } } Here we wrap the int in the Integer class
Java Wrapper Classes Object Boolean Void Number String Character Byte Short Integer Long Float Double
Some Useful Methods • The Java Wrapper Classes include various useful methods: • Getting a value from a Stringe.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 objecte.g. int value = new Integer(545).intValue();sets value to 545.
Reading a Double import java.io.*; class MyProgram { publicstaticvoid 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 { publicboolean validateUser(String uid, String pwd); publicstaticfinal 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 { publicboolean validateUser(String uid, String pwd); publicstaticfinal String ADMIN_USERNAME = “Admin”; } class SimpleSecurityService implements SecurityService { publicboolean validateUser(String uid, String pwd) { if (uid.equals(ADMIN_USERNAME) && pwd.equals(“god”)) { returntrue; } returnfalse; } }
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 { publicstatic 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 publicstatic 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 { publicabstract boolean validateUser(String uid, String pwd); publicstaticfinal String ADMIN_USERNAME = “Admin”; } class SimpleSecurityService extends SecurityService { publicboolean validateUser(String uid, String pwd) { if (uid.equals(ADMIN_USERNAME) && pwd.equals(“god”)) { returntrue; } returnfalse; }
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 { publicstatic void letMeSleepFor(Sleeper sleeper, long time) { new AlarmThread(sleeper, time).start(); } }
The AlarmThread class class AlarmThread extends Thread { private Sleeper sleeper; privatelong time; public AlarmThread(Sleeper sleeper, long time) { this.sleeper = sleeper; this.time = time; } publicvoid run() { try { sleep(time); } catch (Exception e) { System.out.println(“Failed to sleep”); } sleeper.wakeUp(); } }
The Sleeper interface interface Sleeper { publicstaticfinallong ONE_MINUTE = 60000; publicstaticfinallong ONE_SECOND = 1000; publicvoid wakeUp(); } publicclass TestSleeper implements Sleeper { privateint iterations; public TestSleeper() { iterations = 0; } publicvoid 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 { // . . . publicvoid wakeUp() { repaint(); AlarmClock.letMeSleepFor(ONE_MINUTE); } // . . . } • Obviously, we could not use inheritance here…