1
LECTURE 3: FIELDS,
GETTERS AND SETTERS,
CONSTRUCTORS, TESTING
Penkom2013
Assignment A1 is on the CMS and Piazza
2
Write a simple class to maintain information about
butterflies
Objectives in brief:
Get used to Eclipse and writing a simple Java class
Learn conventions for Javadoc specs, formatting
code (e.g. indentation), class invariants, method
preconditions
Learn about and use Junit testing
Important: read carefully, including Step 7, which
reviews what the assignment is graded on.
Overview
3
An object can contain variables as well as
methods.
Variable in an object is called a field.
Declare fields in the class definition. Generally,
make fields private so they cant be seen from
outside the class.
May add getter methods (functions) and setter
methods (procedures) to allow access to some or
all fields.
Use a new kind of method, the constructor, to
initialize fields of a new object during evaluation
of a new-expression.
Create a Junit Testing Class to save a suite of test
References to text and JavaSummary.pptx
4
Declaration of fields: B.5-B.6 slide 12
Getter/setter methods: B.6 slide 13, 14
Constructors: B.17-B.18 slide 15
Class String: A.67-A.73
Junit Testing Class: none slide 74-80
Overloading method names: B-21 slide 22
Homework
5
1. Course website contains classes Time and
TimeTester. The body of the one-parameter
constructor is not written. Write it. The oneparameter constructor is not tested in TimeTester.
Write a procedure to test it.
2. Visit course website, click on Resources and then
on Code Style Guidelines. Study
1. Naming conventions
3.3 Class invariant
4. Code organization
4.1 Placement of field declarations
5. Public/private access modifiers
class Time
6
Object contains the time of day in hours and
minutes.
Methods in object refer to field in object.
Could have an array of such objects to list the
times at which classes start at Cornell.
With variables t1 and t2 below,
t1.getHour() is 8
Time@fa8
t2.getHour() is 9 Time@150
hr
Time hr 9
Time
t2.toString() is 09:05 8
t1 Time@150
min 0 getHour() min 5 getHour()
getMin()
getMin()
t2 Time@fa8
toString()
toString()
A class Time
7
/** An instance maintains a time of day */
public class Time {
private int hr; //hour of the day, in 0..23
private int min; // minute of the hour, in 0..59
Access modifier private:
cant see field from
outside class
} Software engineering
principle: make fields
Time@fa8
hr 9
Time
min
Class invariant
8
/** An instance maintains a time of dayClass
*/
invariant:
public class Time {
collection of
private int hr; //hour of day, in 0..23
defs of
and
private int min; // minute of hour, invariables
0..59
constraints on
them (green
Software engineering principle: Always
stuff)
write a clear, precise class invariant,
which describes all fields.
Call of every method starts with class
invariant true and should end with class
invariant true.
}
Frequent reference to class invariant while
Getter methods (functions)
9
/** An instance maintains a time of day */
public class Time {
private int hr; // hour of the day, in 0..23
private int min; // minute of the hour, in 0..59
/** Return hour of the day */
Spec goes before
public int getHour() {
method.
return hr;
Its a Javadoc
}
comment
Time@fa8
starts
with /**
/** Return minute of the hour */
hr 9
Time
public int getMin() {
return hr;
min 5 getHour()
}
getMin()
}
A little about type (class) String
10
public class Time {
private int hr; //hour of the day, in 0..23
Java:
private int min; // minute of the hour, in 0..59
double
/** Return a represention of this time, e.g. 09:05*/
quotes for
public String toString() {
String
return prepend(hr) + ":" + prepend(min);
Java:
+ is
literals
}
String
/** Return i with preceding 0, if
catenation
necessary, to make two chars. */
private String prepend(int i) {
if (i > 9 || i < 0) return "" + i; Catenate with empty
String to change any
return "0" + i;
value to a String
}
helper function is
private, so it cant be
Setter methods (procedures)
11
/** An instance maintains a time of day */
public class Time {
private int hr; //hour of the day, in 0..23
private int min; // minute of the hour, in 0..59
/** Change this objects hour to h */
public void setHour(int h) {
hr= h;
}
}
No way to
store value
in a field!
We can add
a setter
method
Time@fa8
hr 9
Time
getHour()
getMin()
setHour(int)toString()
setHour(int) is now in the object
min
Setter methods (procedures)
12
Do not say
/** An instance maintains a time of day */
set field hr
public class Time {
to h
private int hr; //hour of day, in 0..23
private int min; // minute of hour, in 0..59
User does not
know there is a
field. All user
/** Change this objects hour to h */
knows is that
public void setHour(int h) {
Time maintains
hr= h;
hours and
Time@fa8
}
minutes. Later,
hr 9
Time
we show an
}
implemin 5 getHour()
getMin()
mentation that
setHour(int)toString()
doesnt have
Test using a Junit testing class
13
In Eclipse, use menu item File New Junit
Test Case to create a class that looks like this:
Select TimeTester in
import static org.junit.Assert.*;
Package Explorer.
import org.junit.Test;
public class TimeTester {
@Test
public void test() {
fail("Not yet implemented");
}
}
Use menu item Run
Run.
Procedure test is
called, and the call
fail() causes
execution to fail:
Test using a Junit testing class
14
Write and save a
suite of test cases
public class TimeTester {
in TimeTester, to test
@Test
that all methods in
public void test() {
Time are correct
Store
new
Time object in t1.
Time t1= new Time();
assertEquals(0, t1.getHour());
assertEquals(0, t1.getMin();
assertEquals("00:00", t1.toString());
}
}
Give green light if expected value equals
computed value, red light if not:
assertEquals(expected value, computed value);
Test setter method in Junit testing class
15
public class TimeTester {
@Test
public void testSetters() {
Time t1= new Time();
t1.setHour(21);
assertEquals(21,
t1.getHour());
}
}
TimeTester can have
several test
methods, each
preceded by @Test.
All are called when
menu item Run
Run is selected
Time@fa8
hr 9
Time
getHour()
getMin()
setHour(int)toString()
min
Constructors new kind of method
16
public class C {
private int a;
private int b;
private int c;
private int d;
private int e;
}
C var= new
C();
var.setA(2);
var.setB(20);
var.setC(35);
var.setD(-15);
C has lots of fields.
Initializing an object can be a
pain assuming there are
suitable setter methods
Easier way to initialize the
fields, in the new-expression
itself. Use:
C= new C(2, 20, 35, -15, 150);
But first, must write a new
method called a
constructor
Constructors new kind of method
17
/** An object maintains a time of day */
public class Time {
private int hr; //hour of day, 0..23
private int min; // minute of hour, 0..59
/** Constructor: an instance with
h hours and m minutes.
Purpose of
constructor:
Initialize field of a
new object so
that its class
Memorize!
invariant is true
Precondition: h in 0..23, m in 0..59 */ Need precondition
public Time(int h, int m) {
hr= h;
min= m;
}
No return type
or void
Name of constructor
is the class name
Time@fa8
hr 9 min 5
Time
getHour() getMin()
toString() setHour(int)
Time(int, int)
Revisit the new-expression
18
Syntax of new-expression:
new <constructorcall>
Example:
new Time(9, 5)
Time@fa8
Evaluation of new-expression:
1. Create a new object of class, with default
values
in fields
2. Execute
the constructor-call
3. Give as value of the
expression
the name of the new
Ifobject
you do not declare a constructor,
Java puts in this one:
public <class-name> () { }
Time@fa8
hr 90 min 50
Time
getHour() getMin()
toString() setHour(int)
Time(int, int)
How to test a constructor
19
Create an object using the constructor. Then
check that all fields are properly initialized
even those that are not given values in the
constructor call
public class TimeTester {
Note: This also
@Test
checks the getter
public void testConstructor1() {
methods! No need
Time t1= new Time(9, 5);
to check them
assertEquals(9, t1.getHour());
separately.
assertEquals(5, t1.getMin();
}
But, main
purpose: check
}
constructor
A second constructor
20
Time is
/** An object maintains a time of day */
overloaded: 2
public class Time {
constructors!
private int hr; //hour of day, 0..23
private int min; // minute of hour, 0..59 Have different
parameter types.
/** Constructor: an instance with
Constructor call
m minutes.
determines which
Precondition: m in 0..23*60 +59 */ one is called
public Time(int m) {
Time@fa8
??? What do we put here ???
hr 9 min 5 Time
}
getHour() getMin()
new Time(9, 5)
toString() setHour(int)
new Time(125)
Time(int, int) Time (int)
Method specs should not mention fields
21
public class Time {
private int hr; //in 0..23
private int min; //in 0..59
/** return hour of day*/ Decide
to
public void getHour() { change
implem
return h;
en}
tation
Time@fa8
hr 9
Time
public class Time {
// min, in 0..23*60+59
private int min;
/** return hour of day*/
public void getHour() {
return min / 60;
}
Time@fa8
min 5
Time
getHour() getMin()
toString() setHour(int)
getHour()
getMin()
Specs of methods stay the same.
setHour(int)toString()
Implementations, including fields, change
min