CSIS 3701: Advanced Object

advertisement
CSIS 3701: Advanced Object-Oriented Programming
Object-Oriented Syntax in Java
In this section, we introduce the basic syntax of creating and using classes in Java.
Further sections will expand upon this, giving more advanced syntax and more details on
the concepts behind them.
An Example Sum Class
For this section, we will create a very simple class called Sum that represents the
concept of a “running total”. More specifically:
 Objects in this class will keep a running total of the integers that are passed to
them as a state variable.
 When an object in this class is constructed its running total will initially be 0.
 Users may use methods to add new integers to the total (using a method called
add) and find the current running total (using a method called getSum).
This could be implemented with the flowing class, which would be stored in a file called
Sum.java.
// Sum is a class representing a running integer total.
// Users can add to the total, and find the total.
public class Sum {
private int total;
// Internal state variable
// The constructor sets the internal running total to 0.
public Sum() {
total = 0;
}
// The add method increments the running total, modifying
// the state of the object.
public void add(int x) {
total = total + x;
}
// The getSum method returns the current value of the
// running total. It does not modify the state.
public int getSum() {
return total;
}
}
Some syntax nodes about the above example:
Basic class structure:
 The keyword class is used to indicate that Sum is a new class with the
constructor and methods defined inside the { }. Unlike C++, you cannot define
the methods separately from the class.
 Defining the variable int total inside the class makes it a state variable of
the class. Every Sum object will have its own individual total.
 Using the word public before the class, constructor, and methods make them
available to the user. Using the word private before the state variable hides it
from the user. This is related to a topic called encapsulation, which we will talk
about in more detail later.
 The class must be stored in a .java file with the same name as the class – in this
case, Sum.java. This will make things like separate compilation much easier,
as the compiler will not need a makefile to figure out what files to look in.
Constructor:
 The constructor for the class has the same name as the class. This is true for most
object-oriented programming languages.
 The constructor does not return anything (not even void). Forgetting this can
lead to some strange compiler errors.
 Other than the above two qualifications, there are no restrictions on what a
constructor can do. They can take parameters (we will see examples of this later),
read from files, allocating memory, etc. – in other words, do whatever is
necessary to set up the initial state of the object.
Methods:
 The syntax for a method is very similar to that of a function in C – you must
define parameters and return type, as well as the code that is executed when the
method is invoked.
 Note that the variable total is used in the methods (and the constructor as well),
but is not declared as a local variable of any of these. In this case, total refers
to the state variable of the object – invoking any of the methods modifies or
accesses the current value of that state variable.
This means that if we were to call the add method of some Sum called S, the call would
end up changing S's total state variable.
In a sense, this means that these methods act as an interface to the state variables of each
Sum. That is, the user will not directly manipulate the state variables, but will instead
manipulate them through these methods:
USER ----->
add
---> total
getSum
This allows users to treat our Sum objects as abstractions. They only need to know what
interface methods affect the Sum, but not how the Sum is represented.
Finally, one very important thing to be aware of is that everything in Java must be a
member of a class. This accounts for some of the more unusual looking syntax in Java,
such as the main function being inside of a class. There are ways around this using the
static keyword that we will see later.
Constructing Objects
As mentioned previously, objects (whether they be part of a Java library like Button or
programmer-defined like Sum) must be created using the new command. This does the
following things:
1. Allocates space in memory for the object.
2. Invokes the constructor for the object.
3. Returns a reference to the object.
For example, to create a new Sum object called odometer we would do the following:
Sum odometer = new Sum();
Note that (unlike C++) you must use the parentheses ( ) to invoke the constructor even
if there are no parameters.
At this point, we can think of odometer as looking something like this:
void add(int)
total: 0
int getSum()
Executing object methods
The syntax to invoke the methods of an object is:
objectname.methodname(parameters);
For example, to add 37 to our Sum odometer, we would do the following:
odometer.add(37);
As described above, this would call the add method for odometer. This would have
the effect of changing the total state variable of odometer. In effect, it would be
identical to:
odometer.total = odometer.total + 37;
At this point, we can think of odometer as looking something like this:
void add(int)
total: 37
int getSum()
And after another add:
odometer.add(62);
void add(int)
total: 99
int getSum()
Given this current state of odometer, the message:
int distanceSoFar = odometer.getSum();
would return 99.
Terminology note:
We often use the term message instead of "call" to describe the process of
invoking a method. This better expresses the idea that we are sending that call to a
particular object. For example, we could say that odometer.add(37) is
"sending a message to the odometer object to add the parameter 37".
Syntax Notes:

Note that these calls are sent to odometer, and no other object (which is another
reason that this is referred to as a "message"). For example, if we had constructed
another Sum called somethingElse:
Sum odometer(), somethingElse();
then a call of the form:
somethingElse.add(86);
would only affect the total variable of somethingElse. It would have no
affect on odometer.

