CS203 Lecture 2 Review of CS 202. Lists A list is a data type that stores a finite collection of...

127
CS203 Lecture 2 Review of CS 202

Transcript of CS203 Lecture 2 Review of CS 202. Lists A list is a data type that stores a finite collection of...

CS203 Lecture 2

Review of CS 202

Lists Need to import java.util.List as well as whatever specific type of

list you use, eg java.util.ArrayList A List must be a list of values of some other data type, in the

same way that an array is an array of items of some other type. List are parameterized by the data type of the values in the list.

Unlike an array, a list can only contain objects, not primitive types. For example, you can not declare a list of doubles, but you can declare a list of Doubles. You will understand this better in a couple of weeks.

We show the underlying data type by enclosing it in angle braces, for example:

List <String>

List Methods The List class provides many methods you will

need to use with lists. Here are some easy to understand ones.

– add() adds an item to the end of the list– get(int position) gets a reference to the item

at the specified position in the list– isEmpty() returns a boolean that indicates just

what it sounds like– size() shows the number of items in the list– clear() deletes all items from the list

More List Methods•Some List methods hinge on the fact that a List contains elements of some other data type.

contains(Object o) indexOf(Object o) finds the index of the first occurrence of a

value in the list lastIndexOf(Object o) finds the index of the last occurrence of a

value in the list

Static Data

6

•Static data fields are controlled by the class, not the object.•A static field has only one value for all instances of a class at any point during runtime

Static vs Instance Methods

7

Static methods like main() can be run using the class code without instantiating an object.

JOptionPane.showMessageDialog(null, "hey"); Instance (non-static) methods can be run only as

methods of particular objects instantiated from the class:

Scanner sc = new Scanner();double d = sc.nextDouble();

Static Methods and Data

8

package demos;public class Borg {

private String name;private static int borgCount;public Borg(String nameIn) {

name = nameIn;borgCount += 1;

}public void stateName() {

System.out.println(name + " of " + borgCount);}public static void main(String[] args) {

int max = 9;borgCount = 0;Borg[] borgs = new Borg[max];for (int counter = 0; counter < max; counter++) {

String name = String.valueOf(counter + 1);borgs[counter] = new Borg(name);

}

for (int counter = 0; counter < max; counter++) {borgs[counter].stateName();

}}

}

Why don’t we just use static methods for everything?

9

public class Clone{private String name;

public Clone(String nameIn){name = nameIn;

}

public static void main(String[] args){

Clone bob = new Clone("Bob");Clone joe = new Clone("Joe");Clone mary = new Clone("Mary");

bob.greet();joe.greet();mary.greet();

}

private void greet(){System.out.println("Hi, my name is " + name);

}}

This example uses three instances of the same class, which each have different data. We can run the same method from each object, getting different results for each one.

10

Public and Private Public data may be accessed directly by any object

that has a reference to the current object

This means that any other object can change your data in any way that seems appropriate to whoever wrote it This leads to unpredictable behavior, because

programmers are almost as crazy as users

Private fields and methods may only be used from within the current object

Most classes have private data which can be accessed or changed only by using public methods The public methods are part of the object and thus can see or change the private data

11

Public and PrivateWe can reduce the confusion by providing well-defined interfaces instead of allowing other objects to access our data directlyTo use an object of a certain class, you only need to know its public methods.

You can protect the data in your own classes by allowing it to be changed or accessed only by methods you wrote and chose to make publicly available

This principle is called information hiding or encapsulation

12

Public and Private

The sport of American football includes several ways to score points. The main ones are these:

A touchdown scores 6 pointsA conversion, also called an extra point, scores one point but can only be scored immediately after a touchdown

A safety scores 2 pointsA field goal scores 3 points

Note that there is no way to score four, five, seven, etc. points at once

13

Public and Privatepublic class FootballScore {

// models the score for one team in a game of American Footballprivate int score;

public int getScore() {return score;

}

public void touchdown() {score += 6;

}

public void extraPoint() {score += 1;

}

public void safety() {score += 2;

}

public void fieldGoal() {score += 3;

}

}

14

How the private data / public methods architecture benefits FootballScore:

If external objects (say, a FootballGame object) could arbitrarily change the score in FootballScore, buggy or malicious code could interfere with the functioning of the class for example, by adding 5 to the score or dividing it by 2,

changes that are invalid in American Football. this kind of problem is hard to find and extremely hard

to fix, since the bad code was probably written by someone else

In FootballScore, the available ways to change the score are limited to the ways points can actually be scored in Football

If anything else needs to be done when the score changes, like updateScoreboard(); or notifyBookmaker(); the author of FootballScore can take responsibility for making sure the public methods trigger it

Public and Private

15

How the private data / public methods architecture benefits objects that use FootballScore:

Other objects do not have to understand the internal functioning of FootballScore They only need to know that they can find out the score

by calling getScore() and can deal with scoring events by calling, for example, touchdown().

If you decide to change the design of FootballScore, nothing in any other class needs to change as long as the public interface remains the same. This will become very important as your classes get

more sophisticated. Suppose you write a class with a method that determines whether or not a touchdown was actually scored. You may sometimes need to change the algorithm used by the method (eg, to use new electronic sensors or to accommodate rule changes in the sport.) As long as the method signature remains the same, other objects don't need to understand anything about it or even know when you change it.

Public and Private

16

Consider this code (Student must also be in the package or be imported):

