Title: Programmer-defined classes
1Programmer-defined classes
2Topics
- Returning objects from methods
- The this keyword
- Overloading methods
- Class methods
- Packaging classes
- Javadoc
3A class for representing Fractions
public class Fraction private int
numerator private int denominator public
Fraction(int num, int denom)
setNumerator(num) setDenominator(deno
m) public int getDenominator( ) return
denominator public int getNumerator( )
return numerator
4// continued from previous slide
public void setDenominator(int denom)
if (denom 0) //Fatal error
System.err.println("Fatal Error")
System.exit(1) denominator
denom public void setNumerator(int
num) numerator num public
String toString( ) return
getNumerator() "/" getDenominator()
5Additional methods for Fraction
- The basic set of methods defined thus far give us
ways to construct, set values, and print out (via
the toString method) Fraction objects - A richer set of methods would give us
functionality comparable to the other numeric
types (int, double, etc.) - The next slide illustrates a method for
simplifying a Fraction rather than having it
alter the calling object, well make it return a
new Fraction object - The methods that add, subtract, multiply and
divide Fractions should return Fraction results
so they will also be object-returning methods
6The simplify() method (with helper method gcd())
public Fraction simplify( ) int num
getNumerator() int denom
getDenominator() int gcd gcd(num,
denom) Fraction simp new
Fraction (num/gcd, denom/gcd) return
simp
private static int gcd (int m, int n) int
r while (true) r nm if (r 0)
break nm mr return m
7Arithmetic algorithms for Fractions
- The next several slides illustrate arithmetic
methods for our Fraction class, based on the
following formulae - Addition a/b c/d (ad cb)/bd
- Subtraction a/b c/d (ad cb)/bd
- Multiplication a/b c/d ac/bd
- Division a/b / c/d ad/bc
- We will define four Fraction-returning methods
plus, minus, times, and dividedBy
8Calling the arithmetic methods
- Client code that uses Fraction objects might
include instructions like these - Fraction f1, f2, f3
-
- f3 f1.plus(f2)
- f2 f3.times(f1)
- f1 f2.minus(f3)
- f3 f1.dividedBy(f2)
9Javas keyword this
- Each of our arithmetic methods corresponds to a
binary arithmetic operation - Binary operations take two operands they will be
represented in our methods by the calling object
and the argument - We will need to access the numerator and
denominator of both objects to perform the
arithmetic operations - We can use the keyword this to access data
components of the calling object
10The plus method
public Fraction plus (Fraction f) int n1, n2,
d1, d2 // numerators denominators of the 2
Fractions Fraction sum // result to be
returned n1 this.numerator // numerator of
calling object n2 f.numerator // numerator of
argument d1 this.denominator // from calling
object d2 f.denominator // from
argument sum new Fraction(n1d2 n2d1,
d1d2) return sum
11Optional use of this
- In the previous example, the use of keyword this
was actually optional - The next couple of slides illustrate the
implementation of arithmetic Fraction methods
without using this
12The minus method
public Fraction minus (Fraction f) int n1, n2,
d1, d2 // numerators denominators of the 2
Fractions Fraction difference // result to
be returned n1 numerator // numerator of
calling object n2 f.numerator // numerator of
argument d1 denominator // from calling
object d2 f.denominator // from
argument difference new Fraction(n1d2 -
n2d1, d1d2) return difference
13The times method
public Fraction times (Fraction f) int n1, n2,
d1, d2 // numerators denominators of the 2
Fractions Fraction product // result to be
returned n1 getNumerator() // numerator of
calling object n2 f.getNumerator() //
numerator of argument d1 getDenominator()
// from calling object d2 f.getDenominator()
// from argument product new Fraction(n1n2,
d1d2) return product
14To this or not to this?
- As the last two slides illustrate, the use of
keyword this to represent the calling object is
optional - In fact, its only optional from our point of
view if we dont insert it (as was the case in
the plus method), the compiler will insert it for
us so in fact, all three methods use this,
whether implicitly or explicitly
15Another use of this avoiding scope clashes
- You may recall that a local variable with the
same name as a variable with wider scope will
hide the more famous variable within its local
block - You can use the keyword this to avoid such a
scope clash - For example, we could have written the set
methods like this - void setNumerator (int numerator)
- this.numerator numerator
16Method overloading
- The term overloading refers to the use of a
program symbol (usually an identifier) to mean
more than one thing - Although Java doesnt support programmer-defined
operator overloading (as C does), we can still
use the operator to illustrate the point - it means addition
- it also means concatenation
- context determines which meaning applies
17Method overloading
- Methods can be overloaded, as follows
- they can have the same name
- their parameter lists must differ in some
significant way - type(s) of argument(s)
- number of arguments
- they can represent completely different algorithms
18Example plus method
- We have already defined method plus, which
produces the sum of the calling object and
another Fraction (the argument to the method) - To make our Fraction class more versatile, we can
overload this method so that it can be used to
add a calling Fraction object and an int
argument, as illustrated on the next slide
19Overloaded plus method
public Fraction plus (int num) Fraction sum
new Fraction (num, 1) sum sum.plus(this) ret
urn sum
In this instance, the overloaded method
incorporates a call to the original method. The
compiler distinguishes between the two methods by
examining each methods parameter list. Since
the message embedded in the overloaded method is
using a Fraction argument (this), the compiler
looks for a method named plus with a Fraction
parameter, which is easily distinguished from the
int parameter in the new method.
20Using the plus method
- Client programmers can now call plus using either
a Fraction or int argument, as in the examples
below - Fraction f1 new Fraction (2,3),
- f2 new Fraction (3,4)
- f1 f1.plus(5)
- f2 f1.plus(f2.plus(6))
- We can overload the other arithmetic methods in a
similar fashion
21Overloading constructors
- Although all the classes we have looked at so far
have included a single constructor, it is quite
common to have multiple constructors for an
object - Since a constructor always has the same name as
its class, then multiple constructors must by
definition be overloaded methods
22Additional constructors for Fraction class
// default constructor (requires no
arguments) public Fraction () numerator
1 denominator 1 // copy constructor
creates a duplicate object of its argument public
Fraction (Fraction f) numerator
f.numerator denominator f.denominator //
constructor with int argument creates
num/1 public Fraction (int num) numerator
num denominator 1
23Examples of calls to Fraction constructors
Fraction f1 new Fraction (2, 3) // calls
original constructor because there are // two
int arguments Fraction f2 new Fraction() //
calls default constructor creates object
with // numerator denominator both equal to
1 Fraction f3 new Fraction(5) // calls
constructor with single int parameter //
creates object with data value 5/1 Fraction f4
new Fraction(f1) // calls copy constructor
creates object identical to f1
24Alternate definitions for constructors
Another use for keyword this is in the definition
of multiple constructors. Consider the
definition of the original constructor public
Fraction (int n, int d) setNumerator
(n) setDenominator (d) Since this
constructor already exists, we can use it to
define additional constructors. For
example public Fraction () this (1,
1) This is a different way to define the
default constructor
25Class methods
- As we have previously seen, methods declared with
the static keyword are class methods rather than
instance methods - class methods are not part of any object
- class methods exist independent of any object
- all objects of a class share a single copy of any
class method - The private helper method gcd is an example of a
static method
26Method gcd
The method is declared private because it only
exists as a helper method for the simplify
method it isnt supposed to be available to
client programmers. It is declared static
because it is unnecessary to include a new copy
of this method for every Fraction object.
private static int gcd (int m, int n) int
r while (true) r nm if (r 0)
break nm mr return m
27A method for comparing two Fractions
- Strategy pass two Fraction objects to the
method, which returns an int value, as follows - 0 if the Fractions are equal
- 1 if the first argument is greater than the
second - -1 if the first argument is less than the second
- Since neither object is the calling object, it
makes sense to make this a static method, since
then no calling object is necessary - Another private helper method, toDouble, is used
to accomplish the task
28The compareTo method
public static int compareTo (Fraction f1,
Fraction f2) double x f1.toDouble() double
y f2.toDouble() int result if (x gt
y) result 1 else if (x lt y) result
-1 else result 0 return result
private double toDouble() double
result result (double)numerator /
denominator return result
29Notes on class methods
- Class methods can only access class variables and
constants, and cannot call instance methods of
the same class (except by declaring objects and
having them call the methods) - Instance methods can call all other methods of
the same class (without declaring new objects)
30Call-by-Value Parameter Passing
- When a method is called,
- the value of the argument is passed to the
matching parameter, and - separate memory space is allocated to store this
value. - This way of passing the value of arguments is
called a pass-by-value or call-by-value scheme.
31Call-by-Value Parameter Passing
- Since separate memory space is allocated for each
parameter during the execution of the method, - the parameter is local to the method, and
therefore - changes made to the parameter will not affect the
value of the corresponding argument.
32Call-by-Value Example
33Memory Allocation for Parameters
34Memory Allocation for Parameters
35Parameter Passing Key Points
- 1. Arguments are passed to a method by using the
pass-by- value scheme. - 2. Arguments are matched to the parameters from
left to right.The data type of an argument must
be assignment-compatible with the data type of
the matching parameter. - 3. The number of arguments in the method call
must match the number of parameters in the method
definition. - 4. Parameters and arguments do not have to have
the same name. - 5. Local copies, which are distinct from
arguments,are created even if the parameters and
arguments share the same name. - 6. Parameters are input to a method, and they
are local to the method.Changes made to the
parameters will not affect the value of
corresponding arguments.
36Organizing Classes into a Package
- For a class A to use class B, their bytecode
files must be located in the same directory. - This is not practical if we want to reuse
programmer-defined classes in many different
programs
37Organizing Classes into a Package
- The correct way to reuse programmer-defined
classes from many different programs is to place
reusable classes in a package. - A package is a Java class library.
38Creating a Package
The following steps illustrate the process of
creating a package named myutil that includes the
Fraction class.
- 1. Include the statement
- package myutil
- as the first statement of the source file for
the Fraction class. - 2. The class declaration must include the
visibility modifier public as - public class Fraction
- ...
39Creating a Package
- 3. Create a folder named myutil, the same name as
the package name. In Java, the package must have
a one-to-one correspondence with the folder. - 4. Place the modified Fraction class into the
myutil folder and compile it. - 5. Modify the CLASSPATH environment variable to
include the folder that contains the myutil
folder.
40Using Javadoc Comments
- Many of the programmer-defined classes we design
are intended to be used by other programmers. - It is, therefore, very important to provide
meaningful documentation to the client
programmers so they can understand how to use our
classes correctly.
41Using Javadoc Comments
- By adding javadoc comments to the classes we
design, we can provide a consistent style of
documenting the classes. - Once the javadoc comments are added to a class,
we can generate HTML files for documentation by
using the javadoc command.
42javadoc for Fraction
- This is a portion of the HTML documentation for
the Fraction class shown in a browser. - This HTML file is produced by processing the
javadoc comments in the source file of the
Fraction class.
43javadoc Tags
- The javadoc comments begins with / and ends
with / - Special information such as the authors,
parameters, return values, and others are
indicated by the _at_ marker - _at_param
- _at_author
- _at_return
- etc
44Example javadoc Source
. . . / Returns the sum of this Fraction
and the parameter frac. The sum returned is NOT
simplified. _at_param frac the Fraction to add
to this Fraction _at_return the
sum of this and frac / public Fraction
add(Fraction frac) ... . . .
45Example javadoc Output
46javadoc Resources
- General information on javadoc is located at
- http//java.sun.com/j2se/javadoc
- Detailed reference on how to use javadoc on
Windows is located at - http//java.sun.com/j2se/1.5/docs/tooldocs/windows
/javadoc.html