In today's class we discuss how we can think of an
API as being a contract between the client and the
component. We will look at some "contracts" from the
java.lang.Math
utility and use some of its
features to solve some simple problems.
In software engineering, the notion of a contract is used as a metaphor for the design and documentation of software components. For example, when a client decides to invoke a method on an object we can think of the client and the object as entering into a contract.
The client has certain obligations:
The method of the object also has certain obligations:
Many methods have parameters; that is, they require the client to supply arguments (data) to the method. Often, the method will have conditions attached to the parameters. For example, the fictitious method:
double squareRoot(double x)
might require that the parameter x
always
be greater than or equal to positive zero. Such a condition
is called a precondition, because it must be true before
the method can be successfully invoked.
It is the client's responsibility to ensure that the precondition is true. If the client fails to ensure the precondition, then there are no guarantees on the behavior of the method.
If the client satisfies the preconditions then the method must meet its contractual obligations. Satisfying the postconditions is the responsibility of the method.
double squareRoot(double x)
Returns the positive square root of a double
value.
Parameters:
x
– a value
Precondition:
x >= 0.0
Returns:
the positive square root of x
Postcondition:
the return value is as stated above
double squareRoot(double x)
Returns the positive square root of a double
value.
Parameters:
x
– a value
Precondition:
true
Returns:
the positive square root of x
Postcondition:
the return value is as stated above if x >= 0.0
;
the return value is NaN
otherwise
Normally we omit the Precondition section if there are no preconditions.
Normally, the Postcondition section is merged with the Returns section.
double squareRoot(double x)
Returns the positive square root of a double
value.
Parameters:
x
– a value
Returns:
the positive square root of x
if x >= 0.0
;
NaN
otherwise
Notice that computing the positive square root of a value requires
that the value be greater than or equal to 0.0
; this
condition can be verified inside the
squareRoot
method at runtime.
One way to deal with the case where a client asks for the square root of a negative value is to indicate to the client that an error has occurred. The mechanism for doing so in Java is to throw an exception object.
An exception object is a particular type of object that contains information about the nature of the error. When an exception is thrown, the method stops execution (i.e. it does not return a value) and the runtime system searches for a client that is willing to handle the exception; if no client can be found, the program will terminate (with some sort of error message hopefully).
A method that might throw an exception when it detects an error will advertise this fact in its API. For example:
double squareRoot(double x)
Returns the positive square root of a double
value.
Parameters:
x
– a value
Returns:
the positive square root of x
if x >= 0.0
;
Throws:
IllegalArgumentException
if x < 0.0
java.lang.Math
UtilityThe java.lang.Math
methods do not have any preconditions nor
do they throw any exceptions.
double sqrt(double a)
Returns the positive square root of a double
value.
Special cases:
If the argument is NaN or less than zero, then the result is Nan.
If the argument is positive infinity, then the result is positive infinity.
If the argument is positive zero or negative zero, then the result is the
same as the argument.
Otherwise, the result is the double value closest to the true mathematical
square root of the argument value.
Parameters:
a
– a value
Returns:
the positive square root of a
. If the argument is NaN
or less than zero, the result is NaN.
import java.io.InputStream; import java.io.PrintStream; import java.util.Scanner; public class SqrtExample { public static void main(String[] args) { InputStream in = System.in; PrintStream out = System.out; Scanner input = new Scanner(in); out.print("Enter a number to find its square root: "); double value = input.nextDouble(); double root = Math.sqrt(value); out.print("The square root is: "); out.println(root); } }
Elite basketball players seemingly defy gravity by hanging in the air.
In his prime, Michael Jordan's vertical leap was approximately 1.2 meters.
Assuming that the acceleration due to gravity is
g = 9.8 m/s2
, MJ would
have to jump vertically with an initial velocity of
v0 = 4.8497 m/s
to acheive a maximum height of 1.2 meters.
How much time does MJ spend in the top 20 cm of his jump?
To solve this problem, you need to solve the following equation for
the time t
:
(1/2)gt2 - v0t + 1 = 0
Recall that the
quadratic formula
solves for the roots of a quadratic equation.
Note: The total amount of time MJ spends in the air is
0.9897 s
On occassion, you will find that your programming problem involves a literal value such as 12 (the number of months in a year), 3.1415 (pi), or in this case 9.8 (acceleration due to gravity). You should avoid using the literal values and create a named constant instead.
In Java you create a constant value by declaring a variable as
final
. The keyword final
means that
the variable can only be assigned to once. By convention,
the names of final
variables are spelled with
capital letters:
public class Hangtime { public static void main(String[] args) { final double ACCEL_G = 9.8; final double INITIAL_VEL = 4.8497; } }
You should try to solve the rest of the problem.
The mass ratio of a rocket is defined as the mass of the
fuelled rocket (plus payload) divided by the mass of the
unfuelled rocket (plus payload). Using the
ideal rocket equation, the mass ratio can be
derived as:
eΔv/ve
where Δv
is the change in the
rocket's velocity and ve
is the
effective exhaust velocity.
To achieve low earth orbit, the value of
Δv
is approximately
Δv = 10 km/s
.
Write a Java program that asks the user for a
rocket's exhaust velocity and outputs the mass ratio.
You will find the following features in
java.lang.Math
to be useful:
static final double E
The double
value that is closer than any
other to e, the base of the natural logarithms.
static double pow(double a, double b)
Returns the value of the first argument raised to the power
of the second argument.
Lots of special cases here...
Parameters:
a
– the base
b
– the exponent
Returns:
the value ab