Lab: Experimenting with Static Members
Instructions:
Answer the following questions one at a time. After answering each question,
check your answer (by clicking on the check-mark icon if it is available)
before proceeding to the next question.
Getting Ready:
Before going any further, you should:
-
Depending on your development environment, create either a
directory or a project for this lab.
-
Setup your development environment.
-
Download the following files:
to an appropriate directory/folder. (In most browsers/OSs, the
easiest way to do this is by right-clicking/control-clicking on
each of the links above.)
1. Understanding Static Members:
This part of the lab will help you understand the difference between
static and non-static members.
-
Read and understand the
AccessCard
class and the
main class named Driver
.
-
Compile and execute
Driver
.
What was output?
After constructing bernstein...
Prof. Bernstein is number 1
Classrooms true
Dorms false
Offices true
After constructing fred...
Fred Flintstone is number 2
Classrooms false
Dorms true
Offices false
After constructing rose...
Pres. Rose is number 3
Classrooms true
Dorms true
Offices true
Before exiting...
Prof. Bernstein is number 1
Classrooms true
Dorms false
Offices true
Fred Flintstone is number 2
Classrooms false
Dorms true
Offices false
Pres. Rose is number 3
Classrooms true
Dorms true
Offices true
-
Make all of the
boolean
attributes in the
AccessCard
class static.
What change did you make?
Changed:
private boolean classroomAccess, dormAccess, officeAccess;
to:
private static boolean classroomAccess, dormAccess, officeAccess;
-
Compile
AccessCard
and execute Driver
.
What was output?
After constructing bernstein...
Prof. Bernstein is number 1
Classrooms true
Dorms false
Offices true
After constructing fred...
Fred Flintstone is number 2
Classrooms false
Dorms true
Offices false
After constructing rose...
Pres. Rose is number 3
Classrooms true
Dorms true
Offices true
Before exiting...
Prof. Bernstein is number 1
Classrooms true
Dorms true
Offices true
Fred Flintstone is number 2
Classrooms true
Dorms true
Offices true
Pres. Rose is number 3
Classrooms true
Dorms true
Offices true
-
Why do all of the
AccessCard
objects have the
same access rights "before exiting"?
Static attributes belong to the class. So, all objects in the
AccessCard
class have the same
classroomAccess
, dormAccess
, and
officeAccess
attributes.
-
Why do all of the
AccessCard
objects have attributes
that allow access to classrooms, dorms, and offices? In other words,
why are the access attributes of all of the objects
true
?
The last call to the setAccessRights()
method was
passed true, true, true
.
-
Fix this defect. In other words, make all of
the
boolean
attributes in the
AccessCard
class non-static.
What change did you make?
Changed:
private static boolean classroomAccess, dormAccess, officeAccess;
back to:
private boolean classroomAccess, dormAccess, officeAccess;
2. Understanding Static and Non-Static Contexts:
This part of the lab will help you understand the concepts
"static context" and "non-static context".
-
Modify the
Driver
class, replacing:
rose.setAccessRights(true, true, true);
with:
AccessCard.setAccessRights(true, true, true);
-
Compile
Driver
-
What error was generated?
Driver.java:19: non-static method setAccessRights(boolean,boolean,boolean) cannot be referenced from a static context
AccessCard.setAccessRights(true, true, true);
^
1 error
-
Why was this message generated?
This error was generated because the new line in the Driver
class is treating the setAccessRights()
method as if
it is static when it isn't.
-
What does it mean when someone says you are behaving like one of 10,000
monkeys at 10,000 keyboards?
If you put 10,000 monkeys at 10,000 keyboards, they will, eventually,
write a Shakespearean play. Programmers are behaving like this when,
instead of thinking about what they are doing, they make random
changes in the hope that they will, eventually, stumble upon the
correct answer.
-
Temporarily, behave like one of 10,000 monkeys at 10,000
keyboard. Specifically, in the
AccessCard
class, make
the setAccessRights()
method static in an attempt to
correct this error.
-
Compile the
AccessCard
class. What error was generated?
AccessCard.java:58: error: non-static variable classroomAccess cannot be referen
ced from a static context
classroomAccess = classroom;
^
AccessCard.java:59: error: non-static variable dormAccess cannot be referenced f
rom a static context
dormAccess = dorm;
^
AccessCard.java:60: error: non-static variable officeAccess cannot be referenced
from a static context
officeAccess = office;
^
3 errors
-
Why were these errors generated?
These errors were generated because the static
method setAccessRights()
is using the non-static
attributes classroomAccess
, dormAccess
, and
officeAccess
. (This can't be allowed because a
static method can be used without an object having been created.
Hence, it can be used in situations in which the attributes
classroomAccess
, dormAccess
, and
officeAccess
don't exist.)
-
Continue to temporarily behave like one of 10,000 monkeys at
10,000 keyboards, and make things even worse. Specifically,
make all of the
boolean
attributes in the
AccessCard
class static.
What change did you make?
Changed:
private boolean classroomAccess, dormAccess, officeAccess;
to:
private static boolean classroomAccess, dormAccess, officeAccess;
-
Compile the
AccessCard
class. It, should compile since
the static setAccessRights()
method now uses only
static attributes.
-
Compile the
Driver
class. It, too, should compile since
the setAccessRights()
method is in fact static.
-
Should you be happy that both classes compile?
Of course not, I already know that the attributes should not
be static because every AccessCard
object should have its own
attributes.
-
Execute the
Driver
class. You should get the same
wrong results you got earlier.
-
Fix the
AccessCard
class by making the boolean
attributes non-static and by making the setAccessRights()
method non-static. What change did you make?
Changed:
private static boolean classroomAccess, dormAccess, officeAccess;
public static void setAccessRights(boolean classroom, boolean dorm, boolean office)
back to:
private boolean classroomAccess, dormAccess, officeAccess;
public void setAccessRights(boolean classroom, boolean dorm, boolean office)
-
Compile
AccessCard
. It should compile.
-
Modify the
Driver
class, changing:
AccessCard.setAccessRights(true, true, true);
back to:
rose.setAccessRights(true, true, true);
-
Compile
Driver
. It should compile.
-
Execute
Driver
. It should execute properly.
3. Using Static Attributes:
One problem with the current design of the
AccessCard
class is that its users (in this case the
Driver
)
must keep track of the next account number to use. We can fix
this with a static attribute.
-
Add the following attribute to the
AccessCard
class:
private static int nextAccountNumber;
-
In the
AccessCard
class's constructor, change:
this.number = number;
to:
this.number = nextAccountNumber;
-
Compile
AccessCard
and Execute Driver
.
What output was generated?
After constructing bernstein...
Prof. Bernstein is number 0
Classrooms true
Dorms false
Offices true
After constructing fred...
Fred Flintstone is number 0
Classrooms false
Dorms true
Offices false
After constructing rose...
Pres. Rose is number 0
Classrooms true
Dorms true
Offices true
Before exiting...
Prof. Bernstein is number 0
Classrooms true
Dorms false
Offices true
Fred Flintstone is number 0
Classrooms false
Dorms true
Offices false
Pres. Rose is number 0
Classrooms true
Dorms true
Offices true
-
This output is obviously incorrect, since each
AccessCard
object now has the same number. Why is it incorrect?
We forgot to increase
nextAccountNumber
. To fix this
problem, add the following line to the bottom of the constructor:
++nextAccountNumber;
-
Compile
AccessCard
and execute Driver
What output was generated?
After constructing bernstein...
Prof. Bernstein is number 0
Classrooms true
Dorms false
Offices true
After constructing fred...
Fred Flintstone is number 1
Classrooms false
Dorms true
Offices false
After constructing rose...
Pres. Rose is number 2
Classrooms true
Dorms true
Offices true
Before exiting...
Prof. Bernstein is number 0
Classrooms true
Dorms false
Offices true
Fred Flintstone is number 1
Classrooms false
Dorms true
Offices false
Pres. Rose is number 2
Classrooms true
Dorms true
Offices true
-
Remove the formal parameter
number
from the
constructor in AccessCard
since it is no longer
needed.
-
Remove the actual parameter corresponding to
number
in each of the uses of the constructor in Driver
.
-
Compile
AccessCard
and Driver
.
-
The card numbers now start at 0 and I'd prefer that they start at 10.
So, we obviously need to initialize
nextAccountNumber
.
As a first attempt, add the following line to the top of the
constructor in AccessCard
:
nextAccountNumber = 10;
-
Compile
AccessCard
and execute Driver
.
What output was generated?
After constructing bernstein...
Prof. Bernstein is number 10
Classrooms true
Dorms false
Offices true
After constructing fred...
Fred Flintstone is number 10
Classrooms false
Dorms true
Offices false
After constructing rose...
Pres. Rose is number 10
Classrooms true
Dorms true
Offices true
Before exiting...
Prof. Bernstein is number 10
Classrooms true
Dorms false
Offices true
Fred Flintstone is number 10
Classrooms false
Dorms true
Offices false
Pres. Rose is number 10
Classrooms true
Dorms true
Offices true
-
Why does every
AccessCard
object now have the number
10?
Because nextAccountNumber
, which is static, is being
initialized every time the constructor is called.
-
To fix this problem, first delete the following line in the
constructor in
AccessCard
:
nextAccountNumber = 10;
Now, change:
private static int nextAccountNumber;
to:
private static int nextAccountNumber = 10;
-
Compile
AccessCard
and execute Driver
.
What output was generated?
After constructing bernstein...
Prof. Bernstein is number 10
Classrooms true
Dorms false
Offices true
After constructing fred...
Fred Flintstone is number 11
Classrooms false
Dorms true
Offices false
After constructing rose...
Pres. Rose is number 12
Classrooms true
Dorms true
Offices true
Before exiting...
Prof. Bernstein is number 10
Classrooms true
Dorms false
Offices true
Fred Flintstone is number 11
Classrooms false
Dorms true
Offices false
Pres. Rose is number 12
Classrooms true
Dorms true
Offices true
-
This output is now correct.
-
To make sure you really understand what's going on,
make
nextAccountNumber
non-static.
-
Compile
AccessCard
and execute Driver
.
What output was generated?
After constructing bernstein...
Prof. Bernstein is number 10
Classrooms true
Dorms false
Offices true
After constructing fred...
Fred Flintstone is number 10
Classrooms false
Dorms true
Offices false
After constructing rose...
Pres. Rose is number 10
Classrooms true
Dorms true
Offices true
Before exiting...
Prof. Bernstein is number 10
Classrooms true
Dorms false
Offices true
Fred Flintstone is number 10
Classrooms false
Dorms true
Offices false
Pres. Rose is number 10
Classrooms true
Dorms true
Offices true
-
Why does every
AccessCard
object again have a number of 10?
Now it's because each AccessCard
object has its
own nextAccountNumber
attribute. Make sure you
understand why this is a problem!
-
Fix
nextAccountNumber
by making it static.
-
Compile
AccessCard
.
4. Using Static Methods:
This part of the lab will help you understand one use of static
methods.
-
Add the following method to the
AccessCard
class:
public static void setFirstAccountNumber(int n)
{
nextAccountNumber = n;
}
-
Compile
AccessCard
.
-
Add the following line to the top of the
main()
method in Driver
:
AccessCard.setFirstAccountNumber(5000);
-
Compile and execute
Driver
.
-
What output was generated?
After constructing bernstein...
Prof. Bernstein is number 5000
Classrooms true
Dorms false
Offices true
After constructing fred...
Fred Flintstone is number 5001
Classrooms false
Dorms true
Offices false
After constructing rose...
Pres. Rose is number 5002
Classrooms true
Dorms true
Offices true
Before exiting...
Prof. Bernstein is number 5000
Classrooms true
Dorms false
Offices true
Fred Flintstone is number 5001
Classrooms false
Dorms true
Offices false
Pres. Rose is number 5002
Classrooms true
Dorms true
Offices true