1 Todays Objectives Announcements Homework #1 is due next week Return Quiz 1 – answers are posted...
-
Upload
jase-ireton -
Category
Documents
-
view
220 -
download
2
Transcript of 1 Todays Objectives Announcements Homework #1 is due next week Return Quiz 1 – answers are posted...
1
Today’s Objectives
Announcements• Homework #1 is due next week
Return Quiz 1 – answers are posted on the Yahoo discussion page site
Basic Java Programming• Looping with while• Using java.util.Stack• Capturing keyboard input with java.util.Scanner
Implementing a data structure as a class – a stack example• Interfaces – Specifying the methods that a class must implement• Generics – Implementing a data structure so it can be used with any data type• Exceptions – adding robustness
– Using inheritance to create exception classes derived from RuntimeException
– Throwing and catching an exception
Bonus Lab – creating a generic class
Week 4
2
Return Quiz 1
Answers are posted on the Yahoo discussion group site under “Files”
3
Basic Java Programming
while loop, switch, using java.util.Stack,
using java.util.Scanner
4
while, switch, java.util.Stack
(From last week’s slides)
5
Finishing SimpleSolitaire
Capturing keyboard input with java.util.Scanner
Implementing the game in SimpleSolitaire
6
Implementing SimpleSolitaire
public static final Scanner IN = new Scanner(System.in);
public void play() { while (true){ System.out.println("\n" + this); boolean done = true; for (Stack<Card> s : stacks){ if (!(s.isEmpty())){ done = false; break; } } if (done){ System.out.println("You win!"); return; } System.out.println("pair,suit,deal,or quit?"); String command = IN.nextLine(); if (command.equals("pair")) { removePair(); } else if (command.equals("suit")) { removeLowCard(); } else if (command.equals("deal")) { dealFourCards(); } else return;}
Here’s the game loop in the play() method.
Basic Java Programming (Flanagan; Drake)
Print a prompt for the user
Capture the user's input as a String
Then we test the input and branch to the correct method call
We added a Scanner object as an instance variable to help with input
SimpleSolitaire.java
7
Implementing SimpleSolitaire
public static final Scanner IN = new Scanner(System.in);
public void play() { while (true){ System.out.println("\n" + this); boolean done = true; for (Stack<Card> s : stacks){ if (!(s.isEmpty())){ done = false; break; } } if (done){ System.out.println("You win!"); return; } System.out.println("pair,suit,deal,or quit?"); String command = IN.nextLine(); if (command.equals("pair")) { removePair(); } else if (command.equals("suit")) { removeLowCard(); } else if (command.equals("deal")) { dealFourCards(); } else return;}
We still need to implement removePair() and removeLowCard()
Basic Java Programming (Flanagan; Drake)
SimpleSolitaire.java
8
Implementing SimpleSolitaire
public static final Scanner IN = new Scanner(System.in);
public void play() { while (true){ System.out.println("\n" + this); boolean done = true; for (Stack<Card> s : stacks){ if (!(s.isEmpty())){ done = false; break; } } if (done){ System.out.println("You win!"); return; } System.out.println("pair,suit,deal,or quit?"); String command = IN.nextLine(); if (command.equals("pair")) { removePair(); } else if (command.equals("suit")) { removeLowCard(); } else if (command.equals("deal")) { dealFourCards(); } else return;}
We still need to implement removePair() and removeLowCard()
Basic Java Programming (Flanagan; Drake)
public void removePair() { System.out.println("Card location (1-4)"); int i = IN.nextInt(); System.out.println("Card location (1-4)"); int j = IN.nextInt(); IN.nextLine();//clear input stacks[i - 1].pop(); stacks[j - 1].pop();}
The Scanner object can be used in any method
SimpleSolitaire.java
What happens on these lines? stacks[i - 1].pop(); stacks[j - 1].pop();
9
Implementing SimpleSolitaire
public static final Scanner IN = new Scanner(System.in);
public void play() { while (true){ System.out.println("\n" + this); boolean done = true; for (Stack<Card> s : stacks){ if (!(s.isEmpty())){ done = false; break; } } if (done){ System.out.println("You win!"); return; } System.out.println("pair,suit,deal,or quit?"); String command = IN.nextLine(); if (command.equals("pair")) { removePair(); } else if (command.equals("suit")) { removeLowCard(); } else if (command.equals("deal")) { dealFourCards(); } else return;}
We still need to implement removePair() and removeLowCard()
Basic Java Programming (Flanagan; Drake)
public void removePair() { System.out.println("Card location (1-4)"); int i = IN.nextInt(); System.out.println("Card location (1-4)"); int j = IN.nextInt(); IN.nextLine();//clear input stacks[i - 1].pop(); stacks[j - 1].pop();}
The Scanner object can be used in any method
public void removeLowCard() { System.out.println("Low card (1-4)"); int i = IN.nextInt(); System.out.println("High card (1-4)"); int j = IN.nextInt(); IN.nextLine();//clear input stacks[i - 1].pop();}
SimpleSolitaire.java
10
Implementing SimpleSolitaire
public String toString(){ StringBuilder result = new StringBuilder(); for (int i=0; i<4; i++){ if (stacks[i].isEmpty()){ result.append("-- "); } else{ result.append(stacks[i].peek() + " "); } } result.append("\n" + deck.size() + " cards left in the deck"); return result.toString();}
The last method to implement is toString()
Basic Java Programming (Flanagan; Drake)
SimpleSolitaire.java
Why use “isEmpty”?
What does “peek” do?
Why use “deck.size()”?
11
Implementing SimpleSolitaire
public String toString(){ StringBuilder result = new StringBuilder(); for (int i=0; i<4; i++){ if (stacks[i].isEmpty()){ result.append("-- "); } else{ result.append(stacks[i].peek() + " "); } } result.append("\n" + deck.size() + " cards left in the deck"); return result.toString();}
The last method to implement is toString()
Basic Java Programming (Flanagan; Drake)
SimpleSolitaire.java
Why use “isEmpty”?
What does “peek” do?
Why use “deck.size()”?
Rank
Spades Hearts Clubs
If the game in progress looks like the picture below, what should toString() print?
12
Implementing Main
package edu.uhcl.sce.simplesolitaire;
public class Main{ public static void main(String[] args) { System.out.println("Simple Solitaire"); SimpleSolitaire game = new SimpleSolitaire(); game.play(); }}
The complete code for the console version is posted on the Yahoo site.
Basic Java Programming (Flanagan; Drake)
Main.java
13
Implementing a Data Structureas a Class
A Stack Example
14
What are we making?Start with the Stack ADT
Goodrich, p. 189
Implementing a Data Structure as a Class
pop()Remove and return the top element on the stack; an error occurs if the stack is empty
E
top()Return the top element on the stack without removing it; an error occurs if the stack is empty.
E
push( E element )Insert element at the top of the stack
void
isEmpty()Indicate whether the stack is empty
boolean
size()Return the number of elements in the stack
int
15
Java Interface
A language element in Java that contains only method declarations
Has no data and no method bodies; and it cannot be used to instantiate an object
Useful for specifying a list of operations that a class must implement
• All its methods should be public• Use the word interface in its declaration• A class can implement an interface by using implements in its
declaration and then implementing all methods of the interface
Implementing a Data Structure as a Class (Goodrich, 80–83)
16
Using a Java Interfacewith a Data Structure
The ADT specifies what the data structure should do, but not how to do it
First create a Java interface that specifies the ADT(The interface should be in a separate file)
Then implement the interface with the class that creates the data structure
package edu.uhcl.sce.arraystack;
public interface Stack{ public void push(Character element); public Character pop(); public Character top(); public int size(); public boolean isEmpty();}
Implementing a Data Structure as a Class (Goodrich, 80–83)
package edu.uhcl.sce.arraystack;
public class ArrayStack implements Stack{ //more code here}
Stack.javaArrayStack.java
17
Step 1 – Create the interface from the ADT
Declare methods in the interface for all the public operations that are called for by the ADT
(See Goodrich, p. 189, for the stack ADT.)
Implementing a Data Structure as a Class
All methods in the interface should be “public” so that they are accessible in any part of your program where there is an object of this class.
package edu.uhcl.sce.arraystack;
public interface Stack { public int size(); public boolean isEmpty(); public void push(Character c); public Character top(); public Character pop();}
Stack.java
18
package edu.uhcl.sce.arraystack;public class ArrayStack implements Stack{}
Step 2 – Start writing the class
Open a .java file and name it “ArrayStack.java”
Write the package statement
Write the keywords “public class” followed by the name of the class
Implementing a Data Structure as a Class
Implement the interface
ArrayStack.java
19
package edu.uhcl.sce.arraystack;public class ArrayStack implements Stack{ public int size(); public boolean isEmpty(); public void push(Character c); public Character top(); public Character pop();}
Step 3 – Declare the public operations
Declare member functions in the class for all the public operations that are in the interface
Implementing a Data Structure as a Class
The declarations of all methods should be identical to the declarations in the interface.
ArrayStack.java
20
package edu.uhcl.sce.arraystack;public class ArrayStack implements Stack{ private int capacity;//Max capacity of the array private Character[] myArray; public int size(); public boolean isEmpty(); public void push(Character c); public Character top(); public Character pop();}
Step 4 – Declare instance variables
Next, decide how to hold the data that the data structure will contain. For example, you could put it into either an array or a linked list.
Implementing a Data Structure as a Class
All instance variables labeled “private” are only accessible to the methods of this class.
ArrayStack.java
21
package edu.uhcl.sce.arraystack;public class ArrayStack implements Stack{ private int capacity;//Max capacity of the array private Character[] myArray; public int size(); public boolean isEmpty(); public void push(Character c); public Character top(); public Character pop();}
Step 4 – Declare instance variables
Next, decide how to hold the data that the data structure will contain. For example, you could put it into either an array or a linked list.
Implementing a Data Structure as a Class
All instance variables labeled “private” are only accessible to the methods of this class.
Information hiding
Instance variables are always “private” so that the object’s client cannot change the data by accessing it directly.
Data can be accessed only by using the “public” member functions.
ArrayStack.java
22
Step 5 – Define the operations
Now, decide how to implement the operations
Implementing a Data Structure as a Class
package edu.uhcl.sce.arraystack;public class ArrayStack implements Stack{ private int topIndex; private int capacity;//Max capacity of the array private Character[] myArray; public int size(); public boolean isEmpty(); public void push(Character c); public Character top(){return myArray[topIndex];} public Character pop();}
ArrayStack.java
23
Step 6 – Add a constructor
package edu.uhcl.sce.arraystack;public class ArrayStack implements Stack{ private int topIndex; private int capacity;//Max capacity of the array private Character[] myArray; public ArrayStack(int cap){ topIndex = -1; capacity = cap; myArray = new Character[capacity]; }
public int size();public boolean isEmpty();public void push(Character c);public Character top(){return myArray[topIndex];}public Character pop();
}
Implementing a Data Structure as a Class
• Public member function with the same name as the class and no return type
• Called automatically whenever an object is instantiated
• Initializes the data members
ArrayStack.java
24
Step 6 – Add a default constructor
package edu.uhcl.sce.arraystack;public class ArrayStack implements Stack{ public static final int CAPACITY = 1024; private int topIndex; private int capacity;//Max capacity of the array private Character[] myArray; public ArrayStack(){ this(CAPACITY); } public ArrayStack(int cap){ topIndex = -1; capacity = cap; myArray = new Character[capacity]; }
public int size();public boolean isEmpty();public void push(Character c);public Character top(){return myArray[topIndex];}public Character pop();
}
Implementing a Data Structure as a Class
• Constructor with no arguments
• Calls the overloaded constructor with the default capacity as an argument
ArrayStack.java
25
Step 6 – Add exceptions
Add robustness – use exceptions
Implementing a Data Structure as a Class (Goodrich 76)
26
UML Diagram for ArrayStack
– capacity : int– myData : Character[ ]– topIndex : int
+ ArrayStack(in cap : int )+ ArrayStack()+ size() : int+ isEmpty() : boolean+ push( in c : Character )+ top() : Character+ pop() : Character
Class name – top section
Instance variables – middle section
Implementing a Data Structure as a Class (Stevens)
Methods – bottom section
+ size() : int+ isEmpty() : boolean+ push( in c : Character )+ top() : Character+ pop() : Character
<<interface>>Stack
ArrayStack
27
Syntax Exercise
Handout
Handout
28
Using ArrayStack with Any Data
So far, our ArrayStack class will do an acceptable job of containing data of the type Character
What happens if we want to store something else in our stack?• Brute force solution – Write a different
stack class for every type of data we might want to store
Implementing a Data Structure as a Class
What’s the disadvantage of that approach?
29
Generics
Better approach• Write a generic class• A generic class can store any kind of data
Instead of making a stack of Character objects, we can make a stack of any kind of objects
The behavior of the stack will be the same for any data type that is stored in it and we only need to write the code once
The data type is specified by a parameter
Implementing a Data Structure as a Class (Goodrich, 89–90)
30
Generics
Allow us to use one data structure class for storing objects of any data type
Syntax
public class ArrayStack<E>implements Stack<E>{
private E[] myArray;
//more code
Implementing a Data Structure as a Class (Goodrich, 89–90)
31
Generics
Allow us to use one data structure class for storing objects of any data type
Syntax
public class ArrayStack<E>implements Stack<E>{
private E[] myArray;
//more code
Implementing a Data Structure as a Class (Goodrich, 89–90)
Angle brackets
32
Generics
Allow us to use one data structure class for storing objects of any data type
Syntax
public class ArrayStack<E>implements Stack<E>{
private E[] myArray;
//more code
Implementing a Data Structure as a Class (Goodrich, 89–90)
Angle brackets
“E” is a placeholder – the compiler will replace this letter
with an actual data type
33
Generics
Allow us to use one data structure class for storing objects of any data type
Syntax
public class ArrayStack<E>implements Stack<E>{
private E[] myArray;
//more code
Implementing a Data Structure as a Class (Goodrich, 89–90)
Angle brackets
“E” is a placeholder – the compiler will replace this letter
with an actual data type
The interface is generic, too
34
Making ArrayStack Intoa Generic Class
package edu.uhcl.sce.arraystack;public class ArrayStack { public static final int CAPACITY = 1024; private int topIndex; private int capacity;//Max capacity of the array private Character[] myArray; public ArrayStack(){ this(CAPACITY); } public ArrayStack(int cap){ topIndex = -1; capacity = cap; myArray = new Character[capacity]; } public int size(){return topIndex + 1;} public boolean isEmpty(){return topIndex < 0;} public void push(Character c){ myArray[++topIndex] = c; } public Character top(){return myArray[topIndex];} public Character pop(){ return myArray[topIndex--]; }}
Implementing a Data Structure as a Class
1. Implement the class for a specific data type
35
Making ArrayStack Intoa Generic Class
package edu.uhcl.sce.arraystack;public class ArrayStack<E> implements Stack<E>{ public static final int CAPACITY = 1024; private int topIndex; private int capacity;//Max capacity of the array private Character[] myArray; public ArrayStack(){ this(CAPACITY); } public ArrayStack(int cap){ topIndex = -1; capacity = cap; myArray = new Character[capacity]; } public int size(){return topIndex + 1;} public boolean isEmpty(){return topIndex < 0;} public void push(Character c){ myArray[++topIndex] = c; } public Character top(){return myArray[topIndex];} public Character pop(){ return myArray[topIndex--]; }}
Implementing a Data Structure as a Class
2. Add <E>
36
Making ArrayStack Intoa Generic Class
package edu.uhcl.sce.arraystack;public class ArrayStack<E> implements Stack<E>{ public static final int CAPACITY = 1024; private int topIndex; private int capacity;//Max capacity of the array private Character[] myArray; public ArrayStack(){ this(CAPACITY); } public ArrayStack(int cap){ topIndex = -1; capacity = cap; myArray = new Character[capacity]; } public int size(){return topIndex + 1;} public boolean isEmpty(){return topIndex < 0;} public void push(Character c){ myArray[++topIndex] = c; } public Character top(){return myArray[topIndex];} public Character pop(){ return myArray[topIndex--]; }}
Implementing a Data Structure as a Class
3. Find all the locations of the data type of the elements in the class
37
Making ArrayStack Intoa Generic Class
package edu.uhcl.sce.arraystack;public class ArrayStack<E> implements Stack<E>{ public static final int CAPACITY = 1024; private int topIndex; private int capacity;//Max capacity of the array private E[] myArray; public ArrayStack(){ this(CAPACITY); } public ArrayStack(int cap){ topIndex = -1; capacity = cap; myArray = new E[capacity]; } public int size(){return topIndex + 1;} public boolean isEmpty(){return topIndex < 0;} public void push( E c){ myArray[++topIndex] = c; } public E top(){return myArray[topIndex];} public E pop(){ return myArray[topIndex--]; }}
Implementing a Data Structure as a Class
4. Substitute “E” for the data type of the elements in the class
38
Making ArrayStack Intoa Generic Class
package edu.uhcl.sce.arraystack;public class ArrayStack<E> implements Stack<E>{ public static final int CAPACITY = 1024; private int topIndex; private int capacity;//Max capacity of the array private E[] myArray; public ArrayStack(){ this(CAPACITY); } public ArrayStack(int cap){ topIndex = -1; capacity = cap; myArray = (E[])new Object[capacity]; } public int size(){return topIndex + 1;} public boolean isEmpty(){return topIndex < 0;} public void push( E c){ myArray[++topIndex] = c; } public E top(){return myArray[topIndex];} public E pop(){ return myArray[topIndex--]; }}
Implementing a Data Structure as a Class
5. Use this special syntax for the array instance variable
39
Instantiating a Stack with a Generic Class
Include it in your package (or import it)package edu.uhcl.sce.arraystack;
Instantiate a stack with the default sizeArrayStack<Character> myStack;
myStack = new ArrayStack<Character>();
Instantiate a stack with a specific sizeArrayStack<Character> smallStack;smallStack = new ArrayStack<Character>(10);
Implementing a Data Structure as a Class
Name of the class Type of data in it
Use "new" to allocate memory and call the constructor
Size of the stack
Name of the stack object Parentheses are required
40
Problem with the Implementation
ArrayStack is not robust
What happens when an operation is used in an unexpected way?
package edu.uhcl.sce.arraystack;public class Main{ public static void main(String args[]){ ArrayStack<Character> stack; stack = new ArrayStack<Character>(); System.out.print(stack.top()); //undefined }}
Implementing a Data Structure as a Class
41
Exceptions
Unexpected problems that occur when the program is running• Occur infrequently• Affect the operation of the program
Examples• Trying to access an array outside of its bounds• Calling top() on an empty stack• Trying to pop() an element from an empty stack• Trying to push() an element onto a full stack
Implementing a Data Structure as a Class (Goodrich, 92)
42
Java Exception Objects
Java exception objects• Allow exceptions to be handled so the program doesn’t crash and
doesn’t behave in an undefined way – more robust code• The program is written so that the code “throws” an exception in
response to an unexpected event• Then the exception is “caught” and an appropriate action can
occur
Exception• Super class for more specific exception classes
RuntimeException• The class used for throwing runtime exceptions in your program• When there’s a potential error, a RuntimeException object is
instantiated and used in the exception-handling procedures
Implementing a Data Structure as a Class (Goodrich, 76–79)
43
Java Exception Handling
Procedure for handling unexpected errors
• Write methods so that they automatically detect a potential error condition such as popping from an empty stack
• In the program, we “try” the method
• If there is a error condition, the method will “throw” an exception as a signal to the calling program that something is wrong
• Then the calling program will “catch” the exception, and it can take appropriate action
Implementing a Data Structure as a Class (Goodrich, 76–79)
44
Try-Catch Block
Used for exception handling
When a method might throw an exception, its call is placed inside a “try block”
try{//...
}
If an exception is thrown by a method call inside the block, then program control goes to the next block after the try block, which must be a “catch block”
catch( RuntimeException e ){//...
}
At that point, the program can take appropriate action
Implementing a Data Structure as a Class (Goodrich, 92)
45
Try-Catch Example
If we write the “top()” method so that it throws an exception whenever the stack is empty, then we can catch the exception like this:
Call top() in a try block.
public static void main(String[] args){ ArrayStack<Character> myStack = new ArrayStack<Character>(); try{ System.out.println(myStack.top()); } catch( RuntimeException e ){ System.out.println(e.getMessage()); } System.out.println("Skipped catch");}
If everything works, the program skips the catch block.
Implementing a Data Structure as a Class
46
Try-Catch Example
If we write the “top()” method so that it throws an exception whenever the stack is empty, then we can catch the exception like this:
Call top() in a try block.
If top() throws an exception, the exception object goes to the catch block.
Implementing a Data Structure as a Class
public static void main(String[] args){ ArrayStack<Character> myStack = new ArrayStack<Character>(); try{ System.out.println(myStack.top()); } catch( RuntimeException e ){ System.out.println(e.getMessage()); } System.out.println("Skipped catch");}
47
Try-Catch Example
If we write the “top()” method so that it throws an exception whenever the stack is empty, then we can catch the exception like this:
Call top() in a try block.
If top() throws an exception, the exception object goes to the catch block.
Implementing a Data Structure as a Class
public static void main(String[] args){ ArrayStack<Character> myStack = new ArrayStack<Character>(); try{ System.out.println(myStack.top()); } catch( RuntimeException e ){ System.out.println(e.getMessage()); } System.out.println("Skipped catch");}
The catch block has a reference to the exception object as an argument.
48
public static void main(String[] args){ ArrayStack<Character> myStack = new ArrayStack<Character>(); try{ System.out.println(myStack.top()); } catch( RuntimeException e ){ System.out.println(e.getMessage()); } System.out.println("Skipped catch");}
Try-Catch Example
If we write the “top()” method so that it throws an exception whenever the stack is empty, then we can catch the exception like this:
Call top() in a try block.
If top() throws an exception, the exception object goes to the catch block.
The getMessage() method returns a String.
Implementing a Data Structure as a Class
49
Throwing an Exception
When a method detects a potential error, it can “throw an exception”1. Create an exception object and throw it2. The method stops3. The exception object is returned to the calling program –
control goes to the calling program at the appropriate catch block
Example of a method that throws an exception
Implementing a Data Structure as a Class
public Character top() {
if(topIndex < 0) throw new RuntimeException("Empty Stack");
return myArray[topIndex];
}“new” is required
Check for a potential error
Use “throw”Instantiate the exception object
50
Exception Specification
When writing a method that throws an exception, you can specify which exceptions the method can throw
• Called the “throw list” or “exception specification”
If an exception is listed in this exception specification, the method is not required to catch it – it can be caught in the calling method
Example Exception specification
public Character top() throws RuntimeException {
if(topIndex < 0) throw new RuntimeException("Empty Stack");
return myArray[topIndex];
}
Implementing a Data Structure as a Class (Goodrich, 77; Deitel)
51
Using Inheritance to Create Exception Classes
Inheritance allows reuse of code that is common between related classes
We can use RuntimeException as a base class for specialized exception classes that we use in our data structures• Advantage – we can use the built-in capabilities of RuntimeException
• Advantage – we can make our specialized class send a custom message
• Create a subclass that extends the super class
Implementing a Data Structure as a Class (Goodrich, 76–79)
52
Defining a New Exception
/*
* FILE: FullStackException.java
*/
package edu.uhcl.sce.arraystack;
public class FullStackException extends RuntimeException{
public FullStackException(){
super("Stack is full");
}
}
Implementing a Data Structure as a Class (Goodrich, 76–79, 190)
53
Using a New Exception
public E top() throws FullStackException {
if(topIndex < 0) throw new FullStackException();
return myArray[topIndex];
}
Implementing a Data Structure as a Class (Goodrich, 76–79, 190)
54
UML Notation for Inheritance
Super class
Sub classes
Implementing a Data Structure as a Class (Deitel, 610–650)
A general class that contains code used by all sub classes
A specific class that contains specialized code
55
UML Notation for Inheritance from RuntimeException
Super class
Sub class
Implementing a Data Structure as a Class (Deitel, 610–650)
RuntimeException
FullStackException
56
Bonus Lab
Creating a generic class
57
References
Deitel, H. M. and P. J. Deitel, Java How to Program. Upper Saddle River, NJ: Prentice Hall.
Goodrich, M. T. and R. Tamassia, Data Structures and Algorithms in Java. Hoboken, NJ: John Wiley & Sons, Inc., 2006.
Flanagan, D., Java in a Nutshell, 5th Edition. Sebastopol, CA:O'Reilly Media Inc., 2005.
Stevens, P. with R. Pooley, Using UML, Software engineering with objects and components, Updated Edition. Harlow, England:Addison-Wesley., 2000.