51
3.1 Black Boxes A black box is something that magically accomplishes some task for you. You do not have to understand how this happens—you can just be glad that it does!

3.1 Black Boxes n A black box is something that magically accomplishes some task for you. You do not have to understand how this happens—you can just be

Embed Size (px)

Citation preview

3.1 Black Boxes

A black box is something that magically accomplishes some task for you. You do not have to understand how this happens—you can just be glad that it does!

For instance, most of you probably don't understand exactly how an internal combustion engine works.

You just know that your car gets you where you want to go (most of the time, hopefully). You supply the gas, push on the pedals, and (ta-da!) you move.

A "black box" provides encapsulation: that is, it hides unimportant details from the user.

Encapsulation is one of the THREE BIG JAVA IDEAS. We won't learn the other two until next semester—but know that encapsulation is important!

Abstraction is the process by which these black boxes can be designed. Abstraction means taking away all the inessential details until only the main idea is left.

3.2 Designing a Public Interface

From here on out, the book relies heavily on a bank account example to illustrate lots of ideas. We will be writing different programs to illustrate ideas, but you should still read through the book to see what they are doing.

Our program

We are going to design a program to keep track of your grades for a particular class.

Our objects will be “Grades".

What do we need to be able to do with grades?

Methods for Grades

Add new scores (mutator) Retrieve the overall grade (accessor) Anything else?

Method Headers Now we need a method header for each of

our methods. Think about the return type of each method and any parameters that may be needed. Choose a name that makes sense. For now, we will leave the body blank.

public void addScore(int score, int outOf)

public double getGrade()

Constructors We will also need Constructors.

Remember, constructors do not have a return type. They must have the same name as the class. You can have more than one if they have different parameters.

public Grade() public Grade(int total, int possible)

That is the basic skeleton!

These four lines make up the public interface of our class! Let's start writing the program! Open up BlueJ if you haven't yet, and type in these four lines. Usually, the constructors come first, and then the methods. Your program should look like this:

public class Grade{

//Constructorspublic Grade(){ }public Grade(int total, int

possible){ }

//Methodspublic void addScore(int score,

int outOf){ }public double getScore(){ }

}

3.3 Commenting

Whenever you write a program, you should comment everything! Java has a standard format for writing these comments, which lets you write an API document for any class you write without doing much work at all!

In your program, look at the top right corner. There is a box that says "implementation". Choose instead "public interface". The screen should change to look very much like the API documents you have looked at. However, it will look much less detailed because we haven't written any comments yet!

In Java, there are two type of comments

either // or /* ...*/ insert a comment to make things

clearer. These comments are great—don't stop

using them!

The other type of comment is for the class documentation.

A program called javadoc can automatically generate this for you.

These comments are blue, and start with /**, and end with */.

You should write a comment like this at the beginning of your class, and for each method and constructor.

/** A class to determine your overall grade in a subject

@author The APCS class*/public class Grade{

//Constructors

/** The default constructor, starting with 0 out

of 0 points possible*/public Grade(){ }

/** A constructor that allows you to set an

initial amount of points out of a set amount

@param total Number of points earned so far @param possible Number of points possible*/public Grade(int total, int possible){ }

//Methods/** Adds a new score to the grade

@param score Number of points earned @param outOf Number of points possible*/public void addScore(int score, int outOf){ }

/** Retrieves the current score as a percentage

@return The current score*/public double getScore(){ }

}

I hear the complaining already…

Yes, it is considered good writing style to have these comments for EVERYTHING you write. Yes, I am going to be checking for them. Later on I probably won’t be as stringent, but for now, write comments. You’ll survive.

3.4 Instance Fields

Every object contains certain data. These are called instance fields. Every time you make a new grade object, what should it know about itself at all times?

• the total points earned• the total points currently possible

An instance field declaration has three parts:

An access specifier—these are usually private. Private means only other things in this class can access this.

The type (such as int) The name (such as myPoints)

Instance fields are declared outside any methods or constructors:

public class Grade { private int myPoints; private int pointsPossible;

… }

Instance fields are often named with "my" at the beginning. This isn't a rule—it just helps to show that the variable belongs to that object. Every time you make a new Grade object, that object will get its very own set of instance fields.

Since our instance fields are private, the only way to access a grade is by calling the method getGrade(). The process of hiding data and providing methods to access it is called encapsulation.

Common mistakes Beginning programmers often either make

way too many instance fields, or way too few instance fields. Remember, an instance field is what an object needs to know about itself at any given time, from various methods.– For example: Someone probably thought of

making the current percent an instance field. This is unnecessary since we can find this by calling the appropriate method at any time. This method uses the existing instance fields to find the data we want—more variables just add more chances for mistakes!

We will continue to work on picking good instance fields in future projects. Don’t worry too much yet!

3.5 Implementation

Now we finally get to write the code for our program!

We'll start with the constructors. The constructors' job is easy: to initialize each instance field. That is, to assign a value to every instance field.

Default Constructor

public Grade()

{

myPoints = 0;

pointsPossible = 0;

}

Constructor 2public Grade(int total, int possible)

{

myPoints = total;

pointsPossible = possible;

}

Make sure that the instance fields always come first in the statements—they are what we are assigning values to! The parameters are the numbers the user has to tell you in order to use your program. You then use these numbers to set up your instance fields.