public class Demo {public static void main(String args[]) {

Student joe = new Student();joe.setName("Joe");joe.setGrade(100.0);System.out.println(joe);

} // end main()}

The output will look approximately like this:demos.Student@1dd61ee4

We have not printed out the useful information in the object, just the location of the object in memory!

toString()

17

There is a built-in toString() method that shows the name of the class and the memory location of the object. This is what we got in the last example.

If you want to provide a more useful String representation of objects, write a toString() method in the class.

toString() is public, takes no parameters, and returns a String, so its method header is

public String toString()

We might add a toString() like this to Student:

public String toString(){return "Name: " + name + "; Grade: " + grade;

}

If we now run the same code from Gradebook, we get this output:

Name: Joe; Grade: 100.0

toString()

Constructors

19

Constructor method headers look like this:public ClassName(parameters){}

By convention, if programmer-defined constructors are present, they are the first methods listed in a class.

A class may have more than one constructor (“constructor overloading”) as long as they take different arguments

If you write one or more constructors, the compiler does not supply an implicit constructor. If you want one, you must write it yourself, which is very easy:public ClassName(){} For example,public Student(){}

20

Creating an object An object can be created using a no-parameter constructor like this:

access modifier classname objectname = new classname();

For example,private Student mary = new Student();

Note that Student is the name of a class mary is a variable whose value is a reference to the object we created. The value of the variable mary is the address of the memory location where the data for the object starts The data type of the variable mary is Student private means that the variable mary is only visible from this object.

Composition• Compose: to create something by combining other things• In programming, Composition occurs when a class includes variables of

other classes• We have been doing this all along whenever we write classes that contain

Strings or Scanners.• Several of the lecture examples have contained variables that referred to

objects of classes defined in the examples.– GradeBook above contains an array list of Students– CollegeDriver from lecture 5 contained an array list of departments, and each

department contained an array list of Courses

• Hierarchies like this can be of any depth.• Double contains a compareTo() method. Since Student.gpa is a Double,

Student.compareTo() could have been written this way:– return this.gpa.compareTo(otherStudent.gpa);

Inheritance

22

• Classes often have natural hierarchies, which can be defined in terms of data or in terms of functionality

• The simplest form of hierarchy is general-to-specific

Inheritance

23

• All vehicles have some variables in common– weight– source of locomotion– manufacturer

• Motor vehicles are a subset of vehicles, and they have additional data fields– Engine displacement– Fuel type

• Trucks are a subset of motor vehicles, and they have yet more data fields– Hauling capacity– Etc

Inheritance

• We can model this kind of general-to-specific hierarchy using class inheritance

• “Super” means above, as in supervisor. “Sub” means under or below, as in submarine.

• A subclass is a class which is a more specific form of some other class, which we call its superclass

• Superclasses are more abstract than their subclasses • The terms parent and child are sometimes used in place of

superclass and subclass.• To define a class as a subclass of a superclass, use the extends

keyword. See the examples below

Inheritance Hierarchy• A class can inherit from a hierarchy of superclasses, in the same way you

have parents, grandparents, great-grandparents, etc.• All Java classes are subclasses of Object. Object is, for example, where the

original forms of toString() is defined. However, most other classes do not inherit directly from Object.

– Here is the class hierarchy for OutOfMemoryErrorjava.lang.Object

java.lang.Throwable java.lang.Error

java.lang.VirtualMachineErrorjava.lang.OutOfMemoryError

Inheritance• Subclasses inherit the methods and variables of their superclasses.• Subclasses can add variables, constants, and methods which are not

present in their superclasses.

Overriding• Subclasses can also replace methods inherited from superclasses with

their own methods. This is called overriding.– toString()!– Use the @Override annotation– Make the superclass methods public or protected; can’t override private methods

• Subclass constructors call superclass constructors. If superclass has a no-argument constructor, it is called by default by a no-argumentsubclass constructor

– See example

Inheritancepackage vehicles;

public class Vehicle {protected double weightInKg;protected double speedInKmPerHr;protected Direction direction;

public Vehicle() {}

public Vehicle(double weightInKgIn, double speedIn) {weightInKg = weightInKgIn;speedInKmPerHr = speedIn;direction = new Direction(0, 0);

}

public void steer(double bearing, double angle) {direction.setDirection(bearing, angle);

}

public void accelerate(double speedIncrement) {speedInKmPerHr += speedIncrement;

}

public String toString() {return "vehicle weighs " + weightInKg + " kg: is going "

+ speedInKmPerHr + ": " + direction.toString();}

}

Inheritancepackage vehicles;

public class MotorVehicle extends Vehicle {private double engineDisplacementInCc;private String fuelType;

public MotorVehicle() {// this one implicitly calls Vehicle's constructor

}

public MotorVehicle(double weightInKgIn, double speedIn,double displacementIn, String fuelTypeIn) {

super(weightInKgIn, speedIn);engineDisplacementInCc = displacementIn;fuelType = fuelTypeIn;

}

// also override steer() to change direction in a way appropriate for a car

// getters and setters omitted

public String toString() {return "engine displacement; " + engineDisplacementInCc

+ ": fuelType; " + fuelType + ": " + super.toString();

}}

Inheritancepackage vehicles;

public class Car extends MotorVehicle {

private double throttleSetting;private String manufacturer;

public Car(double weightInKgIn, double speedIn, double displacementIn,String fuelTypeIn, String manufacturerIn) {

super(weightInKgIn, speedIn, displacementIn, fuelTypeIn);manufacturer = manufacturerIn;throttleSetting = 0;

}

@Overridepublic void accelerate(double speedIncrement) {

double origSpeed = speedInKmPerHr;while (speedInKmPerHr < origSpeed + speedIncrement

&& throttleSetting <= 10) {graduallyOpenThrottle(speedIncrement);

}// then close the throttle a little, etc.

}

private void graduallyOpenThrottle(double speedIncrement) {// use your imagination. This is a cheap examplethrottleSetting = 3;speedInKmPerHr += speedIncrement;

}

public String toString() {return "Manufacturer; " + manufacturer + ": throttle; "

+ throttleSetting + ": " + super.toString();}

}

More On Inheritance

31

• Concrete means particular or tangible, not abstract. – Originally meant solidified or hardened. The

building material was named because of the way it is poured, finished, and then dried to a hard state

• The classes in the previous examples were concrete classes, ones that can be instantiated

Abstraction

32

Some definitions of Abstract (adjective):– Considered apart from any application to a particular object;

removed from; apart from; separate; abstracted.  

– Apart from practice or reality; not concrete; ideal; vague; theoretical; impersonal.

– (art) Free from representational qualities.

– (logic) General (as opposed to particular).  

– Synonyms

• (not applied or practical): conceptual, theoretical

• (insufficiently factual): formal

- Source: Wiktionary

In programming, abstraction is a fundamental concept that you need to think about in every program you write, like expense

Programmers sometimes use the word “abstract” as a transitive verb meaning “to create an abstraction of,” as well as using the more common English usage of “abstract” as an adjective.

Abstraction

33

Abstraction can be multi-layered:

A manhole cover is a round thing that covers a manhole to prevent people falling in and rats crawling out

A round thing is a physical object that has the quality of being round

Round means “in the shape of a circle”

A circle is a geometric shape defined by a set of points which are equidistant from the center

More On Inheritance

34

• Classes may be abstract– An abstract class cannot be instantiated, but it can have

subclasses that are concrete.

• Abstract classes may contain data fields that will be common to all subclasses

More On Inheritance

35

• Abstract classes may define concrete methods, but they may also declare abstract methods– An abstract method isn't defined (written) in the class, but

must be defined in a subclass• Subclasses that are also abstract can define the method or ignore it,

leaving it to be defined in their own subclasses.• A concrete class may inherit or override concrete method definitions from its superclass(es)• A concrete class must define any methods which are abstract in its superclass hierarchy

More On Inheritance

36

• Syntax for abstract method:access modifier abstract return type name();For example:protected abstract void accelerate(double speedIncrement);

• Syntax to implement a method required by a superclass (whether it is abstract or concrete in the superclass)– Just add @Override notation above the method code:

@Overrideprotected void accelerate(double speedIncrement){

speedInKmPerHr+=speedIncrement;}

More On Inheritance

37

• Use an abstract class when you expect to create subclasses that will implement some methods identically but other methods in different ways.

• If you don’t need any variable data fields and don’t need to define any methods, use an interface instead.

• Implementation of multiple subclasses of the same class is another form of polymorphism.

More On Inheritance

38

• Our hierarchy of abstraction is getting complicated:

– An object has actual data values. It is less abstract than the class of which it is an instance

– A concrete class doesn’t have data values (except constants), so it is more abstract than an object. However, all of its methods are defined, whether they were inherited from the superclass(es) or are written in the method itself, so it is less abstract than any superclass(es) it might have

– We may have concrete superclasses, which are more abstract than their subclasses

– Abstract classes are, as the name suggests, more abstract than concrete classes. They usually have methods that must be defined in their subclasses. Even if they don’t, they can never be instantiated; only their subclasses can. For these reasons, they are more abstract than concrete classes.

– We may have a hierarchy of abstract superclasses.

– Every class is a subclass of Object

Types and Data Structure Parameters

39

• Arrays and Lists (and also other data structures you will study in CS 203) can be parameterized with abstract classes.

• An array or list whose type is a class (abstract or concrete) can hold objects of any class that extends the class.

Need For Interfaces

40

• Interfaces meet some of the same needs as abstract classes in a simpler way

• Interfaces provide another way to use polymorphism.– If you are programming a furnace, you need a heatAir()

method. However, the internal workings of the method will differ depending on whether you are programming a gas furnace or an oil one.

• Interfaces contain method declarations and may contain constants– No method definitions– No variables

• Interfaces can’t declare private or protected methods, just public ones (that's why they're called interfaces!)

Interface Syntax

41

• Syntax for defining an interface:Access modifier interface name{

final declarationsmethod declarations

}For example:

public interface Vehicle {

public static final double KMTOMILES = .609;

public void accelerate(double speedIncrementInKmPH);

public double getSpeedInKmPH();

public void steer(Direction d);}

Need For Interfaces

42

• Classes implement interfaces. This is declared in the class header:public class MyClass implements MyInterface {Eg

public class Car implements Vehicle {• The distinction between interface (defined as

the public methods available for a class, whether or not there is a java interface) and implementation is very important in OOP.

• A class can have only one parent class, but can implement any number of interfaces

Implementing Interfaces

43

• A class that implements an interface must implement the methods declared in the interface

• Thus, if a class implements a particular interface, we know that we can call certain methods on objects of the class. We don’t care that the methods may work differently for different implementations of the interface.

• Here's another way to make the last point. Different classes that implement the interface may use methods whose internal workings are completely different, as long as they have the signature defined in the interface

Implementing Interfaces

44

• Implementations of methods required by an interface need the @Override annotation:

@Overridepublic void setLocation(String location){

this.location = location;}

Not Breaking Down At The Interfaces

45

• Other objects that deal with objects of your class should only have to know the public interface (whether or not there is a Java interface)

• Other classes should not need to understand the internal workings of your class– Reduce what other programmers need to learn (or you

need to remember) in order to use your classes– Minimize problems at interfaces– You can change the internal workings of your class

without any problems if the interface stays the same.

Not Breaking Down At The Interfaces

46

• Consider a WeatherReport class and a WeatherBalloon class. – A WeatherReport should be able to get the barometric pressure

from a WeatherBalloon by just calling an accessor method. It shouldn’t be dependent on the particular way WeatherBalloon determines what the pressure is.

• WeatherReport's programmer doesn’t need to learn how the measurement is made

• WeatherBalloon's programmer can change the method for determining pressure without affecting WeatherReport at all.

– Compare this to a computer storing data in permanent storage. I should be able to swap out my hard drive and controller for an SSD drive and controller without affecting the CPU, operating system, etc.

47

• Use variables of the most abstract type available• Use methods from ancestor classes or java interfaces rather

than methods that are unique to particular concrete classes whenever possible

• Coding to particular implementations, as opposed to interfaces, exposes you to the risk that your code will break when some other implementation changes. This is *very* dangerous because you may not even know when other programmer change the other classes, and you will also quickly forget how your own code works.

• Coding to the interface also makes your code more modular. If you rely on well-defined interfaces, you can more easily swap out parts of your code later or determine which implementations of an interface to use at runtime.

Code To The Interface, Not The Implementation

Types and Data Structure Parameters

48

ShrinerMobile extends Car, which extends the abstract class MotorVehicle, which extends the abstract class Vehicle:

package vehicles;

public abstract class Vehicle {protected double weightInKg;protected double speedInKmPerHr;protected Direction direction;

protected abstract void accelerate(double speedIncrement);

protected abstract void register();

protected abstract void steer(double bearing, double angle);}

49

Types and Data Structure Parameters

50

Code To Interface, Not Implementation

CompareTo• Java contains a way to make it easy to sort objects

using programmer-defined criteria• Collections.sort(list) is a static method of the

Collections class. Lists are a type of Collection; we will cover this when we discuss inheritance.

• Sort() sorts according to the result of running compareTo() when objects are compared during the sort

• compareTo() compares the current object with another one sent as input to the method

• compareTo() can compare objects using any criteria you can code.

CompareTo• Objects with compareTo() methods must be

declared to implement the interface Comparable<>. Here is an example of the interface declaration:

public class Student implements Comparable<Student>

• Note the parameterization of Comparable, which looks just like the parameterization used when declaring a list. For now, use the class name of the current class as the parameter.

CompareTopackage demos;

public class Student implements Comparable<Student>{private String name;private Double gpa;

public Student(String nameIn, Double gpaIn){name = nameIn;gpa = gpaIn;}

public String toString(){return "Name: " + name + "; GPA: " + gpa;}

// getters and setters omitted@Override

public int compareTo(Student otherStudent) {return this.gpa.compareTo(otherStudent.gpa);}

}

CompareTopackage demos;

import java.util.ArrayList;import java.util.Collections;import java.util.List;

public class GradeBook {public static void main(String[] args) {

List<Student> students = new ArrayList<Student>();

String[] names = {"Skipper", "Gilligan", "Mary Anne", "Ginger", "Mr. Howell", "Mrs. Howell", "The Professor"};double[] gpas = {2.7, 2.1, 3.9, 3.5, 3.4, 3.2, 4.0};

Student currStudent;

for(int counter = 0; counter < names.length; counter++){currStudent=new Student(names[counter], gpas[counter]);students.add(currStudent);

}

// output the dataSystem.out.println("Unsorted:");for(Student s: students)

System.out.println(s);

Collections.sort(students);

System.out.println("\nSorted:");for(Student s: students)System.out.println(s);

}}

55

• Cloneable is an interface that requires that implementing classes have clone() methods.

• clone() methods return deep copies of objects, so a variable that refers to a clone points to a separate object, not the one that was cloned

• Object contains a protected clone() method which you need to call from your own clone methods, but Object.clone() will not copy objects to which your instance variables point. – If these are mutable, your clone() method must also copy

them. If you fail to do this, your variables will point to the same objects the original object variables pointed to. This can lead to strange results.

clone() and Cloneable

Simulators

• Imagine you need data to test software that will be used to process real-world measurements, like the ages of college students

• Sometimes you might want linearly-distributed data, but Gaussian distributions are often more realistic

package simulator;

import java.util.Arrays;

public class Grader {private double average;private double std;private int classSize;private double[] grades;private final double MINGRADE = 0;private final double MAXGRADE = 100;

public enum GradingType {LINEAR, GAUSSIAN

};

public Grader(double avgIn, double stdIn, int classSizeIn) {average = avgIn;std = stdIn;classSize = classSizeIn;

}

public static void main(String[] args) {Grader grd = new Grader(80d, 10d, 20);grd.grade(GradingType.LINEAR);grd.grade(GradingType.GAUSSIAN);

}

private void grade(GradingType type) {Simulator sim = new Simulator();if (type == GradingType.LINEAR)

grades = sim.getLinearData(classSize, MINGRADE, MAXGRADE);if (type == GradingType.GAUSSIAN)

grades = sim.getGaussianData(average, std, classSize, MINGRADE,MAXGRADE);

System.out.println("\nData using distribution type: " + type + "\n");for (int i = 0; i < grades.length; i++) {

System.out.print("Student #" + i + " received a grade of ");System.out.printf("%3.1f\n", grades[i]);

}Arrays.sort(grades);System.out.println("Here are the sorted values from the simulator:");for (double d : grades)

System.out.printf("%3.1f\n",d);}

}

package simulator;

import java.util.Random;

public class Simulator {

private static double[] nums;

public double[] getGaussianData(double mean, double std, int count, double min, double max) {Random r = new Random();nums = new double[count];double randDoub;for (int counter = 0; counter < nums.length; counter++){

randDoub = r.nextGaussian() * std + mean;// it's pretty hard to set limits for the values in a good way, so here is a hacky way.if(randDoub > max) randDoub = max;if(randDoub < min) randDoub = min;nums[counter] = randDoub;

}return nums;

}

public double[] getLinearData(int count, double min, double max) {// it would be better to make sure max < min first, but I am not implementing this in this example

Random r = new Random();nums = new double[count];double randDoub;for (int counter = 0; counter < nums.length; counter++){

randDoub = r.nextDouble() * (max - min) + min;nums[counter] = randDoub;

}return nums;

}}

• Grader is domain-specific (only useful for a narrow type of problem, in this case grading schoolwork)

• Simulator, on the other hand, does not contain anything that shows it is from an application that simulates grading. It could be used to generate test data for a very wide variety of problems

• This is an example of separation of concerns, an important principle in software engineering. Separate the general from the specific, and separate things you can probably reuse from things you can't. If two things are likely to change independently of each other, don’t combine them.

– "When all you have is a hammer, everything looks like a nail" – folk proverb– "If I had a hammer, I'd hammer in the morning, I'd hammer in the evening, all over this land.

I'd hammer out danger; I'd hammer out a warning; I'd hammer out love between my brothers and my sisters, all over this land." –Pete Seeger

Separate Things That Are Likely To Change Independently

TestingDebugging is twice as hard as writing the code in the first place. Therefore, if you write the code as cleverly as possible, you are, by definition, not smart enough to debug it.

--Brian Kernighan

Testing• Besides providing plenty of output that you can check, test various

conditions that should be true or false. package monsters;

public class MonsterAttackDriver {

public static void main(String[] args) {Monster dracula;String dName = "Dracula", dNewName = "Bob", dHome = "Transylvania";

dracula = new Vampire(dName, dHome);if(dracula.getName() != dName) System.out.println("Name error");

dracula.setName(dNewName);if(dracula.getName() != dNewName) System.out.println("Name error");

if(dracula.getOriginStory() == null) System.out.println("Origin story error");

// etc. Test all public methods}

}

Unit Testing• Unit testing is a systematic way to test parts of your

applications• Test for every likely error you can think of• Each test asserts that some condition is true or false;

the assertions will fail if particular errors occur

Unit Testing• Run all the tests periodically to find errors caused by

later code breaking things that worked before or by implementation changes in one part of a system– This is the simplest instance of the concept of regression

testing.• Regression means "going back". Regression testing

"goes back" to test code again to see if it still works correctly.

JUnit• Eclipse includes a unit testing framework called JUnit• A test case is a class that contains one or more tests, usually all

testing the same target class.• Create one or more separate packages in each project for test cases. • Tests use assertions of various kinds

– assertNull(Object o), assertNotNull(Object o)– assertEquals(Object o, Object p), assertFalse(boolean)– Many others listed here: https://github.com/junit-team/junit/wiki/Assertions

• A test succeeds if the assertion(s) are true when the test is run and fails if one or more are false

• The object of a test is to assert something that will be true if the class is working correctly but false if some plausible error occurs

JUnit• Let's start by writing unit tests for the Vampire class, which

implements the Monster interface, and for the Crypt class, which is used by Vampire.

• Test Crypt first, because it can work without Vampire, but Vampire will not work if Crypt is broken

Monsterpackage monsters;public interface Monster {

public void setName(String name);public String getName();public void setLocation(String location);public String getLocation();public void rampage();public String getOriginStory();

}

Cryptpackage monsters;

public class Crypt {

private String location;

public Crypt(String location) {this.location = location;

}

public void setLocation(String location) {this.location = location;

}

public String getLocation() {return location;

}

public String toString(){return "a mysterious crypt in " + location;

}}

Vampirepackage monsters;

public class Vampire implements Monster, Cloneable {

private String name;private Crypt crypt;

public Vampire(String name, String location) {this.name = name;crypt = new Crypt(location);

}

@Overridepublic void setName(String name) {

this.name = name;}

@Overridepublic String getName() {

return name;}

@Overridepublic void setLocation(String location) {

crypt.setLocation(location);// TODO Auto-generated method stub}

@Overridepublic String getLocation(){

return crypt.getLocation();}

@Overridepublic String getOriginStory() {

return "undead creature which lives by sucking the blood of living humans";}

@Overridepublic void rampage() {

StringBuilder sb = new StringBuilder(name+ " arises from " + crypt.toString() + " and ");

if (crypt.getLocation() == "Transylvania")sb.append("sucks people's blood all night, then returns to a coffin to hide from sunlight");

else if (crypt.getLocation() == "Burbank")sb.append("takes over the entire television industry");

else {System.out.println("wreaks unknown havoc in fresh Vampire territory");return;

}System.out.println(sb);

}

@Overridepublic Object clone() {

Vampire newV;try {

/* Object clone() returns an Object. It will be a Vampire, but in order to get to anything specific to Vampires, we need to cast it to a Vampire and use a Vampire reference variable */

newV = (Vampire) super.clone();newV.crypt= new Crypt(crypt.getLocation());

} catch (CloneNotSupportedException e) {e.printStackTrace();return null;

}return newV;

}}

Unit Testing

Unit Testing• JUnit tests are identified with the annotation@Test:

@Testpublic void testCryptCreated(){

String location = "Transylvania";Crypt c = new Crypt(location);assertNotNull(c);

}

@Testpublic void testToString(){

String location = "Transylvania";Crypt c = new Crypt(location);assertNotNull(c.toString());

}

Unit Testing

JUnit Assertions require imports

JUnit Assertions require imports

Unit Testing• Write assertions that will fail if likely errors occur• Keep the tests simple. Most tests have only one assertion

each. This way, you can identify problems quickly when assertions fail.

• Systematically exercise the whole interface– In this case, "interface" means the public interface of the class being

tested. That may be defined partially or completely by a Java interface, an abstract class, or a concrete superclass, or it may be unique to the class.

– Unit testing is not usually used for private methods; if these are wrong, any errors should come to light through the public interface

• It is possible to instantiate objects and use them in multiple tests, but it is usually better to start from scratch for each test– Tests should not have dependencies on each other, which would cause

tests to break if other tests are changed

Unit Testingpackage test;

import static org.junit.Assert.*;import monsters.Crypt;

import org.junit.Test;

public class CryptTester {

@Testpublic void testCryptCreated(){

String location = "Transylvania";Crypt c = new Crypt(location);assertNotNull(c);

}

@Testpublic void testCryptLocation(){

String location = "Transylvania";Crypt c = new Crypt(location);assertEquals(c.getLocation(), location);

}

@Testpublic void testSetCryptLocation(){

String firstLocation = "Transylvania";Crypt c = new Crypt(firstLocation);String secondLocation = "Wisborg";c.setLocation(secondLocation);assertEquals(c.getLocation(), secondLocation);

}

@Testpublic void testToString(){

String location = "Transylvania";Crypt c = new Crypt(location);assertNotNull(c.toString());

}}

VampireTester

• Vampire has a Crypt (remember, this is composition). – There is no public method in Vampire that returns the Crypt, so we can’t directly test

that it is correctly creating the crypt.– This is white box testing, though, and we do know that Vampire.getLocation() gets the

location from Crypt.getLocation()

@Testpublic void testLocation() {

String name = "Orlok";String location = "Transylvania";Vampire v = new Vampire(name, location);assertEquals(v.getLocation(), location);

}

VampireTester

• Here are some tests of Vampire.clone()

@Testpublic void testCloneIsNewVampire(){

String name = "Orlok";String location = "Transylvania";Vampire v1 = new Vampire(name, location);Vampire v2 = (Vampire) v1.clone(); //clone() returns an object, but it is a VampireassertNotSame(v1, v2);

}

@Testpublic void testCloneName(){

String name = "Orlok";String location = "Transylvania";Vampire v1 = new Vampire(name, location);Vampire v2 = (Vampire) v1.clone(); //clone() returns an object, but it is a VampireassertTrue(v1.getName().equals(v2.getName()));

}

@Testpublic void testCloneLocation(){

String name = "Orlok";String location = "Transylvania";Vampire v1 = new Vampire(name, location);Vampire v2 = (Vampire) v1.clone(); //clone() returns an object, but it is a VampireassertTrue(v1.getLocation().equals(v2.getLocation()));

}

@Testpublic void testCloneChangeLocation(){

String name = "Orlok";String location = "Transylvania";Vampire v1 = new Vampire(name, location);Vampire v2 = (Vampire) v1.clone(); v2.setLocation("Burbank");assertFalse(v1.getLocation().equals(v2.getLocation()));

}

VampireTester

• To refactor code is to change the implementation• When refactoring a class, don't change the public

interface unless you can do a major reorganization of the whole application– Refactoring should be completely invisible from outside the class, so

that • other code does not have to change; and • other programmers don’t have to learn the internal workings of your code

– Changing the interface inherently means other code must change

• Let's refactor Crypt.

VampireTester

• Refactor Crypt without introducing any errors:

public String toString(){return "a very, very mysterious crypt in " + location;

}

• All test results remain the same

VampireTester

• Let's say we refactor Crypt and make a mistake:

public void setLocation(String location) {location = location;

}

• Both CryptTester and VampireTester contain tests that will now fail

• The failing test in VampireTester shows that Vampire will have to change to match the change in Crypt. This is not desirable, and it might not even be possible.

VampireTester

VampireTesterClick on *each* line in the JUnit output indicating a failed test

GUIs• Practically all consumer-oriented software today uses Graphical

User Interfaces (GUIs, pronounced "gooeys")• An attractive and easy to use UI makes a bigger impression on the

typical consumer than elegant program logic or even performance does.– Consumers buy sizzle, not steak. – Bill Gates is the richest person in the world, but Richard Stallman can’t afford

a razor

• Java is heavily used in several types of GUI-based applications– Web apps– Android apps– BluRay interface

JavaFX

• The Horstmann textbook we used last year in CS202 taught GUI programming with Swing, as did earlier versions of the Liang textbook we are now using.

• A future lab will require a little JavaFX work. The basic principles are generally similar to those of Swing.

• If you do not have a basic familiarity with JavaFX, read chapters 14-16 and work your way through the examples in lectures 10-11 from my section of CS202 this term (not any you may have left over from my sections of 202 last year.)

JavaFXSome JavaFX examples include main() methods like this one:

public static void main(String[] args){Application.launch(args);

}• This kind of main() may be necessary to run JavaFX applications

from some IDEs, but if Eclipse is correctly configured you will not need it. You will also not need it to compile and run from a command line in current versions of Java. You should not include main() at all.

start(Stage primaryStage) is the starting point of a JavaFX application. • Your start() overrides one from javafx.application.Application• primaryStage is created automatically

JavaFX• The window in which JavaFX GUI components are placed is an

object of class Stage. JavaFX developers are afflicted with the Java habit of giving things campy names. Don’t say I didn’t warn you.

• Stage has many setter methods like setTitle() and setWidth(). Experiment with these as you work.

• Individual UI components, like Labels and Buttons, are called controls

• You can set up multiple Stages and swap them in and out; we will cover that later.

JavaFX

• Each Stage has a Scene which holds the controls• You can put controls like buttons directly into the Scene, but most

Scenes hold objects of subclasses of Pane. These serve as containers for the controls. The first Pane we will try out is the StackPane. This is a container which stacks the components it holds in back-to-front order.

• The constructor for Scene takes a parameter that is a reference to the root of the scene graph, eg the Stack Pane.

• You can add UI controls directly to the StackPane but there are other containers you can use to get more control over layout.

• Once you have the Scene constructed, use Stage.setScene() to make the particular Stage use the Scene

• Stage.show() makes the Stage actually appear

JavaFX

JavaFX offers two different ways to code the UI– Both controls and functionality coded in Java. This is the way we will

initially use– XML description of the controls, with Java code to define how they work.

This is similar to the way most (not all) web and mobile programming frameworks work. We will try this method a little later.

Hello World in JavaFXimport javafx.application.Application;import javafx.scene.Scene;import javafx.scene.layout.StackPane;import javafx.scene.text.Text;import javafx.stage.Stage;

public class Hello extends Application{ @Override public void start(Stage primaryStage) { primaryStage.setTitle("Hello World!"); Text txt = new Text("Hello, World!"); StackPane root = new StackPane(); root.getChildren().add(txt); Scene sc = new Scene(root, 300, 250); primaryStage.setScene(sc); primaryStage.show(); }}

JavaFXStackPane stacks components in “back to front” order according to when they are added to the Pane. Run this and then reverse the order of the two root.getChildren() lines and run it again:

public class Hello extends Application{ @Override public void start(Stage primaryStage) { primaryStage.setTitle("Hello World!"); Text txt = new Text("Hello, World!"); Button b = new Button("Click me!"); StackPane root = new StackPane(); root.getChildren().add(txt); root.getChildren().add(b); Scene sc = new Scene(root, 300, 250); primaryStage.setScene(sc); primaryStage.show(); }}

Note that Text has a transparent background, so you can see through it to the button

JavaFXGroup is another type of Pane that renders its components using specified x and y coordinates. Experiment with the values of the parameters in this code:

@Overridepublic void start(Stage primaryStage) {

Group g = new Group();

Rectangle r = new Rectangle();r.setWidth(200);r.setHeight(100);r.setFill(Color.RED);r.setX(50);r.setY(50);

Circle c = new Circle();c.setRadius(100);c.setFill(Color.GREEN);c.setCenterX(300);c.setCenterY(300);

g.getChildren().add(r);g.getChildren().add(c);Scene sc = new Scene(g, 750, 750);primaryStage.setScene(sc);primaryStage.show();

}

JavaFX Architecture• A JavaFX user interface is based on a scene graph, which is a tree, much like an

html document. To review, the CS conception of a tree looks like this:

• Other than the root, each node has one parent (more oddly-chosen vocabulary!)• Each node may have one or more children• A node with no children is called a leaf• All nodes are said to be contained within the root

JavaFX Architecture• In JavaFX, the root of the scene graph tree is the pane.

Styling

• Each node in the scene graph has an id, size, and a style class. The style class is actually a list of Strings that are the names of CSS classes.

• This capability is new and is still somewhat limited.• The CSS properties are different from the usual ones used with

html, so you will have to look them up. • Oracle’s documentation of the CSS properties is preliminary, but

I won’t make you do anything too obscure with these in this class.

Styling@Override

public void start(Stage primaryStage) {StackPane s = new StackPane();Scene sc = new Scene(s, 300, 300);sc.getStylesheets().add("styles/style.css");

Label l = new Label("Hello");l.getStyleClass().add("arthur");l.getStyleClass().add("beatrice");

s.getChildren().add(l);primaryStage.setScene(sc);primaryStage.show();

}

Styling

.arthur{-fx-background-color: #FFFF00;-fx-text-fill: #00DDFF;

}

.beatrice{-fx-font-size: 500%;

}

Contents of style.css

Styling• This setup separates the presentation from the content, which makes

it much easier to change them separately.public class Hello extends Application {

@Overridepublic void start(Stage primaryStage) {

StackPane s = new StackPane();Scene sc = new Scene(s, 300, 300);sc.getStylesheets().add("styles/style.css");

Label l = new Label("Hello");

boolean am = getAm();

if(am) l.getStyleClass().add("amstyle");else l.getStyleClass().add("pmstyle");

s.getChildren().add(l);primaryStage.setScene(sc);primaryStage.show();

}

private boolean getAm(){String[] options = {"AM", "PM"};return JOptionPane.showOptionDialog(null, "AM or PM?", "What time of day is it?", JOptionPane.YES_NO_OPTION,

JOptionPane.INFORMATION_MESSAGE, null, options, "AM") == 0;

} }

Styling.amstyle{

-fx-background-color: #FFFF00;-fx-text-fill: #00DDFF;-fx-font-size: 300%;

}

.pmstyle{-fx-background-color: #FF00FF;-fx-text-fill: #00FF00;-fx-font-size: 400%;

}

Events

• GUI programs must handle events that are user-directed and may occur at any time.

• GUI actions, such as button clicks, raise Events. In OOP, an event is implemented as an object of some class. In JavaFX, these are instances of subclasses of the EventObject class.

Event Handlers

• Event handlers specify which events the program will respond to and what to do when they occur

• In JavaFX, these implement the EventHandler interface and are parameterized with subclasses of Event, such as ActionEvent.

• You can add EventHandlers to may different types of GUI components

• EventHandlers must implement the method handle(Event event)• You can create an Event Handler object in many different ways

– Code a class in a separate file and instantiate an object– Code an inner class and instantiate an object– Code an anonymous class and instantiate an object separately– Code an anonymous class and instantiate a one-of-a-kind object all at once

Separate EventHandler Classimport javax.swing.JOptionPane;import javafx.event.Event;import javafx.event.EventHandler;

public class MyClickHandler<ActionEvent> implements EventHandler<Event>{

@Overridepublic void handle(Event event) {

JOptionPane.showMessageDialog(null, "Thanks!");}

}

Separate EventHandler Classpublic class Hello extends Application {@Overridepublic void start(Stage primaryStage) {StackPane s = new StackPane();Scene sc = new Scene(s, 300, 300);

Button b = new Button();b.setText("Click Me!");EventHandler<Event> handler = new MyClickHandler<Event>();b.addEventHandler(MouseEvent.MOUSE_CLICKED, handler);

s.getChildren().add(b);primaryStage.setScene(sc);primaryStage.show();} }

Inner EventHandler Classpublic class Hello extends Application {

@Overridepublic void start(Stage primaryStage) {

StackPane s = new StackPane();Scene sc = new Scene(s, 300, 300);

Button b = new Button();b.setText("Click Me!");EventHandler<Event> handler = new MyClickHandler<Event>();b.addEventHandler(MouseEvent.MOUSE_CLICKED, handler);

s.getChildren().add(b);primaryStage.setScene(sc);primaryStage.show();

}

private class MyClickHandler<ActionEvent> implements EventHandler<Event>{@Overridepublic void handle(Event event) {

JOptionPane.showMessageDialog(null, "Thanks!");}

}}

Anonymous EventHandler Class with Variablepublic class Hello extends Application {

@Overridepublic void start(Stage primaryStage) {

StackPane s = new StackPane();Scene sc = new Scene(s, 300, 300);

Button b = new Button();b.setText("Click Me!");

// “anonymous” because we never name the classEventHandler<Event> handler = new EventHandler<Event>(){

@Overridepublic void handle(Event event) {

JOptionPane.showMessageDialog(null, "Thanks!");}

};b.addEventHandler(MouseEvent.MOUSE_CLICKED, handler);

s.getChildren().add(b);primaryStage.setScene(sc);primaryStage.show();

} }

Anonymous Class with Anonymous Objectpublic class Hello extends Application {

@Overridepublic void start(Stage primaryStage) {

StackPane s = new StackPane();Scene sc = new Scene(s, 300, 300);

Button b = new Button();b.setText("Click Me!");b.addEventHandler(MouseEvent.MOUSE_CLICKED, new EventHandler<Event>(){

@Overridepublic void handle(Event event) {

JOptionPane.showMessageDialog(null, "Thanks!");}

});

s.getChildren().add(b);primaryStage.setScene(sc);primaryStage.show();

} }

Anonymous Class with Anonymous Object

b.addEventHandler(MouseEvent.MOUSE_CLICKED, new EventHandler<Event>(){@Overridepublic void handle(Event event) {

JOptionPane.showMessageDialog(null, "Thanks!");}

});

This idiom may be hard to get used to, but it is very common in many different GUI programming frameworks, and will certainly be on the final exam.

Beginning of method callOpen parenthesis begins parameter list for addEventhandler()

Semicolon ends addEventhandler() statement

Close parenthesis ends parameter list for addEventhandler()

Call to EventHandler constructor

Open curly brace begins definition of anonymous class

Close curly brace ends definition of anonymous class

GridPane• GridPane is a Pane that allows you to specify the relative location of controls using

row and column numbers• Column numbers are listed first

Celsius Converter: Version 1public class CelsiusConverter extends Application{

@Overridepublic void start(Stage primaryStage) {

GridPane gp = new GridPane();Scene sc = new Scene(gp);sc.getStylesheets().add("styles/style.css");

Label lblFahr = new Label("Fahrenheit Value: ");TextField tfFahr = new TextField();Label lblCels = new Label("Celsius Value:");Label lblCelsAns = new Label();Button btnCalc = new Button("Convert");btnCalc.addEventHandler(MouseEvent.MOUSE_CLICKED, new EventHandler<Event>(){

@Overridepublic void handle(Event event) {

double cels = (Double.parseDouble(tfFahr.getText())-32)*5/9;lblCelsAns.setText(String.valueOf(cels));

}});

gp.getStyleClass().add("pane");gp.add(lblFahr, 0, 0);gp.add(tfFahr, 2, 0);gp.add(lblCels, 0, 1);gp.add(lblCelsAns, 2, 1);gp.add(btnCalc, 1, 2);

primaryStage.setScene(sc);primaryStage.show();

} }

CelsiusConverter.pane{

-fx-font-size: 250%;-fx-padding: 20px;

}

Separate Application Logic From The GUI• The initial EventHandler examples showed simple responses

coded in the handlers. It is better to separate out any substantial processing into separate methods, in other classes, following the general principle of separation of concerns. – We may want to reuse code to handle various different events.– We may want to use the same functionality with a different kind of

GUI– When we need to change the processing code, it is easier to work with

if it is not mixed with GUI code.– It's hard to unit test GUIs, so we should get the code that might have

subtle bugs away from the GUI.

Separate Application Logic From The GUI• Don’t put any substantial processing in the Event Handlers

and don’t access the GUI from the processing code.• Either

– use separately-defined classes for the GUI app and the processing; or– In simple cases, use an inner class with processing methods.

Celsius Converter 2.0• Let's move the conversion calculation to this

class:

package application;

public class CelsiusCalculator {private final double CONVFACTOR = 5.0/9.0;private final int FSTART = 32;

public double fToC(double f){return (f-FSTART) * CONVFACTOR;

}}

package test;

import static org.junit.Assert.assertEquals;

import org.junit.Test;

import application.CelsiusCalculator;

public class CelsiusCalculatorTester {

@Testpublic void testFreezing() {

CelsiusCalculator calc = new CelsiusCalculator();double freezingF = 32;double freezingC = 0;double freezingResult = calc.fToC(freezingF);

// assertEquals for two doubles takes a delta as the third argument!assertEquals(freezingResult, freezingC, 0.1);

}

@Testpublic void testBoiling() {

CelsiusCalculator calc = new CelsiusCalculator();double boilingF = 212;double boilingC = 100;double boilingResult = calc.fToC(boilingF);

assertEquals(boilingResult, boilingC, 0.1); }

@Testpublic void testNegForty() {

CelsiusCalculator calc = new CelsiusCalculator();double negForty = -40;double negFortyResult = calc.fToC(negForty);

assertEquals(negFortyResult, negForty, 0.1); }

}

Unit Tests

package application;

import javafx.application.Application;import javafx.event.Event;import javafx.event.EventHandler;import javafx.scene.Scene;import javafx.scene.control.Button;import javafx.scene.control.Label;import javafx.scene.control.TextField;import javafx.scene.input.MouseEvent;import javafx.scene.layout.GridPane;import javafx.stage.Stage;

public class CelsiusConverterGUI extends Application{

@Overridepublic void start(Stage primaryStage) {

CelsiusCalculator calc = new CelsiusCalculator();GridPane gp = new GridPane();Scene sc = new Scene(gp);sc.getStylesheets().add("styles/style.css");

Label lblFahr = new Label("Fahrenheit Value: ");TextField tfFahr = new TextField();Label lblCels = new Label("Celsius Value:");Label lblCelsAns = new Label();Button btnCalc = new Button("Convert");btnCalc.addEventHandler(MouseEvent.MOUSE_CLICKED, new EventHandler<Event>(){

@Overridepublic void handle(Event event) {

double cels = calc.fToC(Double.parseDouble(tfFahr.getText()));lblCelsAns.setText(String.valueOf(cels));

}});

gp.getStyleClass().add("pane");gp.add(lblFahr, 0, 0);gp.add(tfFahr, 2, 0);gp.add(lblCels, 0, 1);gp.add(lblCelsAns, 2, 1);gp.add(btnCalc, 1, 2);

primaryStage.setScene(sc);primaryStage.show();

} }

CelsiusConverterGUI

This application uses GUI components and EventHandlers in a slightly more complex way:• Place a grid of buttons on a GridPane• Place a Label into in an Hbox (one-row Pane) indicating how many

buttons are currently clicked• Attach EventHandlers to each button that track whether the

button is currently clicked or not clicked and update the count displayed on the Label

• Add both Panes to a BorderPane• Notice the use of String.valueOf() to convert numeric values to

Strings for display in labels

ClickCounter

public class ClickCounter extends Application {private int numClicked;@Overridepublic void start(Stage primaryStage) throws Exception {

BorderPane bp = new BorderPane();bp.getStyleClass().add("grid");

GridPane gp = new GridPane();

Label clickedLabel = new Label("Buttons Clicked: ");clickedLabel.getStyleClass().add("clickedLabel");Label numClickedLabel = new Label("0");numClickedLabel.getStyleClass().add("clickedLabel");

HBox clickedCounterBox = new HBox();clickedCounterBox.getStyleClass().add("clickedBox");clickedCounterBox.getChildren().add(clickedLabel);clickedCounterBox.getChildren().add(numClickedLabel);

Scene sc = new Scene(bp);sc.getStylesheets().add("styles/style.css");

numClicked = 0;

for (int rowCounter = 0; rowCounter < 10; rowCounter++)for (int colCounter = 0; colCounter < 10; colCounter++) {

}

Click Counter

Button b = new Button("Unclicked");b.setMinWidth(150);b.getStyleClass().add("button");b.addEventHandler(MouseEvent.MOUSE_CLICKED,

new EventHandler<Event>() {Boolean clicked = false;

@Overridepublic void handle(Event event) {

if (clicked == true) {clicked = false;b.setText("Unclicked");numClicked--;

} else {clicked = true;b.setText("Clicked");numClicked++;

}

numClickedLabel.setText(String.valueOf(numClicked));}

});gp.add(b, colCounter, rowCounter);

}bp.setTop(clickedCounterBox);bp.setBottom(gp);

primaryStage.setScene(sc);primaryStage.show();}

}

Click Counter

.pane{-fx-font-size: 250%;-fx-padding: 20px;

}

.grid{-fx-font-size: 200%;

}

.clickedLabel{-fx-background-color: #00FFFF;

}

.clickedBox{-fx-alignment: center;

}

CSS

JavaFX can also handle events using setter methods from the various Node classes, like this:

Label l = new Label("Click Me!");l.setOnMouseClicked(new EventHandler<MouseEvent>(){

@Overridepublic void handle(MouseEvent event) {

JOptionPane.showMessageDialog(null, "Thanks!");}

});

Event Handling with Setters

• Simple event handling works well with lambda expressions, a feature that is commonly used in functional programming and has recently been introduced to Java.

• A Lambda expression is equivalent to an anonymous method (Liang says an anonymous class)

• Here is a sample; e is the parameter name for the event, which is passed into the lambda expression.. Later we will get information from the event objects.

Label l = new Label("Click Me!");l.setOnMouseClicked(e -> {

JOptionPane.showMessageDialog(null, "Thanks!"); }

);

Event Handling with Lambda Expressions

Class diagram

Account- Customer_Name- Balance

+deposit( )+withdraw( )

Name

Attributes

Operations

Sequence Diagrams – Object Life Spans

• Creation Create message Object life starts at that point

• Activation Symbolized by rectangular stripes Place on the lifeline where object is

activated. Rectangle also denotes when object

is deactivated.• Deletion

Placing an ‘X’ on lifeline Object’s life ends at that point

Activation bar

A

BCreate

XDeletion

Return

Lifeline

Sequence Diagram

User Catalog Reservations

1: look up ()

2: title data ()

3: [not available] reserve title ()

4 : title returned ()

5: hold title ()

5 : title available ()

6 : borrow title ()

6 : rem ove reservation ()

•Sequence diagrams demonstrate the behavior of objects in a use case by describing the objects and the messages they pass.

•The horizontal dimension shows the objects participating in the interaction.

•The vertical arrangement of messages indicates their order.

•The labels may contain the seq. # to indicate concurrency.

Message

State Diagrams (Billing Example)

State Diagrams show the sequences of states an object goes through during its life cycle in response to stimuli, together with its responses and actions; an abstraction of all possible behaviors.

Unpaid

Start End

PaidInvoice created payin

gInvoice destroying

State Diagrams (Traffic light example)

Yellow

Red

Green

Traffic LightState

Transition

Event

Start

Ways To Generate UML Diagrams

• Microsoft Visio• UMLet – Free UML tool• Several Eclipse plug ins support UML diagrams.

In Eclipse, go to Help / Eclipse Marketplace and enter "UML" in the find box. Some tools are evaluation versions of commercial software, while others are open-source.– Model Goon provides an easy way to generate class

diagrams– Many others available

Installing Eclipse Add Ons

• There are thousands of add-ons available to add functionality to Eclipse, many of them open source or otherwise free.– Some look free but are actually evaluation versions

• Choose Help/Eclipse Marketplace, then enter text in the search box

• Many add ons can be installed with a few clicks

Eclipse Add Ons

Write and Test Your Code Incrementally

129

• You should be able to explain in one sentence how any method you write works. If you can’t, break it down into two or more methods.

The Stevie Wonder principle:"When you believe in things that you don't understand, then you suffer."