Return to lecture notes index
15-100 Lecture 4 (Wednesday, Jan 21, 2004)

Review of Interfaces

A large portion of last lecture was spent talking about interfaces. Let's breifly recall what we konw about them so far. For more in-depth information, please read the notes from Lecture 3.

Interfaces are protocol specifications.
Interfaces specify the behaviors that a class of objects can exhibit, how to get each behavior from the object, and what each behavior returns. They specify the types of messages that each object can send and receive. The interface specification basically defines the "what" an object can do and and "how to ask" the object to do it. Using an interface specification ensures that programs only send correctly formed, legal messages.

How to write an interface specification
Interface specifications have a particular way of being written in Java. Let's examine the parts of this example:



interface Calculator {
public float add(float num1,float num2);
public float getResult();
void clear();
public float subtract(float num1, float num2);
}
Notice the opening line, interface Calculator { . The keyword interface tells Java that this is the beginning of our interface specification. We then assign an identifier, or name, to our interface specification. In this case we will use Calculator, but we can name it whatever we want, this identifier is chosen by the programmer. We then signal the beginning of the body of our interface specification with the squiggly bracket, {.

The next 4 lines are referred to as the body of the specification. Lets examine the top line of the body first.

public float add(float num1, float num2); Lets start by examining this line word by word, starting with public. The method is defined as public, since only public methods are allowed in interface specifications. As a reminder public means that the method can be accessed by objects outside of the class, while private methods can only be accessed by members of the same class.

The next word that we'll look at is float. This defines the return type as a float, which is one of the primative types in java, some of the other return types that you could specify include int(integer), string, double, Object, or void.

Next comes the name of the method, add. Following it, in parentheses, is the formal argument list, (float num1, float num2). The formal argument list defines what parameters each method must be given when it is called. For example, the method add must be given two floating point numbers. Finally, we tell Java we're done defining our method with the semicolon, ;.

If you understand all of the method specifications in the interface skip down to the next bullet point, if not we'll quickly go over the other three method specifications.

The next method that we're going to look at is the get result method. If you look at the line public float getResult(); there are several things that you should notice right away. The first is that this method is a public method that returns a float, exactly like the last method we did. Where the getResult method is diffrent from the add method is in the argument list. When we used the add method we passed it the two numbers, add(float num1, float num2), that we wanted the calculator to add together. For the getResult() method we only want it to return the answer, so we don't pass the method any variables.

The third method is the public void clear(); method. Once again the method is declared public but this time we only want the calculator to clear, we don't actually want it to return any numbers. The return type void tellls the method that it won't be returning anything. Like the getResult method we won't pass clear any arguments.

The final method, public float subtract(float num1, float num2); is set up exactly like add.

After we have defined all of our methods in the body, we have to tell Java we are ending the body of our code. This is done with the other squiggly bracket, }.

Interface Specifications vs. Class Specifications: Messages vs. Actions
Tied to each interface specification is at least one class specification. An interface specification defines "what" and instance can do and "how to ask". The class specification defines "how it is actually done".

So, for each message that we can send an object, the class specification defines the method used to perform the requested behavior.

It is possible for different classes of objects to implement the same interface -- they can do the same things and interact with other -- objects the same way -- even if, behind the scenes, they might contain different machinery which requires different internal actions. So, as Java programmers, we'll implement both interface specifications and class specifications.

As an aside, if only one class of objects implements an interface, Java doesn't require that the interface be defined separately, instead, it can infer the interface from the class specification. But, for now, we will write interface specifications, even when they aren't strictly necessary.

Using Interface Specifications to write a Class Specification

Interface specifications tie directly to class specifications. The interface specification tells what methods each class specification must have, and the manner in which the methods can be called. The class specification then tells specifies exactly how a method does what it needs to do. Lets take a brief look at an example class specification:

class SimpleCalculator implements Calculator {

private float result;
public void clear() {
result = 0;
return;
}

public float geLast() {
return result;
}

public float add(float num1, float num2) {
result = num1 + num2;
return result;
}

public float subtract(float num1, float num2) {
result = num1 - num2;
return result;
}
}

Let's examine the first line, class Counter implements Calculator {. Just like in the interface class, we start with a keyword that tells Java we're starting a special thing, in this case a class. We then name our class with the identifier Counter. Now we want Java to know that this class will follow the specification laid out for us in the Calculator interface. This is done by invoking the interface by iinvoking the identifier with the command implements Calculator. Finally, we let Java know we are ready to start with the body of our class specification with the squiggly bracket, {.

So now on to all that stuff in the rest of the body of the class. Well, if you remember the Calculator interface specification we wrote, it will look mostly familiar. There are four methods, each of which was defined in the interface specification. The first line of each of these methods is exactly the same except the semicolons (;) are replaced with curly brackets {. The curly bracket signifies the beginning of the instructions that are to be executed when the method is called.

When a method is done, it is told to either return an expression or, if it doesn't need to return a value (ie clear), it is just told to return. Below is a quick definition of what a expression is in java.

An expression in java is anything that we can evaluate to get a value. In java we can return any value or expression that we can evaluate to get a value. For example although in the class above the expression we return is the value of result we could have also told the method to return num1 + num2;. Below is a little word diagram of what expression means. While word diagrams are not emphasized in this course if you find that they help you learn many computer science textbooks do utilize them, so you could go find them in a library or bookstore.


expression <-- literal, ex 1, 2, 'a', b'
<-- variable, ex num1
<-- binary operation
<-- unary operation

What else is different from the interface specification? If you notice at the beginning of the body of the class, we declare a private float result;. This is called an instance variable. It can only be accessed by this class. In fact, as far as Java is concerned, it exists only inside this class. It is created when the class is used, and destroyed when the class is no longer being used. The reason that we created this variable is because of something in java called scope.

Scope in java is where you can access a given variable. We will be talking more in depth about scope later on but for now all you need to know is that you can't access a variable outside the method that it is declared in. Therefore if you created a int called result to in the add method the only place that you can access that variable from is the add method. This would cause a problem for our calculator though, because we want the getResult() method to be able to return the result as well. Since we want the entire class to be able to access the variable result we declare result as a instance variable

One last comment about instance variables. It is considered very bad style to put your instance variables anywhere other then at the begining of the class or at the very end of the class. The reason for this is that if they were scattered through the class it would be very easy to lose track of them, so to increase readability they are put together at the begining or at the end.

How to Use a Class Specification

So now we know how to write a class specification, but how do we use it? What exactly is it for? A class specification is the blueprint for creating objects of the type the class specifies. It's the instructions Java interprets to create objects. So how exactly do we create a new object? This is done using the Java command new.

Creating a new object

So, let's continue to draw upon the examples we have above. I want to create a new calculator object. So first let's start with the command new.

 new
Ok, so now what? Do I want a new calculator, a new Porsche, a new brain, or what? The first thing you'll notice with the command new is that you need to specify what type of object you want it to create.
 
new simpleCalculator(); 
So now we're getting somewhere. Java reads that and says, "this person wants me to create a new simpleCalculator." Java then does just that. As a quick aside, the command simpleCalculator() is a special function called a constructor. It initializes the instance variables of an object and gets it ready for use. In our example program, we didn't create our own constructor. That's ok, because Java will automatically createa default constructor for us.

Java's been hard at work in the meantime, creating our new simpleCalculator for us. So now that it's made the object Java returns a reference to that object, so that we will be able to find it in the computer's memory. A reference variable holds the reference and allows us to access it later. In the line of code below the reference variable is the name "gregsCalculator".

 
simpleCalculator gregsCalculator = newsimpleCalculator(); 

(Quick side note: references are primitives in Java). Please note it does not actually return the object, only the way to find the object. Java gives us the name of the object and a way to make the object do things, but no way for us to actually touch the object in memory. Think of it as Java giving us a phone number and a phone, and we call someone halfway around the world to tell them to make more computer chips. They make the computer chips and then ship them to us. We can't actually go to the factory to make the chips ourselves though.

The first thing you should notice about the previous line of code is that simpleCalculator is in the in the very front of that line. This is the type of reference variable you're creating. This says that you are making a reference variable that will lead to a simpleCalculator object. The next thing you should notice is the variable name, gregsCalculator. This is what we are calling thisparticular GregsCalculator object. So, from this point in our code on, if we say 'simpleCalculator' we're talking about a single, specific simpleCalculator object. The last new thing you should notice is the assignment statement, =. This equals sign means "take the phone number given to us by the new command on the right-hand side, and store that information in the variable gregsCalculator on the left-hand side.

Using an object

We now have this shiny, new simpleCalculator that can add, subtractor, get the last value it figured, and clear its results.  So how do we use it? Let's apply what we learned from creating the object.  First thing we have to do is look up its number in our phonebook.

gc

Ok, so now we know how to get in touch with it.  So, what are we going to make it do? Let's make it add 2.5 and 2.7.


gc.add(2.5,2.7); 

This can be thought of like this. We look up the number for gregsCalculator. Then we tell it that we want to add. Finally, we give it what numbers we want it to add. Let's dissect this line of code.

We know gregsCalculator is a reference to a particular simpleCalculator object. But what's this right after gregsCalculator? The dot (.) is called the scope operator. It tells Java to go inside of the object that gregsCalculator points to. Once inside of gregsCalculator, we tell Java to run the add method, and pass it two parameters, 2.5 and 2.7. The two parameters are then fed into the add method inside of gc, and the add method produces a result. This result is then returned. But what happens to the result after it is returned? If you're like me, I forget everything unless I write it down. That's what we need to tell Java to do, to store the result in a new variable.


float number = gc.add(2.5,2.7);

So let's think back quickly to our specification for the simpleCalculator class. The add method that we specified in it requires that we gives it two floating point numbers, and then it returns the sum of the two as a floating point number. So, we must specify the type of variable it returns as float. We then give a name to the variable that will hold result, in this case we called it number. Again, we use the assignment statement, =, to tell the variable number to take the value of gc.add(2.5,2.7) . The variable number now holds the value 5.2 .

Let's try using another method of the GregsCalculator class. Let'ss say I want to store the last value we found using the calculator in a new variable. So first, I'd want to make a new variable to store it in.


float last;

Next, I want to actually get the value from the object. I do this by calling the getResult() method on the object gregsCalculator, and assigning the value it returns into the newly created variable.


Float last = gc.getLast();

So now last and number both contain the value 5.2.

Summary

So, we now see all the steps involved in making an interface specification, a class specification, creating an object and using the object. The interface specification tells what form the class will take, what methods it will have, and what these methods will return. The class specification then details how to fulfill these requirements. It focuses on processing data and making the methods work.

We learned that, in order to create an object from our class specification, we must use the keyword new. New creates a new object, stores it in memory, and returns a way to access this object. This access method is called a reference. The reference, in order to be useful to us, needs to be stored in a reference variable. We can then access the methods of an object by calling them on the reference variable.