Passing parameters

Passing parameters to methods or constructors is often confusing at first.

The parameters are just temporary names for data you need to get from somewhere else. The data comes from outside your class, probably from a main method somewhere. The user gives you data, which you rename for convenience.

As long as the type is correct, you don’t care what the original name of the data was.

For example:

In your main method:

int a = 15;int b = 18;Grade joeChemGrade = new Grade(a, b);

Now, inside the Grade constructor you have total = 15 and possible = 18. You don’t know or care that their original names were a and b. You just want to use the values temporarily to set up your instance fields. Then you’re done with them!

Now the methods . . .

public void addScore(int score, int outOf)

{

int newScore = myPoints + score;

int newTotal = pointsPossible + outOf;

myPoints = newScore;

pointsPossible = newTotal;

}

The more advanced version of this method…proceed with caution!

public void addScore(int score, int outOf)

{

myPoints = myPoints + score;

pointsPossible = pointsPossible + outOf;

}

Amazingly legal Why does this work? Remember, in java, =

does NOT mean “equals”. It means “assign”. So you are really saying “Take the current

value of myPoints, add score, and then assign this new value to myPoints (overwriting the old value).”

This is the same thing the first version of the method did—the second version just does it with less writing.

Either version is perfectly acceptable!

Next method . . .

public double getGrade()

{

double currentGrade = (double)

myPoints/pointsPossible;

return currentGrade;

}

A few comments on this method

Returning data: This method had a return type (of double). That means the very last thing we should do is return a double. If you forget to return something after you have promised to in the header, the compiler will complain.

If you put more code after the return line, it will never be reached—the return must be last.

Trust me for now

You may also be wondering about the (double) in the code. This has to do with how math is done in Java. You’ll learn all about it next chapter. For now, just go with it.

For those of you who are really thinking… Did you notice a potential downfall of our

program? What if someone tries to call getGrade without entering any scores first? The computer would try to divide by zero . . . a big no-no.

As we get better, we will be able to put in checks to make sure this doesn’t happen. For now, we have to trust that our users are going to be responsible and not try to do this. I know, not a great solution. Be patient though, it will get better.

OK, I think that does it for now. Time to compile . . .

Does it work?

And test it!

Test your program once it compiles by right-clicking on it and selecting one of the constructors.

You can then right-click on the red box that appears and try our methods to make sure they work properly.

Sorry, we still aren’t done with this chapter!

3.7 Kinds of Variables

We have worked with three different kinds of variables this chapter.

Instance fields (or instance variables): These are declared at the beginning of a

class. Each object that is created gets its own set of instance fields.

The lifetime (how long it lasts) of an instance field is much longer than other variables—these variables will stay "alive" until the object no longer exists (is no longer used in any method).

Local variables:

These are created inside a particular method. In the addScore method, we created a local variable named newScore. This variable has a much shorter lifetime—it is not created until someone calls the method addScore. As soon as the method reaches the end, the variable "dies". When someone calls this method again, a new variable is created and then dies.

Parameter variables:

These are declared in the header of a method, like outOf for the method addScore. Like local variables, these only last as long as the method they belong to. Once the method is over, they die. They cannot be used in any other methods.

Initializing

Another important difference between these variables (besides lifetime) is how they are initialized. Local and parameter variables must be initialized before you can use them. If you forget, the compiler complains.

Instance fields

Instance fields, however, do not have to be initialized: they have a default value. If you forget, the compiler automatically sets any numbers equal to 0 and any object references to null.

Null

This special word refers to no object at all. – String var = null; //no object– String var2 = “”; //an object

“Null” is a little confusing at first--don’t worry about it!

A tip . . .

Even though the compiler will let you get away with this, it is still a good idea to initialize every instance field yourself in every constructor. You can avoid lots of mistakes later on by doing this.

3.8 Implicit and Explicit Parameters Revisited Explicit parameters are the extra

information you put in the parentheses. Implicit parameters are the objects that

call a method. This lets you know what instance fields you can use.

Look at the method getGrade that we wrote. It uses myPoints and pointsPossible to figure out the grade. But every Grade object we make will have its very own copy of myPoints and pointsPossible. There could be hundreds of myPoints variables! To get the right one, the method must have an implicit variable—an object that is calling it with its own myPoints.

janesGrade.getGrade(); //uses janesGrade’s myPoints

paulsGrade.getGrade();//uses paulsGrade’s myPoints

Keyword “this”

You could technically say this.myPoints in the method to tell the computer which myPoints to use—the implicit parameter is always referred to as this inside a method. Some people like to always put this in, others let the compiler figure it out. It’s just a matter of taste.

Only one . . .

Every method is allowed one implicit parameter, although they can have many explicit parameters.

Chap 3 Partner Assignment

Chapter 3 Project: Designing a class– You will spend two days writing this class with a

partner.– You will spend part of the third day critiquing at

least one other group’s program, and part of the time fixing your program.

– To hand in: Your rough draft, including comments and signatures from at least one other group, and your final draft fixing any issues.

Chapter 3 Individual Assignment

Review Exercises: 1-12– You need to read the book examples of

Bank Account to do these!

Programming Exercises: 6, 8, 9, 10