If a state variable (such as total) is redeclared in a method, then references to
that variable will affect the local variable only (sort of like what happens if you
redeclare a global variable locally in C). For example:
public void doNothing() {
int total; // total is redeclared locally
total = 0; // this only changes the local total
}
Overloaded Methods and Constructors
One potential problem with the convention that the name of the constructor must be the
same as the name of the class is that it might only allow us one way to initialize objects in
the class – that is, while we may have many different methods in a class (such as add and
getSum), we can only have one constructor (Sum), since it must have the same name as
the class.
Suppose I wanted to give the user two different options for creating Sum objects.
Specifically:

A default constructor, which allows the user to create a Sum with an initial total
of 0 (like the one given above).

An additional constructor, which allowed the user to specify the initial total to
something other than 0.
That is, I would like to modify the above class as follows:
// Sum is a class representing a running integer total.
// Users can add to the total, and find the total.
public class Sum {
private int total;
// Internal state variable
// The default constructor sets the internal running total to 0.
public Sum() {
total = 0;
}
// The additional constructor sets the running total to the given
// parameter.
public Sum(int t) {
total = t;
}
// The add method increments the running total.
public void add(int x) {
total = total + x;
}
// The getSum method returns the current value of the
// running total.
public int getSum() {
return total;
}
}
In the above example, I have overloaded the Sum constructor. Overloading a method or
constructor refers to reusing the same name with more than one definition.
In C, this would give us a compiler error, as you cannot redefine a function any more
than you can redefine a variable.
In Java, however, we can give the same constructor or method more than one definition,
as long as it is possible to disambiguate between them based on either:

The number of parameters

The type of parameters
For example, consider the following lines of code:
Sum s1 = new Sum();
Sum s2 = new Sum(42);
Java will choose the definition of Sum that matches the type and number of parameters.
s1 would be created using the first constructor, and s2 would be created using the
second constructor.
An Example Application
To better illustrate how objects can be use, we give a sample Java application that creates
a Sum object and uses it to compute trip mileage. You won’t understand everything this
application does at this point; however, you should be able to understand all of the lines
in bold, which are related to the Sum.
import javax.swing.*;
import java.awt.event.*;
public class MileageApp extends JFrame
implements ActionListener,
WindowListener {
JButton moreMileage;
JTextField getMileage, showMileage;
Sum odometer;
// a reference to a Sum object
public MileageApp() {
// Create visual objects
moreMileage = new JButton(“add distance to next city”);
getMileage = new JTextField(5);
showMileage = new JTextField(5);
showMileage.setEditable(false);
JLabel showLabel = new JLabel(“Total distance: “);
// Create a panel to display the objects, and add them
// to the panel.
JPanel P = new JPanel();
getContentPane().add(P);
P.add(moreMileage);
P.add(getMileage);
P.add(showLabel);
P.add(showMileage);
// Listen for events on the button, and for the closing
// of the window.
moreMileage.addActionListener(this);
addWindowListener(this);
// create the Sum object
odometer = new Sum();
}
//
//
//
//
//
This event handler is invoked when the button is
pressed. It gets the number in the getMileage field
and sends it to the odometer. It then gets the total
mileage from the odometer and displays it in the
showMileage field.
public void actionPerformed(ActionEvent e) {
// read the number of miles from the textfield and
// convert it to an integer
int miles = Integer.parseInt(getMileage.getText());
// Invoke the add method to add that many miles to the
// odometer.
odometer.add(miles);
// Use the getSum method to get the total number of
// miles.
int totalMiles = odometer.getSum();
// Display it in the other textfield
showMileage.setText(“” + totalMiles);
}
// Called by java, use to create and display a MileageApp object
public static void main(String[] args) {
MileageApp m = new MileageApp(); // create an object
m.setSize(280, 120);
// set its size
m.show();
// display it
}
}
When run, the applet will look something like this:
Another important thing to note about this example is the way the developer of the Sum
class and the author of this application are able to know as little as possible about each
other. Specifically:
 The author of the application of the Sum class is able to use it without
understanding how it works – to them, it is just something to keep track of
mileage traveled so far.
 The author of the Sum class does not have to know how the class will be used –
that is, they don’t have to be aware in any way that it is being used to keep track
of mileage traveled.
Arrays and Strings Revisited
Now that we have introduced basic OOP syntax and concepts in Java, we can talk a bit
more about arrays and Strings in Java.
While arrays are not completely treated like objects (there are no methods or
constructors), they behave like objects in certain ways. Like other objects, arrays must be
allocated with the new command. They also have properties that can be accessed (sort of
like state variables in a class).
The most useful property to be able to find out is the length of an array. This can be
accessed using the form:
arrayname.length
For example, we can easily iterate through an entire array using a for loop by accessing
its length property. For example:
for (int i = 0; i < A.length; i++) { … }
Strings are full-fledged classes in Java, with many methods for accessing individual
characters, finding the length, searching, etc. Probably the most useful method, however,
is the equals method, which allows you to compare two strings to determine whether
they contain the same sequence of characters (recall that this cannot be done with the ==
operator, as it just checks whether two things refer to the same object). For example:
String name = T.getText();
// read in a name from
// textfield T
if (name.equals(“Fred”)) {
T.setText(“hello Fred!”);
}
Copyright © 2000 by Dr. John R. Sullins
// not name == “Fred”!!!
Download