Download Objects First With Java

Document related concepts
no text concepts found
Transcript
STREAM
A software process
The Mañana Principle
Don’t try to everything at once!
Static Methods
Stateless Utility Functions
STREAM
S tubs
T ests
R epresentation
E valuation
A ttributes
M ethods
Example
• Wanted: a class to represent a Date.
• Must have the following two methods:
- setToNextDay : no parameters
- toString : no parameters, returns String with
format “<year>-<month>-<day>”
Objects First with Java - A Practical Introduction using BlueJ, © David J. Barnes, Michael Kölling
1. Stubs
class Date {
/**
* Advance the date to the next day
*/
public void setToNextDay () {
}
/**
* @return A representation of this date
*
in the format <year>-<month>-<day>
*/
public String toString () {
return null;
}
}
Objects First with Java - A Practical Introduction using BlueJ, © David J. Barnes, Michael Kölling
2. Tests
The Date class can already be compiled. Using
BlueJ, we can immediately create an instance and
start testing its methods. Of course, they won’t do
much just yet!
Make a list of some simple tests we would like to
make.
To carry out those tests, what else will we need in
the Date class?
We’ll need a way to set a particular date – only then
can we tell if setToNextDay and toString work.
Objects First with Java - A Practical Introduction using BlueJ, © David J. Barnes, Michael Kölling
2. Tests
So, just by thinking about testing, we see the need
for another method. This is cohesion in action!
class Date {
/**
* Set the date to a particular day
*/
public void setDate
(int day, int month, int year) {
}
...
setToNextDay method (as before)
...
toString method (as before)
}
Objects First with Java - A Practical Introduction using BlueJ, © David J. Barnes, Michael Kölling
3. Representations
R1: use three integer fields
- day (1..31), month (1..12), year (1..)
R2: use one integer field
- the number of days since 1st. January, 1970
Many others are possible …
Objects First with Java - A Practical Introduction using BlueJ, © David J. Barnes, Michael Kölling
3. Evaluate
R1: use three integer fields
- day (1..31), month (1..12), year (1..)
R2: use one integer field
- the number of days since 1st. January, 1970
Implementation
Effort
R1
R2
setToNextDay
toString
Objects First with Java - A Practical Introduction using BlueJ, © David J. Barnes, Michael Kölling
The TEACH Scale
Trivial
Easy
Average
Challenging
Hard
difficulty
Objects First with Java - A Practical Introduction using BlueJ, © David J. Barnes, Michael Kölling
3. Evaluate
R1: use three integer fields
- day (1..31), month (1..12), year (1..)
R2: use one integer field
- the number of days since 1st. January, 1970
Implementation
Effort
R1
R2
setToNextDay
Challenging
Trivial
toString
Trivial
Hard
Objects First with Java - A Practical Introduction using BlueJ, © David J. Barnes, Michael Kölling
5. Attributes (we call them fields)
R1: use three integer fields
- day (1..31), month (1..12), year (1..)
class Date {
private int day;
private int month;
private int year;
// 1 ≤ day ≤ daysInMonth
// 1 ≤ month ≤ 12
// 1 ≤ year
...
setDate (as before)
...
setToNextDay method (as before)
...
toString method (as before)
}
Objects First with Java - A Practical Introduction using BlueJ, © David J. Barnes, Michael Kölling
5. Attributes (we call them fields)
R2: use one integer field
- the number of days since 1st. January, 1970
class Date {
private int date;
// days since 1970-01-01
...
setDate (as before)
...
setToNextDay method (as before)
...
toString method (as before)
}
Objects First with Java - A Practical Introduction using BlueJ, © David J. Barnes, Michael Kölling
6. Method Implementation
R1
class Date {
private int day;
private int month;
private int year;
...
// 1 ≤ day ≤ daysInMonth
// 1 ≤ month ≤ 12
// 1 ≤ year
setDate and setToNextDay methods
/**
* @return A representation of this date
*
in the format <year>-<month>-<day>
*/
public String toString () {
return year + "-" + month + "-" + day;
}
}
Objects First with Java - A Practical Introduction using BlueJ, © David J. Barnes, Michael Kölling
6. Method Implementation
R2
class Date {
private int date;
...
// days since 1970-01-01
setDate and setToNextDay methods
/**
* @return A representation of this date
*
in the format <year>-<month>-<day>
*/
public String toString () {
... tricky !!!
}
}
Objects First with Java - A Practical Introduction using BlueJ, © David J. Barnes, Michael Kölling
6. Method Implementation
R2
class Date {
private int date;
...
// days since 1970-01-01
setDate and toString methods
/**
* Advance the date to the next day
*/
public void setToNextDay () {
date = date + 1;
}
}
Objects First with Java - A Practical Introduction using BlueJ, © David J. Barnes, Michael Kölling
6. Method Implementation
R1
class Date {
private int day;
private int month;
private int year;
...
// 1 ≤ day ≤ daysInMonth
// 1 ≤ month ≤ 12
// 1 ≤ year
setDate and toString methods
/**
* Advance the date to the next day
*/
public void setToNextDay () {
day = day + 1;
... more stuff needed
}
}
Objects First with Java - A Practical Introduction using BlueJ, © David J. Barnes, Michael Kölling
The Mañana Principle
When – during
implementation of a method
– we wish we had a certain
support method, write our
code as if we had it.
Implement it later.
Objects First with Java - A Practical Introduction using BlueJ, © David J. Barnes, Michael Kölling
The Mañana Principle
Special
WhenCase
– during
Rule:
implementation
Often, we needoftoaidentify
method
and
– we
deal
wish
with
weahad
special
a certain
case.
Write
support
themethod,
code forwrite
this in
oura
code
separate
as if we
method.
had it.
Implement it later.
Objects First with Java - A Practical Introduction using BlueJ, © David J. Barnes, Michael Kölling
6. Method Implementation
R1
class Date {
private int day;
private int month;
private int year;
...
// 1 ≤ day ≤ daysInMonth
// 1 ≤ month ≤ 12
// 1 ≤ year
setDate and toString methods
/**
* Advance the date to the next day
*/
public void setToNextDay () {
day = day + 1;
... more stuff needed
checkDayOverflow
();
}
}
Objects First with Java - A Practical Introduction using BlueJ, © David J. Barnes, Michael Kölling
6. Method Implementation
/**
* Advance the date to the next day
*/
public void setToNextDay () {
day = day + 1;
checkDayOverflow ();
}
R1
/**
* Spot and deal with special day case
*/
private void checkDayOverflow () {
if (day > 30) {
day = 1;
month = month + 1;
}
}
Objects First with Java - A Practical Introduction using BlueJ, © David J. Barnes, Michael Kölling
/**
* Spot and deal with special day case
*/
private void checkDayOverflow () {
if (day > 30) {
day = 1;
month = month + 1;
}
checkMonthOverflow ();
}
}
}
/**
* Spot and deal with special month case
*/
private void checkMonthOverflow () {
if (month > 12) {
month = 1;
year = year + 1;
}
}
Objects First with Java - A Practical Introduction using BlueJ, © David J. Barnes, Michael Kölling
R1
The Mañana Principle
Hard Problem Rule:
when we need the answer
to a problem we cannot
immediately solve, defer it a
separate method.
Implement it later.
Objects First with Java - A Practical Introduction using BlueJ, © David J. Barnes, Michael Kölling
/**
* Spot and deal with special day case
*/
private void checkDayOverflow () {
if (day > daysInMonth
30) {
()) {
day = 1;
month = month + 1;
checkMonthOverflow ();
}
}
R1
/**
* @return The number of days in the month
*/
private int daysInMonth () {
return 30;
}
Objects First with Java - A Practical Introduction using BlueJ, © David J. Barnes, Michael Kölling
class Date {
private int day;
private int month;
private int year;
R1
// 1 ≤ day ≤ daysInMonth
// 1 ≤ month ≤ 12
// 1 ≤ year
private static final int[] monthDays =
{31, 28, 31, 30, 31, 30,
31, 31, 30, 31, 30, 31};
...
other methods
/**
* @return The number of days in the month
*/
private int daysInMonth () {
return monthDays[month
30;
– 1];
}
}
Objects First with Java - A Practical Introduction using BlueJ, © David J. Barnes, Michael Kölling
class Date {
...
R1
day, month, year fields
private static final int[] monthDays =
{31, 28, 31, 30, 31, 30,
31, 31, 30, 31, 30, 31};
...
other methods
/**
* @return The number of days in the month
*/
private int daysInMonth () {
return
int
answer
monthDays[month
= monthDays[month
– 1]; – 1];
}
if ((month == 2) && isLeapYear ()) {
answer = answer + 1;
}
return answer;
}
}Objects First with Java - A Practical Introduction using BlueJ, © David J. Barnes, Michael Kölling
The Mañana Principle
HardFunctionality
Problem Rule:
Heavy
Rule:
when
need
the answer
when we
some
statements
or
to a problembecome
we cannot
expressions
too
immediately
solve,
defer
it a
long
or complex,
move
them
method.
intoseparate
a separate
method.
Implement
Implement itit later.
later.
Objects First with Java - A Practical Introduction using BlueJ, © David J. Barnes, Michael Kölling
/**
* @return The number of days in the month
*/
private int daysInMonth () {
int answer = monthDays[month – 1];
if ((month == 2) && isLeapYear ()) {
answer = answer + 1;
}
return answer;
}
R1
/**
* @return Whether the year is a leap year
*/
private boolean isLeapYear () {
return
(divides (4, year) && !divides (100, year))
|| divides (400, year);
}
Objects First with Java - A Practical Introduction using BlueJ, © David J. Barnes, Michael Kölling
R1
/**
* @return Whether the year is a leap year
*/
private boolean isLeapYear () {
return
(divides (4, year) && !divides (100, year))
|| divides (400, year);
}
/**
* @param d The divisor
* @param n The number being divided
* @return Whether d divides n exactly
*/
private boolean divides (int d, int n) {
return (n % d) == 0;
}
Objects First with Java - A Practical Introduction using BlueJ, © David J. Barnes, Michael Kölling
2. Tests
So, just by thinking about testing, we see the need
for another method. This is cohesion in action!
class Date {
/**
* Set the date to a particular day
*/
public void setDate
(int day, int month, int year) {
}
...
setToNextDay method (as before)
...
toString method (as before)
}
Objects First with Java - A Practical Introduction using BlueJ, © David J. Barnes, Michael Kölling
R1
class Date {
private int day;
private int month;
private int year;
// 1 ≤ day ≤ daysInMonth
// 1 ≤ month ≤ 12
// 1 ≤ year
/**
* Set the date to a particular day
*/
public void setDate
(int day, int month, int year)
{
this.day = day;
this.month = month;
this.year = year;
}
... setToNextDay and toString methods
}
Objects First with Java - A Practical Introduction using BlueJ, © David J. Barnes, Michael Kölling
R1
/**
* Set the date to a particular day
*/
public void setDate
(int day, int month, int year)
{
defer
this.day = day;
decision as
this.month = month;
to what is
this.year = year;
legal !!
if (!legalDate ()) {
this.day = 1;
this.month = 1;
this.year = 1;
System.out.println
("*** setDate: Bad parameters" +
" ... setting date to" +
" 0001-01-01");
}
}
Objects First with Java - A Practical Introduction using BlueJ, © David J. Barnes, Michael Kölling
R1
/**
* @return Whether the date fields are legal
*/
private boolean legalDate () {
return ((1 <= day) &&
(day <= daysInMonth
30)) &&
())) &&
((1 <= month) &&
(month <= 12)) &&
(1 <= year);
}
BUG: if month is not in the range 1..12,
daysInMonth() will crash.
Objects First with Java - A Practical Introduction using BlueJ, © David J. Barnes, Michael Kölling
class Date {
...
R1
day, month, year fields
private static final int[] monthDays =
{31, 28, 31, 30, 31, 30,
31, 31, 30, 31, 30, 31};
...
other methods
/**
* @return The number of days in the month
*/
private int daysInMonth () {
return
int
answer
monthDays[month
= monthDays[month
– 1]; – 1];
}
if ((month == 2) && isLeapYear ()) {
answer = answer + 1;
}
Assumes: month is in
return answer;
}
the range 1..12.
}Objects First with Java - A Practical Introduction using BlueJ, © David J. Barnes, Michael Kölling
R1
/**
* @return Whether the date fields are legal
*/
private boolean legalDate () {
return (1
((1<=
<=year)
day) &&
((1(day
<= month)
<= daysInMonth
&&
())) &&
((1(month
<= month)
<= 12))
&& &&
((1(month
<= day)
<=&&
12)) &&
(1 (day
<= year);
<= daysInMonth ()));
}
FIXED: operands of && are evaluated
BUG: if monthIf
is any
not operand
in the range
1..12,
left-to-right.
is false,
will remaining
crash.
thedaysInMonth()
result is false and
operands (if any) are not evaluated.
Objects First with Java - A Practical Introduction using BlueJ, © David J. Barnes, Michael Kölling
STREAM
•
•
•
•
•
•
S tubs
T ests
R epresentation
E valuation
A ttributes
M ethods
Our choice of
representation
can have great
impact on the
complexity of
the logic.
Objects First with Java - A Practical Introduction using BlueJ, © David J. Barnes, Michael Kölling
5. Attributes (we call them fields)
R2: use one integer field
- the number of days since 1st. January, 1970
class Date {
private int date;
// days since 1970-01-01
...
setDate (as before)
...
setToNextDay method (as before)
...
toString method (as before)
}
Objects First with Java - A Practical Introduction using BlueJ, © David J. Barnes, Michael Kölling
6. Method Implementation
R2
class Date {
private int date;
...
// days since 1970-01-01
setDate and setToNextDay methods
/**
* @return A representation of this date
*
in the format <year>-<month>-<day>
*/
public String toString () {
... tricky !!!
}
}
Objects First with Java - A Practical Introduction using BlueJ, © David J. Barnes, Michael Kölling
6. Method Implementation
R2
class Date {
private int date;
...
// days since 1970-01-01
setDate and toString methods
/**
* Advance the date to the next day
*/
public void setToNextDay () {
date = date + 1;
}
}
Objects First with Java - A Practical Introduction using BlueJ, © David J. Barnes, Michael Kölling
6. Method Implementation
R2
class Date {
private int date;
...
// days since 1970-01-01
setToNextDay and toString methods
/**
* Set the date to a particular day
*/
public void setDate
(int day, int month, int year)
{
... tricky !!!
}
}
Objects First with Java - A Practical Introduction using BlueJ, © David J. Barnes, Michael Kölling
R1
/**
* Set the date to a particular day
*/
public void setDate
(int day, int month, int year)
{
But the R2 Date has
this.day = day;
no day, month or year
this.month = month;
fields to set …
this.year = year;
if (!legalDate ()) {
… and legalDate has
this.day = 1;
no fields on which it
this.month = 1;
to operate.
this.year = 1;
System.out.println
("*** setDate: Bad parameters" +
" ... setting date to" +
" 0001-01-01");
}
}
Objects First with Java - A Practical Introduction using BlueJ, © David J. Barnes, Michael Kölling
R2
/**
* Set the date to a particular day
*/
public void setDate
(int day, int month, int year)
{
if (legalDate (day, month, year)) {
... still tricky
setLegalDate
(day,!!!
month, year)
} else {
date = 1;
System.out.println
("*** setDate: Bad parameters" +
" ... setting date to" +
" 1970-01-01");
}
defer
}
decision as
defer hard
to what is
logic !!
legal !!
Objects First with Java - A Practical Introduction using BlueJ, © David J. Barnes, Michael Kölling
R2
/**
* Set the date to a particular day
*
* @param day
(assume: 1 ≤ day ≤ daysInMonth)
* @param month (assume: 1 ≤ month ≤ 12)
* @param year (assume: 1 ≤ year)
*
*/
private void setLegalDate
(int day, int month, int year)
{
... still tricky !!!
}
Objects First with Java - A Practical Introduction using BlueJ, © David J. Barnes, Michael Kölling
R2
/**
* Set the date to a particular day
*/
public void setDate
(int day, int month, int year)
{
if (legalDate (day, month, year)) {
... still tricky
setLegalDate
(day,!!!
month, year)
} else {
date = 1;
System.out.println
("*** setDate: Bad parameters" +
" ... setting date to"
to "++
" 1970-01-01");
}
defer
}
decision as
defer hard
to what is
logic !!
legal !!
Objects First with Java - A Practical Introduction using BlueJ, © David J. Barnes, Michael Kölling
R2
/**
* @param day
(legal: 1 ≤ day ≤ daysInMonth)
* @param month (legal: 1 ≤ month ≤ 12)
* @param year (legal: 1 ≤ year)
*
* @return Whether the parameters are legal
*
*/
private boolean legalDate
(int day, int month, int year)
{
… but daysInMonth has
return (1 <= year) &&
no month or year fields
((1 <= month) &&
on which to operate.
(month <= 12)) &&
((1 <= day) &&
(day <= daysInMonth ()));
X
X
}
Objects First with Java - A Practical Introduction using BlueJ, © David J. Barnes, Michael Kölling
R2
/**
* @param day
(legal: 1 ≤ day ≤ daysInMonth)
* @param month (legal: 1 ≤ month ≤ 12)
* @param year (legal: 1 ≤ year)
*
* @return Whether the parameters are legal
*
*/
private boolean legalDate
(int day, int month, int year)
{
return (1 <= year) &&
… so we must
((1 <= month) &&
supply them.
(month <= 12)) &&
((1 <= day) &&
(day <= daysInMonth (month,
()));
year)));
}
Objects First with Java - A Practical Introduction using BlueJ, © David J. Barnes, Michael Kölling
class Date {
...
R1
day, month, year fields
private static final int[] monthDays =
{31, 28, 31, 30, 31, 30,
31, 31, 30, 31, 30, 31};
...
other methods
/**
* @return The number of days in the month
*/
private int daysInMonth () {
int answer = monthDays[month – 1];
if ((month == 2) && isLeapYear ()) {
answer = answer + 1;
}
Assumes: month is in
return answer;
}
the range 1..12.
}Objects First with Java - A Practical Introduction using BlueJ, © David J. Barnes, Michael Kölling
class Date {
private int date;
R2
// days since 1970-01-01
private static final int[] monthDays =
{31, 28, 31, 30, 31, 30, 31, ... , 31};
/**
* @param month (assume: 1 ≤ month ≤ 12)
* @param year (assume: 1 ≤ year)
* @return The number of days in the month
*/
private int daysInMonth (int month, int year)
{
int answer = monthDays[month – 1];
if ((month == 2) && isLeapYear (year)) {
answer = answer + 1;
}
no year field … so
return answer;
}
we must supply.
}Objects First with Java - A Practical Introduction using BlueJ, © David J. Barnes, Michael Kölling
R1
/**
* @return Whether the year is a leap year
*/
private boolean isLeapYear () {
return
(divides (4, year) && !divides (100, year))
|| divides (400, year);
}
Objects First with Java - A Practical Introduction using BlueJ, © David J. Barnes, Michael Kölling
R2
/**
* @param year (assume: 1 ≤ year)
* @return Whether the year is a leap year
*/
private boolean isLeapYear (int year) {
return
(divides (4, year) && !divides (100, year))
|| divides (400, year);
}
Objects First with Java - A Practical Introduction using BlueJ, © David J. Barnes, Michael Kölling
R1
class Date {
private int day;
private int month;
private int year;
...
// 1 ≤ day ≤ daysInMonth
// 1 ≤ month ≤ 12
// 1 ≤ year
setDate, setToNextDay, toString methods
private int daysInMonth ()
{ ... }
private boolean isLeapYear ()
{ ... }
private boolean legalDate ()
{ ... }
}
Objects First with Java - A Practical Introduction using BlueJ, © David J. Barnes, Michael Kölling
R2
class Date {
private int date;
...
// days since 1970-01-01
setDate, setToNextDay, toString methods
private int daysInMonth (int month, int year)
{ ... }
private boolean isLeapYear (int year)
{ ... }
private boolean legalDate
(int day, int month, int year)
{ ... }
}
Objects First with Java - A Practical Introduction using BlueJ, © David J. Barnes, Michael Kölling
OBSERVATION:
We could have used the fully parametrised versions:
int daysInMonth (int month, int year)
boolean isLeapYear (int year)
boolean legalDate (int day, int month, int year)
in the R1 version of Date, as well as in version R2 .
They do not depend on any chosen field representation.
They may, therefore, be worth factoring out into a separate
class, DateStuff, which either representation for Date
could use.
Objects First with Java - A Practical Introduction using BlueJ, © David J. Barnes, Michael Kölling
class DateStuff {
private static final int[] monthDays =
{31, 28, 31, 30, 31, 30,
31, 31, 30, 31, 30, 31};
public int daysInMonth (int month, int year)
{ ... }
public boolean isLeapYear (int year)
{ ... }
public boolean legalDate
(int day, int month, int year)
{ ... }
private boolean divides (int d, int n)
{ ... }
}
Objects First with Java - A Practical Introduction using BlueJ, © David J. Barnes, Michael Kölling
DateStuff
But, now that they are public methods, daysInMonth and
isLeapYear must be protected against misuse.
public int daysInMonth (int month, int year)
{ ... }
public boolean isLeapYear (int year)
{ ... }
public boolean legalDate
(int day, int month, int year)
{ ... }
Note: legalDate is already secure – dealing with bad data is,
after all, its purpose!
Objects First with Java - A Practical Introduction using BlueJ, © David J. Barnes, Michael Kölling
DateStuff
/**
* @param month (1 ≤ month ≤ 12)
* @param year (1 ≤ year)
* @return The number of days in the month
*/
public int daysInMonth (int month, int year)
{
if ((month < 1) || (month > 12) || (year < 1)) {
System.out.println
("*** daysInMonth: bad argument(s)" +
" – returning zero");
return 0;
}
int answer = monthDays[month – 1];
if ((month == 2) && isLeapYear (year)) {
answer = answer + 1;
}
return answer;
}
Objects First with Java - A Practical Introduction using BlueJ, © David J. Barnes, Michael Kölling
DateStuff
/**
* @param year (1 ≤ year)
* @return Whether year is a leap year
*/
public boolean isLeapYear (int year)
{
if (year < 1){
System.out.println
("*** isLeapYear: bad argument " +
"– returning false");
return false;
}
return
(divides (4, year) && !divides (100, year))
|| divides (400, year);
}
}
Objects First with Java - A Practical Introduction using BlueJ, © David J. Barnes, Michael Kölling
DateStuff
/**
* @param day
(legal: 1 ≤ day ≤ daysInMonth)
* @param month (legal: 1 ≤ month ≤ 12)
* @param year (legal: 1 ≤ year)
*
* @return Whether the parameters are legal
*
*/
public boolean legalDate
*
(int day, int month, int year)
{
return (1 <= year) &&
((1 <= month) &&
(month <= 12)) &&
((1 <= day) &&
(day <= daysInMonth (month, year)));
}
* except that now it’s public.
Objects First with Java - A Practical Introduction using BlueJ, © David J. Barnes, Michael Kölling
class DateStuff {
private static final int[] monthDays =
{31, 28, 31, 30, 31, 30,
31, 31, 30, 31, 30, 31};
public int daysInMonth (int month, int year)
{ ... }
public boolean isLeapYear (int year)
{ ... }
public boolean legalDate
(int day, int month, int year)
{ ... }
private boolean divides (int d, int n)
{ ... }
}
Objects First with Java - A Practical Introduction using BlueJ, © David J. Barnes, Michael Kölling
class DateStuff {
private static final int[] monthDays =
{31, 28, 31, 30, 31, 30,
31, 31, 30, 31, 30, 31};
public static
int daysInMonth
int daysInMonth
(int month,
( ...int
) year)
{ ... }
public static
booleanboolean
isLeapYear
isLeapYear
(int year)
(int year)
{ ... }
public static
booleanboolean
legalDate
legalDate
(int day, int month, int year)
{ ... }
private static
booleanboolean
dividesdivides
(int d,(int
int n)
d, int n)
{ ... }
}
Objects First with Java - A Practical Introduction using BlueJ, © David J. Barnes, Michael Kölling
New Java Concept:
Methods, as well as fields, may be declared static.
static methods may work with fields of its class, but only if
they are static.
static methods may invoke other methods of its class, but
only if they are static.
In DateStuff, the methods isLeapYear and divides work
only with their parameters – no fields.
In DateStuff, the methods daysInMonth and legalDate
work with their parameters and (the static field) monthDays.
In DateStuff, daysInMonth invokes isLeapYear, which
invokes divides. And legalDate invokes daysInMonth.
Objects First with Java - A Practical Introduction using BlueJ, © David J. Barnes, Michael Kölling
class DateStuff {
private static final int[] monthDays =
{31, 28, 31, 30, 31, 30,
31, 31, 30, 31, 30, 31};
public static int daysInMonth ( ... )
{ ... }
public static boolean isLeapYear (int year)
{ ... }
public static boolean legalDate
(int day, int month, int year)
{ ... }
private static boolean divides (int d, int n)
{ ... }
}
Objects First with Java - A Practical Introduction using BlueJ, © David J. Barnes, Michael Kölling
New Java Concept:
Methods, as well as fields, may be declared static.
static methods may work with fields of its class, but only if
they are static.
static methods may invoke other methods of its class, but
only if they are static.
static fields and methods belong to the class. They are
shared by all objects (if any) of the class.
To invoke a static method of another class, we don’t need an
object of that other class. We invoke it prefixed with the name
of its owning class (followed by the usual dot).
Normally: we invoke a method on an object. We invoke it
prefixed with the name of the variable referencing the object
(followed by the usual dot).
Objects First with Java - A Practical Introduction using BlueJ, © David J. Barnes, Michael Kölling
/**
* Set the date to a particular day
*/
public void setDate
(int day, int month, int year)
{
if (legalDate (day, month, year)) {
setLegalDate (day, month, year)
} else {
date = 1;
System.out.println
("*** setDate: Bad parameters" +
" ... setting date to" +
" 1970-01-01");
}
}
Objects First with Java - A Practical Introduction using BlueJ, © David J. Barnes, Michael Kölling
R2
R2
/**
* Set the date to a particular day
*/
public void setDate
(int day, int month, int year)
{
if (DateStuff.legalDate
(legalDate (day, month,
(day,
year))
month,
{ year)) {
setLegalDate (day, month, year)
} else {
date = 1;
System.out.println
("*** setDate: Bad parameters" +
" ... setting date to" +
" 1970-01-01");
}
}
Objects First with Java - A Practical Introduction using BlueJ, © David J. Barnes, Michael Kölling
/**
* Set the date to a particular day
*/
public void setDate
(int day, int month, int year)
{
this.day = day;
this.month = month;
this.year = year;
if (!legalDate (){
this.day = 1;
this.month = 1;
this.year = 1;
System.out.println
("*** setDate: Bad parameters" +
" ... setting date to" +
" 0001-01-01");
}
}
Objects First with Java - A Practical Introduction using BlueJ, © David J. Barnes, Michael Kölling
R1
R1
/**
* Set the date to a particular day
*/
public void setDate
(int day, int month, int year)
{
this.day = day;
this.month = month;
this.year = year;
if (!DateStuff.legalDate
(!legalDate (){
(day, month, year) {
this.day = 1;
this.month = 1;
this.year = 1;
System.out.println
("*** setDate: Bad parameters" +
" ... setting date to" +
" 0001-01-01");
}
}
Objects First with Java - A Practical Introduction using BlueJ, © David J. Barnes, Michael Kölling
New Java Concept:
Methods, as well as fields, may be declared static.
static methods may work with fields of its class, but only if
they are static.
static methods may invoke other methods of its class, but
only if they are static.
static fields and methods belong to the class. They are
shared by all objects (if any) of the class.
To invoke a static method of another class, we don’t need an
object of that other class. We invoke it prefixed with the name
of its owning class (followed by the usual dot).
Classes with only static fields and methods need no objects
constructed from them. So … hide the constructor!!
Objects First with Java - A Practical Introduction using BlueJ, © David J. Barnes, Michael Kölling
class DateStuff {
...
monthDays
(private static field)
constructor
private DateStuff () {
// deliberately empty
}
...
daysInMonth, isLeapYear, legalDate
(public static methods)
...
divides
(private static method)
}
This class doesn’t construct any instances of itself. Its constructor is
private, so nobody else can. There can be no DateStuff objects.
Objects First with Java - A Practical Introduction using BlueJ, © David J. Barnes, Michael Kölling
OBSERVATION:
We could have used the fully parametrised versions:
int daysInMonth (int month, int year)
boolean isLeapYear (int year)
boolean legalDate (int day, int month, int year)
in the R1 version of Date, as well as in version R2 .
They do not depend on any chosen field representation.
They may, therefore, be worth factoring out into a separate
class, DateStuff, which either representation for Date
could use.
Objects First with Java - A Practical Introduction using BlueJ, © David J. Barnes, Michael Kölling
They may, therefore, be worth factoring out into a separate
class, DateStuff, which either representation for Date
could use.
DateStuff contains a set of utility functions that work just
with their parameters. They need no persistent state to be
held in fields. Such things are very reusable.
DateStuff can be used with either the R1 or R2 choice
for representation of a date in the Date class.
Factoring out these low-level functions into DateStuff
leaves the Date class (R1 or R2) shorter.
Collections of purely static methods are how we used to
do things – before Object-Orientation. Don’t make a habit
of it! Objects carrying their own state are powerful!!
Objects First with Java - A Practical Introduction using BlueJ, © David J. Barnes, Michael Kölling
The Mañana Principle
When – during
implementation of a method
– we wish we had a certain
support method, write our
code as if we had it.
Implement it later.
Objects First with Java - A Practical Introduction using BlueJ, © David J. Barnes, Michael Kölling
The Mañana Principle
Special
WhenCase
– during
Rule:
implementation
Often, we needoftoaidentify
method
and
– we
deal
wish
with
weahad
special
a certain
case.
Write
support
themethod,
code forwrite
this in
oura
code
separate
as if we
method.
had it.
Implement it later.
Objects First with Java - A Practical Introduction using BlueJ, © David J. Barnes, Michael Kölling
The Mañana Principle
Hard
Special
Problem
Case Rule:
Rule:
when
Often,we
weneed
needthe
to identify
answer
andtodeal
a problem
with a special
we cannot
case.
immediately
Write the code
solve,
for defer
this initaa
separate method.
Implement it later.
Objects First with Java - A Practical Introduction using BlueJ, © David J. Barnes, Michael Kölling
The Mañana Principle
HardFunctionality
Problem Rule:
Heavy
Rule:
when
need
the answer
when we
some
statements
or
to a problembecome
we cannot
expressions
too
immediately
solve,
defer
it a
long
or complex,
move
them
method.
intoseparate
a separate
method.
Implement
Implement itit later.
later.
Objects First with Java - A Practical Introduction using BlueJ, © David J. Barnes, Michael Kölling
The Mañana Principle
Heavy
Functionality
Rule:
Nested
Loop Rule:
when
statements
whensome
we have
a nestedor
expressions
become
too
loop,
move the
inner loop
long
them
intooracomplex,
separatemove
method.
intoImplement
a separateit method.
later.
Implement it later.
Objects First with Java - A Practical Introduction using BlueJ, © David J. Barnes, Michael Kölling
The Mañana Principle
Code Duplication Rule:
Nested Loop Rule:
when we repeat the same
when we have a nested
code, move that code into a
loop, move the inner loop
separate method and repeat
into a separate method.
an invocation instead.
Implement it later.
Implement it later.
Objects First with Java - A Practical Introduction using BlueJ, © David J. Barnes, Michael Kölling
Mañana – Specific Forms
•
•
•
•
•
Special Case rule
Hard Problem rule
Heavy Functionality rule
Nested Loop rule
Code Duplication rule
Utility Classes
public static methods, as well as private static fields.
Utility classes (like DateStuff) have only the above kind of
methods and fields.
Utility classes (like DateStuff) have only private constructors
– no objects can be constructed.
public static methods are invoked via the class name – no
object is needed.