Download SoftwareDevelopmentLifecycle

Document related concepts
no text concepts found
Transcript
Software Jobs
• Not all of you are going to be programmers
– but you should know how to design, program, test, debug
software
• Other types of jobs:
–
–
–
–
–
–
–
Designer
Tester
Database, Network, Security Administrator
Project Leader
Manager
Professor
etc …
• NOTE: designers & programmers on a project may not
be the same people
Design, then develop
• We will design all classes before coding
– not easy to do
– UML is used for software design
• You cannot design a system unless you really
understand the necessary technology
– designs cannot be created without a little testing
• trying out different small-scale examples (HWs 1-5)
The HW Plan
HW 1 - GUIs & Events
HW 2 - Database Integration
HW 3 - 2D Graphics & Timers
HW 4 - UML Design
HW 5 – Multi-threading
HW 6 – Final Project
What is a framework?
• Groups of classes that form the basis for customization
– cooperating classes for a particular technology
• ex: multimedia, the Web, databases, etc.
– used to build new applications & other frameworks
– what’s Java’s application framework for the domain of GUI
development?
• Swing (a framework built on the AWT framework)
Applications Using Frameworks
Framework
App1 calls
methods of
Framework
objects
Framework calls
methods of App1
& App2 objects
Application #1
• How can this happen?
App2 calls
methods of
Framework
objects
Application #2
Other Java Frameworks
Table 1: Java Frameworks
Application
Frameworks
Database
JRelational
Intelligent Agents
Jade, JAF, ABLE
Logging
Java logging framework, Log4J
Multimedia
JMF
Networking
RMI
Testing
JUnit, Cactus, JFCUnit, Abbot, Hansel
Web Development
Struts, WebWork, SOFIA, Cocoon, JBoss, JOFFAD
XML
Dom4j, JBind
Others
Java Collections, BSF, Joone, ...
Framework Documentation
• Frameworks are more than just one class, but
many classes working together
• Framework developers must explain how to use
them all together properly
– API
– Tutorials
• Frameworks are open source as well as for
purchase, ex:
– http://www.j2eeolympus.com/J2EE/Servlets/ServletsFrameworks.jsp
– http://www.runtime-collective.com/JavaXML.html
Who cares?
• We are constantly using Java frameworks
• Think about how you might create a framework
• Gaining the ability to make frameworks will
make you a powerful developer
Your Project?
Make that Minesweeper++
• We’ll add lots of stuff:
–
–
–
–
–
–
accounts
detailed stats and records
custom board building
colors and themes
zombies
and more
So where were we?
• We learned to use Swing to:
– create a window (JFrame)
– arrange components in our window
– react to user interactions
• Note: so far, we are only using pre-made components
– JButton, JTextField, etc.
– these have pre-programmed options for:
• rendering
• behavior
What’s next?
• How will we render our zombies?
• How can we respond to mouse dragging?
So what do we need from Java?
• How do we load an image?
• How can we render an image where we like?
• Law of Efficient Programming:
– load each image no more than once
– Why?
• a game may have many similar images
• load each image once, use it as many times as you like
Loading Images
• Use Java’s java.awt.Toolkit class
– a Singleton class with some useful odds and ends
methods
• 2 important methods for us in this class:
– getDefaultToolkit
– createImage method
• loads images from a file name or URL
• .jpg, .gif, .bmp, .png
• WARNING: this is done asynchronously
Image Loading Example
• Let’s load a single image called cat.jpg
…
private Toolkit tk = Toolkit.getDefaultToolkit();
private Image catImage;
…
…
catImage = tk.createImage("cat.jpg");
…
• At some point we will render catImage
– WARNING: did I mention Image loading is done asynchronously
Asynchronous Image Loading?
• Who cares?
– you should
• What does asynchronous image loading mean?
– you call createImage
• Java spawns a thread to load image
– while loading, your program continues to run
– so?
• your program might try to render an image before its
loaded
A solution: MediaTracker
• Tell Java to wait for an image to load before continuing
• 2 Options:
– wait for each image one at a time by ID
– add all images with unique IDs and then
waitForAll
• Option 1 Example:
catImage = tk.createImage("cat.jpg");
MediaTracker tracker = new MediaTracker(this);
int catId = 9;
tracker.addImage(catImage, catId);
try { tracker.waitForID(catId); }
Option 2 Example
MediaTracker tracker = new MediaTracker(this);
catImage = tk.createImage("cat.jpg");
tracker.addImage(catImage, 0);
dogImage = tk.createImage("dog.jpg");
tracker.addImage(dogImage, 1);
armadilloImage = new
tk.createImage("armadillo.jpg");
tracker.addImage(armadilloImage, 2);
try { tracker.waitForAll(); }
catch (InterruptedException ie) {}
// CODE DOWN HERE WILL ONLY START TO EXECUTE
// AFTER ALL 3 IMAGES HAVE BEEN COMPLETELY
// LOADED INTO MEMORY AND ARE READY TO BE USED
Where will be draw our images?
• On a JPanel
• Why?
– because they’re blank canvases
• To do this:
– define your own JPanel
– customize how its rendered
Drawing on a JPanel
• Define a class that extends JPanel
– include necessary instance variables
• would have data about the items to be drawn
• images, locations, etc.
– override the paintComponent method
• inherited from JComponent
• do all image (and shape & text) rendering inside
• paintComponent
– called on all GUI components
– we can plug in our own custom rendering
Panel Rendering
public class MyPanel extends JPanel
{
// INSTANCE VARIABLES CONTAINING
// INFO ABOUT EVERYTHING TO BE
RENDERED
public void paintComponent(Graphics
g)
{
// code for drawing will go here
}
}
public void paintComponent(Graphics g)
• Never call this method yourself
• You will be tempted to. Why?
– you changed the map
– now you want to change what’s rendered
• Instead, to redraw your panel
– call repaint on your panel object (
• in response to events
• or in response to a timer (for animation)
An approach to defining
paintComponent
• Anticipate changes in what gets rendered
– think dynamically
• Render according to instance variables
• Carefully map out your logic
– remember: design, design, design
Graphics
• Stores settings for rendering:
– current Color to use (text and shapes)
– current Font to use (text)
• Has methods for rendering
– images, rectangles, ovals, and text
• Specify all locations and sizes in pixels
– (0, 0) coordinate is top-left corner of panel
Some Methods of the Graphics
Class
• To change rendering settings:
– setColor
– setFont
• To render:
– drawImage
– drawString
– drawLine
– drawRect
– fillRect
– drawOval
– fillOval
Colors
• setColor
– select a color used for all subsequent drawing. Ex:
• 13 Standard Colors:
– black, blue, cyan, darkGray, gray, green,
lightGray, magenta, orange, pink, red,
white, yellow
– Ex:
g.setColor(Color.red);
• More than 4 billion custom colors:
– Color(int red, int green, int blue)
– Red, blue, and green are values from 0-255
– Ex:
g.setColor(new Color(255, 0, 0));
Rendering Images
• Inside paintComponent:
– call drawImage on the Graphics object
– specify:
•
•
•
•
image object
x location in the panel (from left)
y location in the panel (from top)
we won’t use the ImageObserver (use null)
• drawImage(Image img, int x, int y, ImageObserver observer)
• Ex:
g.drawImage(catImage, 100, 200, null);
How can we respond to mouse clicks on our panel?
• Define our own event handler (a MouseListener)
– make it an inner class of panel
• Respond inside one of 5 methods:
–
–
–
–
–
mousePressed
mouseReleased
mouseClicked
mouseEntered
mouseExited
• For your panel:
– declare your handler as an instance variable
– construct your handler
– register your handler with the panel
How can we respond to mouse dragging on our panel?
• Define our own event handler (a MouseMotionListener)
– make it an inner class of panel
• Respond inside one of 2 methods:
– mouseDragged
– mouseMoved
• For your panel:
– declare your handler as an instance variable
– construct your handler
– register your handler with the panel
Example: mixing Graphics & Events
• Create a GUI with a panel on which we will
render lots of 2 different images
– Logo1.png & Logo2.png
• When the user mouse clicks on the panel
– Logo 1 will from then on be drawn there
• Wherever the user drags the mouse on the panel:
– Logo 2 will from then on be drawn there
public class ImageFrame extends JFrame
{ private ImagePanel imagePanel;
public ImageFrame()
{
super("ImageFrame");
setExtendedState(MAXIMIZED_BOTH);
setDefaultCloseOperation(EXIT_ON_CLOSE);
layoutGUI();
}
public void layoutGUI()
{
imagePanel = new ImagePanel();
this.add(imagePanel, BorderLayout.CENTER);
}
public static void main(String[] args)
{
ImageFrame frame = new ImageFrame();
frame.setVisible(true);
}
public class ImagePanel extends JPanel
{
// EVENT HANDLERS
private MouseHandler mouseHandler;
private MouseMotionHandler mouseMotionHandler;
// FOR IMAGE LOADING AND RENDERING
private Toolkit tk;
private Image logo1Image;
private Image logo2Image;
private Vector<Point2D.Double> logo1Locations;
private Vector<Point2D.Double> logo2Locations;
public ImagePanel()
{
// INITIALIZE THE TOOLKIT
tk = Toolkit.getDefaultToolkit();
// AND THE 2 IMAGES WE'RE USING
MediaTracker tracker = new MediaTracker(this);
logo1Image = tk.createImage("Logo1.png");
tracker.addImage(logo1Image, 1);
logo2Image = tk.createImage("Logo2.png");
tracker.addImage(logo2Image, 2);
try { tracker.waitForAll(); }
catch (InterruptedException ie) {}
// AND THE VECTORS FOR THE POINTS
logo1Locations = new Vector<Point2D.Double>();
logo2Locations = new Vector<Point2D.Double>();
// LISTEN FOR MOUSE CLICKS AND DRAGGING ON THE PANEL
mouseHandler = new MouseHandler();
this.addMouseListener(mouseHandler);
mouseMotionHandler = new MouseMotionHandler();
this.addMouseMotionListener(mouseMotionHandler);
}
public void paintComponent(Graphics g)
{
super.paintComponent(g);
// DRAW ALL THE LOGO1s
Iterator<Point2D.Double> it1 =
logo1Locations.iterator();
while(it1.hasNext())
{
Point2D.Double p = it1.next();
g.drawImage(logo1Image, (int)p.x, (int)p.y, null);
}
// DRAW ALL THE LOGO2s
Iterator<Point2D.Double> it2 =
logo2Locations.iterator();
while(it2.hasNext())
{
Point2D.Double p = it2.next();
g.drawImage(logo2Image, (int)p.x, (int)p.y, null);
}
}
class MouseHandler extends MouseAdapter
{
public void mouseClicked(MouseEvent me)
{
int x = me.getX();
int y = me.getY();
Point2D.Double point = new Point2D.Double(x,y);
if (!logo1Locations.contains(point))
logo1Locations.add(point);
repaint();
}
}
class MouseMotionHandler extends MouseMotionAdapter
{
public void mouseDragged(MouseEvent me)
{
int x = me.getX();
int y = me.getY();
Point2D.Double point = new Point2D.Double(x,y);
if (!logo2Locations.contains(point))
logo2Locations.add(point);
repaint();
}
}
}
This semester I intend to brainwash you
• Important Principles for creating a Software Solution:
•
•
•
•
•
•
•
•
•
First, define the problem
Design, then code
Always Provide Feedback
First, define the problem
Design, then code
Always Provide Feedback
First, define the problem
Design, then code
Always Provide Feedback
•
•
•
•
•
•
•
•
•
First, define the problem
Design, then code
Always Provide Feedback
First, define the problem
Design, then code
Always Provide Feedback
First, define the problem
Design, then code
Always Provide Feedback
Do you remember why we’re here?
• To learn a methodology for constructing
software systems of high quality
• Do you remember:
– what makes software high quality?
– the Software Development Life Cycle?
What properties make a software system high quality?
• Correctness
• Efficiency
• Ease of use
– for the user
– for other programmers using your framework
•
•
•
•
•
Reliability/robustness
Reusability
Extensibility
Scalability
Maintainability, Readability, Modifiability,
Testability, etc.
Correctness
• Does the program perform its intended function?
– And does it produce the correct results?
• This is not just an implementation (coding) issue
– Correctness is a function of the problem definition
• A flawed Requirements Analysis results in a
flawed Design
• A flawed Design results in a flawed program
Efficiency
• Plan for efficiency
– wisely choose your data structures & algorthms,
O(N), in the design phase
– tools & technologies too
• Does the program meet user performance
expectations?
• If not, find the bottlenecks
– done after implementation
Ease of Use for End User
• Is the GUI easy to learn to use?
– a gently sloped learning curve
• What makes a GUI easy to use?
–
–
–
–
familiar GUI structures
familiar icons when possible instead of text
components logically organized & grouped
appealing to look at
• colors, alignment, balance, etc.
– forgiving of user mistakes
– help, tooltips, and other cues available
Ease of Use for other Programmers
• In particular for frameworks
– think of the Java API developers
• Should you even build a framework?
• What makes a framework easy to use?
–
–
–
–
–
–
logical structure (should mirror problem)
naming choices (classes, methods, etc.)
flexibility (usable for many purposes)
feedback (exceptions for improper use)
documentation (APIs & tutorials)
etc.
Reliability/Robustness
• Does your program:
– anticipate erroneous input?
– anticipate all potential program conditions?
– handle erroneous input intelligently?
• again, think about this in the design stage
– provide graceful degradation?
• What’s graceful degradation?
Graceful Degradation
• An error condition occurs in your program
• Should your program:
–
–
–
–
crash?
exit?
notify the user and exit?
provide an approximated service?
• not always possible
• Web Browsers
– What does they do with poorly formatted HTML?
Feedback, Feedback, Feedback, Feedback
•
•
•
•
•
•
•
•
•
•
Feedback
Feedback
Feedback
Feedback
Feedback
Feedback
Feedback
Feedback
Feedback
Feedback
• Feedback
• Feedback
• Feedback
• Feedback
Feedback to whom?
• End user due to:
– bad input, equipment failure, missing files, etc.
• How?
– popup dialogs, highlighting (red x in Web form), etc.
• Other programmers using your framework due to:
– passing bad data, incorrect initialization, etc.
• How?
– exception throwing, error value returning, etc.
Flexibility in a Framework
• Programmers need to know:
– when and why things in a framework might go wrong
AND
– When and why things in a framework do go wrong
• Why?
– customized response
– Ex:
• System.out.println notification
• JOptionPane notification
• Web page generated and sent via Servlet notification
• use alternative services
• etc.
Applications Using Frameworks
Framework
App1 calls
methods of
Framework
objects
Framework calls
methods of App1
& App2 objects
Application #1
App2 calls
methods of
Framework
objects
Application #2
• Note, making a framework is much more
difficult than making an application. Why?
Reusability
• Code serving multiple purposes
• Who cares?
– management does
• avoid duplication of work (save $)
– software engineering does
• avoid duplication of work (save time & avoid mistakes)
• How can we achieve this?
– careful program decomposition
Extensibility
• Can the software easily be extended?
• Huh?
– can it be used for other purposes
• Ex:
–
–
–
–
plug-ins
exporters
add-ons
etc
Extensibility Example
• In eclipse, try HelpInstall New Software
• Work With:
– http://download.eclipse.org/releases/galileo/
• Anyone can make an eclipse plug-in
Scalability
• How will the program perform when we
increase:
– # of users/connections
– amount of data processed
– # of geographic locations users are from
• A function of design as well as technology
And More
•
•
•
•
•
Maintainability
Readability
Modifiability
Testability
etc.
• All of these, as with the others, must be
considered early in design
How can these properties be achieved?
• By using well proven, established processes
– preferably while taking advantage of good tools
Requirements
Analysis
Design &
Document
Evaluate
Design
Code
Test
Profile
Debug
• Software Development Life Cycle
Deploy
Hopefully, the point of no return
• Correctness, Efficiency, Ease of use,
Reliability/robustness, Reusability,
Maintainability, Modifiability, Testability,
Extensibility, Scalability
• When should we consider these properties?
– the requirements analysis & design stages
• How about the implementation stages?
– too late to make a big impact
Where to begin?
• Understand and Define the problem
–
–
–
–
the point of a requirements analysis
What are system input & output?
How will users interact with the system?
What data must the system maintain?
• Generate a problem specification document
– defines the problem
– defines what needs to be done to solve the problem
– HW 3
Requirements Analysis
• i.e. Software Specification (spec.)
• A textual document
• It serves two roles. It:
– defines the problem to be solved
– explains how to solve it
• This is the input into the software design stage
What goes in a requirements analysis (RA)?
• The why, where, when, what, how, and who
–
–
–
–
–
Why are we making this software?
Where and when will it be created?
What, exactly, are we going to make?
How are we going to make it?
Who will be performing each role?
What really goes in a RA?
• Detailed descriptions of all:
–
–
–
–
necessary data
program input and output
GUI screens & controls (
user actions and program reactions
• For a database:
– necessary forms & views
Where do you start?
• Interviews (really)
• Who do you interview?
– end users
• What do they need?
• What do they want?
Design Approaches
• Have other “similar” problems been solved?
– Do design patterns exist to help?
• What are the “easy” and “hard” parts?
– Why is this important?
• work measurement
• Employ:
– data-driven design
– top-down design
Data-driven Design
• From the problem specification, extract
– nouns (objects, attributes of objects)
– verbs (methods)
• Divide data into separate logical, manageable groupings
– these will form your objects
• Note needs for data structures or algorithms
– design your data management classes early on
Top-down class design
• Top-down class design strategy:
–
–
–
–
Decompose the problem into sub-problems (large chunks).
Write skeletal classes for sub-problems.
Write skeletal methods for sub-problems.
Repeat for each sub-problem.
• If necessary, go back and redesign higher-level classes
to improve:
–
–
–
–
modularity
information hiding
information flow
etc.
Designing Methods
• Decide method signatures
– numbers and types of parameters and return values
• Write down what a method should do
– use top-down design
• decompose methods into helper methods
• Use javadoc comments to describe methods
• Use method specs for implementation
Results of Top-down class design
UML Class Diagrams
Skeletal Classes
• instance variables
• static variables
• class diagrams
• method headers
• DOCUMENTATION
Class relationships
• Think data flow:
–
–
–
–
–
–
What HAS what?
What IS what?
What USES what?
Where should data go?
How will event handler X change data in class Y?
Static or non-static?
• Design patterns will help us make these decisions
• Bottom line: think modular
– no 1000 line classes or 100 line methods
Modularity
• How reusable are your classes?
– can they be used in a future project?
• Think of programmers, not just users
• Can individual classes be easily separated and re-used
• Data vs. Mechanics
• Functionality vs. Presentation
Functionality vs. Presentation
• What is a game state manager (GSM)?
– classes that do the work of managing data & enforcing rules
on that data
• Why separate the GSM and the UI?
–
–
–
–
so we can change the GSM without changing the UI
so we can change the UI without changing the GSM
so we can design several different UIs for an GSM
reuse code that is proven to work
• This is a common principle throughout GUI design
– even for Web sites (separate content)
Choosing Data Structures
• Internal data structures
– What is the natural representation of the given data?
• grid should be stored in its natural state (2D)
– Setup vs. access speeds
– Keep data ordered?
• Which access algorithms?
• Ordered by what?
Evaluating the Design
• Periodic reviews are necessary
– redesign is less costly during the design stage than after
• Is the design correct?
– according to the problem description
• Will it work efficiently?
• Are the classes independent?
– Encapsulation – Do they manage & protect their own data?
– Can they be tested individually?
– Do they produce code reuse?
• Is there redundancy? Is it necessary?
– Reduce redundancy wherever possible
• Is data and control flow clear or complex?
Software Longevity
• The FORTRAN & COBOL programming
languages are almost 50 years old
– many mainframes still use code written in the 1960s
– software maintenance is more than ½ a project
• Moral of the story:
– the code you write may outlive you, so make it:
• Easy to understand
• Easy to modify & maintain
– software must be ready to accommodate change
Software Maintenance
• What is software maintenance?
• Improving or extending existing software
–
–
–
–
–
–
incorporate new functionality
incorporate new data to be managed
incorporate new technologies
incorporate new algorithms
incorporate use with new tools
incorporate things we cannot think of now
Summary
• Always use data driven & top-down design:
–
–
–
–
identify and group system data
identify classes, their methods and method signatures
determine what methods should do
identify helper methods
• Write down step by step algorithms inside methods to help you!!!
– document each class, method and field
– specify all conditions that need to be enforced or checked
• decide where to generate exceptions
• add to documentation
– evaluate design, and repeat above process
• until implementation instructions are well-defined
Design Patterns
• Design Pattern
– A description of a problem and its solution that you
can apply to many similar programming situations
• Patterns:
– facilitate reuse of good, tried-and-tested solutions
– capture the structure and interaction between
components
Why is this important?
• Using proven, effective design patterns can
make you a better software designer & coder
• You will recognize commonly used patterns in
others’ code
– Java API
– Project team members
– Bitter ex-employees
Common Design Patterns
• Some we’ll look at closely:
–
–
–
–
–
–
–
–
The Command Pattern
The Factory Pattern
The Flyweight Pattern
The Iterator Pattern
The Observer Pattern
The Singleton Pattern
The State Pattern
The Strategy Pattern
• Others we may see:
–
–
–
–
–
–
The Adapter Pattern
The Bridge Pattern
The Composite Pattern
The Decorator Pattern
The Proxy Pattern
The Visitor Pattern
In addition, different technologies
have their own patterns:
Servlet patterns, GUI patterns, etc …
But First Let’s Review Objects
• Let’s quickly review some concepts heavily used
by design patterns:
– Abstraction & Objects
– Static vs. Non-static
What is abstraction?
• Ignoring certain low-level details of a problem to
get a simpler solution
– Logical first step in any design
– What parts of the problem can be abstracted out to a higherlevel solution?
• Abstraction Techniques:
–
–
–
–
–
Type Abstraction
Abstraction by Specification
Iteration Abstraction
Data Abstraction
etc.
Type Abstraction
• Abstract from individual data types to families of
related types
– a many to one map
• How can we do this?
– Inheritance & Polymorphism via:
• Polymorphic variables
• Polymorphic methods (arguments & return type)
• To understand type abstraction, we should first know
how objects are managed by Java
Types
• A type specifies a well-defined set of values
– example: int, String
• Java is a strongly typed language, what does this mean?
– compiled Java programs are guaranteed to be type safe
• except in the case of improper object casting
– Generics is one way to avoid this problem
– Ex: ArrayList<Film> films
= new ArrayList<Film>();
– Java also uses automatic storage management
• Helps avoid many errors from C & C++
– the Java compiler checks the code to ensure that every
assignment & every call is type correct
• type checking is always done using an object’s apparent type
Java object management
• Local variables are stored on the runtime stack
–
–
–
–
space is allocated (pushed) when a method is called
space is de-allocated (popped) when a method returns
includes object handles for local variables
Note, in CSE 220 you’ll learn the details of how this is done
• Object data is stored on the system heap
– instance variables
• Objects in the heap continue to exist as long as they are
reachable from some variable still on the heap or stack
– a variable that hasn’t been removed by the garbage collector
– you may force garbage collection using System.gc() or
Runtime.gc()
Example
public void someMethod()
{
int i = 4;
int[] a = new int[3];
…
String s = "abc";
s2 = "cba";
}
Where would s2 be?
STACK
i
4
a
s
[0, 0, 0]
RUNTIME
-String data cba in global region
-S2 variable storing memory
location of cba may be in heap
(if s2 is an instance variable) or
in global (if s2 is a static
variable)
RUNTIME
HEAP
Instance variable of String
class of type char[]
['a', 'b', 'c']
GLOBALS
When someMethod completes, what will be garbage collected?
Apparent vs. Actual Type
• Each constructed object has an apparent type and an
actual type
– due to the rules of polymorphism
– only methods of an objects apparent type are available
– Java guarantees the apparent type of any object is an ancestor
of its actual type (or the same)
– Ex:
Vector v = new Vector();
// what are v’s apparent & actual types?
Object o1 = v;
// what are o1’s apparent & actual types?
int[] a = {1, 2};
Object o2 = a;
// what are o2’s apparent & actual types?
• Remember where polymorphism is particularly important?
– method arguments & return statements
• like readObject & writeObject
java.util.Hashtable
• A Hashtable maps keys to values
– done by mapping Objects (usually Strings) to Objects
– http://java.sun.com/j2se/1.5/docs/api/java/util/Hashtable.html
• Ex:
Hashtable dates = new Hashtable();
dates.put("TODAY", new GregorianCalendar());
dates.put("DDAY", new GregorianCalendar(
1944, Calendar.JUNE,6));
dates.put("ENDOFWORLD", new GregorianCalendar(
2004, Calendar.OCTOBER, 27));
…
Object obj = dates.get("ENDOFWORLD"); OUTPUT: Oct 27, 2004
Calendar whatDate = (Calendar)obj;
DateFormat df =
DateFormat.getDateInstance(DateFormat.MEDIUM);
String dateString = df.format(whatDate.getTime());
System.out.println(dateString);
Potential for Runtime Error!
OUTPUT: What happens if I add dates.put(“NOW", new Date()) ?
Hashtable using generics
• Alternative: constraint ArrayList, Ex:
Hashtable<String, Calendar> dates = new OUTPUT: Oct 27, 2004
Hashtable<String, Calendar>();
dates.put("TODAY", new GregorianCalendar());
dates.put("DDAY", new GregorianCalendar(1944,
Calendar.JUNE,6));
dates.put("ENDOFWORLD", new GregorianCalendar(2004,
Calendar.OCTOBER, 27));
Calendar whatDate = dates.get("ENDOFWORLD");
DateFormat df =
DateFormat.getDateInstance(DateFormat.MEDIUM);
String dateString = df.format(whatDate.getTime());
System.out.println(dateString);
OUTPUT: What happens if I add dates.put("NOW", new Date()) ?
Compiler Error!
Which would you prefer, a runtime or compiler error?
Where’s the type abstraction?
• The Hashtable class can store any type of
Object
• Using generics, a Hashtable object can be
constrained to enforce the storage only of a
particular type of class
• Inside the Hashtable class:
– Object[] keys
– Object[] values
java.util.ArrayList class
• ArrayList implements List
– can be passed to any method that takes a List object,
like:
• Collections.binarySearch
– uses Comparator for comparisons
• Collections.reverseOrder
• Collections.shuffle
• Collections.sort
– uses Comparable for comparisons
• You could also define your own class that
implements List
– then define the 25 abstract methods in List
public class Employee implements Comparable {
private String name;
private int salary;
public Employee(String initName, int initSal) {
name = initName;
salary = initSal;
}
public String getName(){ return name; }
public int getSalary() { return salary; }
public void setSalary(int newSalary) {
salary = newSalary;
}
public int compareTo(Object o) {
Employee otherEmp = (Employee)o;
if (this.salary == otherEmp.salary)
return 0;
else if (this.salary > otherEmp.salary)
return 1;
else
return -1;
}
public String toString() {
return name + ", $" + salary;
}
}
Ex: Allowing Employees to be sorted by salary
Using ArrayLists
import java.util.*;
public class CollectionsTester {
public static void main(String[] args) {
ArrayList<Employee> staff
= new ArrayList<Employee>();
Employee e = new Employee("Joe",100000);
staff.add(e);
e = new Employee("Jane",200000);
staff.add(e);
e = new Employee("Bob",66666);
staff.add(e);
Collections.sort(staff);
Employee lowestPaid = (Employee)staff.get(0);
System.out.println(lowestPaid);
}
}
Output:
Bob, $66666
Where’s the type abstraction?
• The Comparable interface provides a standard means
for communication with yet unknown types of objects
• What does that mean?
– It means Employee guarantees an abstract, standard mode of
behavior (compareTo)
– So, Collections.sort can sort Employee objects
• by calling the Employee class’ compareTo method
• Why is this important to us?
– Design patterns use lots of type abstraction
More on actual vs. apparent
• So:
– Apparent data type of an object determines what
methods may be called
– Actual data type determines where the
implementation of a called method is defined
• Starts looking in the actual type class & works its way up
public class Parent {
public void print() {
System.out.println("Parent");
}
}
public class Child extends Parent {
public void print() {
System.out.println("Child");
}
}
public class Driver {
public static void display(Parent p2) {
p2.print();
}
public static void main(String[] args) {
Parent p = new Parent();
display(p);
Child c = new Child();
display(c);
Parent
}
}
Child
Output?
Interfaces
• Specify abstract methods
– method headers with no bodies
• Ex:
public interface ActionListener
{
public int actionPerformed(ActionEvent ae);
}
• Any class that implements ActionListener
guarantees it will define actionPerformed
– else a syntax error
• So, Java’s event handling framework can call your
event handler (your ActionListener’s
actionPerformed)
Abstract Classes
• Can specify abstract and concrete methods
• Any class that extends an abstract class:
– guarantees it will define all abstract methods, ex:
public abstract class AbstractDie {
protected int upValue = 1;
protected int numSides = 6;
public abstract void roll();
public int getUpValue() { return upValue; }
}
public class Die extends AbstractDie {
public void roll() {
upValue = (int)(Math.random()*6)+ 1;
}
}
Interfaces/Abstract classes & Polymorphism
• Similar rules of polymorphism apply
• Objects can have an apparent type of:
– A concrete class
– An interface
– An abstract class
• Ex:
public void addActionListener(
ActionListener listener)
• Objects can never have the actual type of an
interface or abstract class. Why?
– they have no constructors
static vs. non-static
• static methods and variables are important to
many design patterns
• What’s the difference?
– static (class) methods & variables are shared by
an entire class
• one static variable for all objects to share
– Non-static (object) methods & variables are not
shared by an entire class
• each object owns its non-static methods & variables
static usage
• Can a static method:
– directly call (without using a “.”) a non-static method in
the same class?
– directly call a static method in the same class?
– directly reference a non-static variable in the same class?
– directly reference a static variable in the same class?
• Can a non-static method:
– directly call (without using a “.”) a non-static method in
the same class?
– directly call a static method in the same class?
– directly reference a non-static variable in the same class?
– directly reference a static variable in the same class?
1 public class Nothing {
2 private int nada;
3 private static int nothing;
4
5 public void doNada()
{ System.out.println("NADA");
}
6 public static void doNothing()
{ System.out.println("NOTHING"); }
7
8 public static void myStaticMethod()
{
9
doNada();
10
doNothing();
11
nada = 2;
12
nothing = 2;
13
Nothing n = new Nothing();
14
n.doNada();
15
n.nada = 2;
16 }
17
18 public void myNonStaticMethod() {
19
doNada();
20
doNothing();
21
nada = 2;
22
nothing = 2;
23
Nothing n = new Nothing();
24
n.doNada();
25
n.nada = 2;
26 }
27}