home—info—exams—lectures—labs—hws
Recipe—Laws—lies—syntax—java.lang docs—java.util docs
lect07b
Returning objects from methods (pt. I)
lect07b
We have seen that an object can
take in an objects as a parameter:
In lecture we wrote a
method for PizzaServers,
namely
boolean hasHigherSalaryThan(PizzaServer rival).
Then in lab,
we wrote methods for class Date:
first
boolean isEqual(Date other)
and then
boolean comesBefore(Date other).
We can also write methods where we return an objects1.
For example, let's write a function for a PizzaServer
which takes in two possible work-Dates,
and decides which one they prefer.
For example, given the choice of
working 2007.Feb.21 and 2007.Feb.28,
a particular PizzaServer might have
a preference for 2007.Feb.21.
Let's write this method together, using the steps of The Design Recipe.
-
Data analysis — What are the pieces of information
at hand, for this problem, and
which data types should be used to represent them in the program?
(E.g., int, String,
boolean, ...?)
-
Examples of the data.
Make a bunch of example instances.
(If using BlueJ with unit test tools enabled,
you can create these these instances by right-clicking on the class;
then you can right-click on the test-class
and select “Bench to test fixture”.
-
Signature — for each method (function),
specify its name, what input parameters it needs (name and type),
and what type of information it will return.
(See our mantra
for signatures)
- Comments (written in
javadoc).
Describe what each parameter means
(for example “the price of the item, in dollars”,
or “the number of students officially enrolled in the course”)
as well as the meaning of the return value.
-
Complete the stub function, and compile.
Note that you still haven't yet written any code which
computes a solution.
-
Test cases:
Write 2-3 test cases (or more, as appropriate).
- A test case includes input(s), and the
expected output.
- Include at least one test with a degenerate input
(if appropriate). For numbers, consider 0, 1.
For Strings, consider the empty string.
- Include at least one typical-use case.
- Consider whether fractional or negative numbers are
possible inputs. Either include a test case with them,
or make sure your comments state clearly they are not allowed.
-
The body of the function.
This is the only non-automatic part of the process.
Reflect on the test cases you worked through by hand:
how did you get from the input to the output?
What is the general case?
Things to help you on your way:
- Remind yourself of your parameters and fields -- these
are the only pieces of info you have, to calculate your answer!
- What are the types of each of these data?
What pertinent methods can you call, on objects of that type?
-
Test — run the test cases you already wrote down
from step 2.
Does your program give the results you expect?
-
Refactor — review and (as necessary) rewrite your
code. Does it obey the The Laws of Programming?
In addition to solving this particular problem about choosing a shift,
what we're really trying to teach is the recipe.
The same recipe guides you through all problems, even those which are
much more complicated than the one we work on here.
-
Data analysis — What are the pieces of information
at hand, for this problem, and
which data types should be used to represent them in the program?
(e.g., int, String,
boolean, ...?)
-
Examples of the data.
Make a bunch of example instances.
(If using BlueJ with unit test tools enabled,
you can create these these instances by right-clicking on the class;
then you can right-click on the test-class
and select “Bench to test fixture”.
-
Signature — for each method (function),
specify its name, what input parameters it needs (name and type),
and what type of information it will return.
(See our mantra
for signatures)
- Comments (written in
javadoc).
Describe what each parameter means
(for example “the price of the item, in dollars”,
or “the number of students officially enrolled in the course”)
as well as the meaning of the return value.
-
Complete the stub function, and compile.
Note that you still haven't yet written any code which
computes a solution.
-
Test cases:
Write 2-3 test cases (or more, as appropriate).
- A test case includes input(s), and the
expected output.
- Include at least one test with a degenerate input
(if appropriate). For numbers, consider 0, 1.
For Strings, consider the empty string.
- Include at least one typical-use case.
- Consider whether fractional or negative numbers are
possible inputs. Either include a test case with them,
or make sure your comments state clearly they are not allowed.
-
The body of the function.
This is the only non-automatic part of the process.
Reflect on the test cases you worked through by hand:
how did you get from the input to the output?
What is the general case?
Things to help you on your way:
- Remind yourself of your parameters and fields -- these
are the only pieces of info you have, to calculate your answer!
- What are the types of each of these data?
What pertinent methods can you call, on objects of that type?
Often, the body of the function is
just a return statement,
although you might also
name partial results using local variables,
and use an if statement which contains
a return statement or names partial results.
-
Test — run the test cases you already wrote down
from step 2.
Does your program give the results you expect?
-
Refactor — review and (as necessary) rewrite your
code. Does it obey the The Laws of Programming?
Magic Numbers
A Magic Number is a literal value which
occurs in a program, whose value is a mystery:
other people reading the code have no idea how that number was chosen,
or if it is truly the correct value.
Avoid magic numbers by using named constants.
Note that 0 and 1
(and often 2, as in double radius = diam/2;)
are not considered magic numbers,
but $5.15 and 3.14159 are magic.
$5.15 should be named MINIMUM_WAGE
(or is it PIZZA_PRICE_PER_SQ_FT?? Who can tell?).
Similarly, use Math.PI rather than 3.14159.
(Note that PI is actually a field inside
the Math object2.
(optional) the conditional operator
Java's if-else is a statement -- it
is on its own line(s),
and it will happen before or after other statements,
but it can't be combined as a sub-part of larger statements.
This is different than expressions, like “Math.sqrt(16)” or
“(a && b)”,
which might occur as sub-expressions of the larger expression
“(Math.sqrt(16) > x) || (a && b))”.
It turns out, there is a statement form of
if-else, using the punctuation
“?” and “:”.
conditonal-operator ::=
condition ? expressiontrue : expressionfalse
For example, if a Dates have a predicate isLeapYear,
and d is an instance of Date,
then the following expression
evaluates to the number of days in February:
This can be combined into other expressions, like the right-hand-side of
an <= expression:
d.getDay() <= (d.isLeapYear() ? 29 : 28)
|
Note that the conditional operator
must contain answer-expressions for
both condition-being-true and condition-being-false.
(This is different from if, which can legally be written
without an else.)
We can use the conditional operator to make the above code more concise:
Date whichDayToWork( Date d1, Date d2 ) {
if (this.getBalance() < 100) {
return (d1.comesBefore(d2)) ? d1 : d2;
}
else { /* balance >= 100 */
return (d1.comesBefore(d2)) ? d2 : d1;
}
}
|
In this case, we are combining the conditional-operator into the
expression portion of
the return-statement (whose syntax is
return expression).
Challenge exercise:
re-write the above statement starting with the decision of which
date comes first, and (in each case) asking about what the balance is:
Date whichDayToWork( Date d1, Date d2 ) {
if (d1.comesBefore(d2)) {
return ? : ;
}
else { /* d1 doesn't come before d2 */
return ? : ;
}
}
|
Although most Java programmers
tend to use if most of the time,
the conditional expression is actually extremely handy,
and you are encouraged to use it if you're comfortable with it.
1
Okay yes, the Constructor is already a method which returns an object,
although we didn't actually write the return statement ourself.
↩
2Again, it's a
temporary lie
that Math is an object, even though
we call its methods and fields as if it were.
↩
home—info—exams—lectures—labs—hws
Recipe—Laws—lies—syntax—java.lang docs—java.util docs