| CSCI A201/A597Lecture Notes 11 Spring 2000 |
First we note that there's an exam coming up on Feb 24-25, the first practical exam. You already know what it will be on, you will have two hours to produce a two-dimensional pattern that will be communicated to you at the time of the exam. Patterns will be distributed randomly, in class.
To see how this works we will have this Friday for a practical mock-up in which you will have one hour to produce a simpler pattern that will be distributed in class. Note however that the mock-up practical is not as strict as the real practical about the distribution of patterns.
In addition the mock-up practical will be open-book and your grade on it will be a bonus on the real practical (up to 10%). So if you have a perfect mock-up practical and a perfect practical you'll end up with 110% on the real practical.
Hopefully that much is clear.
A few other considerations:
Now let's get to the new stuff.
We've covered primitive types and we're pretty comfortable with them.
We review them here for reference:
int to work with)
double)
boolean is true or false)
char)
int could be used to store the age of a person (e.g., a student)
double could be used to store the GPA of a student
boolean could store whether that student is eligible or not for a type of award
'M' or an 'F' for the student's gender
Strings. They are not primitive types but we have started working with them already.
A String could store the student's name.
Let's say then that when we think of a Student (for the purpose
of this example or this discussion only) we only look at the following pieces
of information for any student:
age
gender
eligibile-ity for financial aid
gpa, and
name
objects
whose description is given by the definition of classes. For example we can group all the definitions mentioned above in a class definition such as this:
public class Student {
int age;
char gender;
boolean eligible;
double gpa;
String name;
}
And we now have a data structure that contains all the elements that we use to
model a student in this particular case. How do we store information about one particular student in this model?
Let's say we want to describe two students, s1 and s2.
The first one
The test program will be in a class called PlayOne.
You will see that this is very close to setting up the cast (as in the set of actors) and screenplay for a dramatic production. It all happens according to your instructions. You're the director.
The first play simply comes up with the actors, but they don't do anything.
public class PlayOne {
public static void main(String[] args) {
Student s1 = new Student();
s1.name = "Mark Anderson";
s1.gpa = 3.75;
s1.eligible = false;
s1.gender = 'M';
s1.age = 21;
Student s2 = new Student();
s2.name = "Sarah Johnson";
s2.gpa = 3.9;
s2.eligible = true;
s2.gender = 'F';
s2.age = 20;
}
}
We need to explain how this works.
We will draw a diagram in class and
trace the program step by step. What we need to realize is this: that every
time we need a new Student data structure we can obtain a fresh one
that matches the blueprint defined above. Each student data structure, or student
record, will have 5 fields, of the types enumerated above, initially empty.
We keep a pointer to
the record in a variable of type Student (such as s1
and s2 above). We access the individual fields with the dot notation:
name of structure, dot, name of field.
This structure only keeps together data. But it could also keep together procedures, or methods, not just data. Let's look at another example. Let's say that all we care for in a baseball player, for the purpose of our second play, is the name of the player and the team for which he currently plays.
Write a description for a class (data structure) BaseballPlayer. Then set
up a play in which there are two baseball players, one named Sammy Sosa that plays for
Chicago Cubs, and another one Mark McGwire, playing for the St. Louis Cardinals. The
players need not do anything in this play other than show up and be themselves.
Here's the description of the class:
public class BaseballPlayer {
String name;
String team;
}
And here's the play:
public class PlayTwo {
public static void main(String[] args) {
BaseballPlayer b1 = new BaseballPlayer();
BaseballPlayer b2 = new BaseballPlayer();
b1.name = "Sammy Sosa";
b2.name = "Mark McGwire";
b1.team = "Chicago Cubs";
b2.team = "St. Louis Cardinals";
}
}
That's all there is to it. It's like a play, but underneath two records (or data structures) get initialized. The initialization procedure can be specified as part of the class definition in the form of a constructor.
First we need to mention that before we assign any values the them, the fields in the defintion of the data structure get initialized to default values as follows:
boolean fields get initialized to false
Strings get initialized to null
Slugger,
that will contain: Slugger data structure will be very similar
with the BaseballPlayer of a few lines above, except
it will define one more variable, call it homeRuns.
public class Slugger {
String name;
String name;
int homeRuns;
}
Let's say the play (PlayThree) now involves two Sluggers by the
names of Sammy Sosa (Chicago Cubs) and Mark McGwire (Cardinals) that keep hitting home run
after home run. Our story starts with McGwire at 59, and Sosa at 61. McGwire hits three more
home runs, and then the unexplainable happens: he moves to the Atlanta Braves. Let's write this short play:
public class PlayThree {
public static void main(String[] args) {
System.out.println("You are watching PlayThree with Mark McGwire ");
Slugger s1 = new Slugger();
s1.name = "Mark McGwire";
s1.team = "St. Louis Cardinals";
s1.homeRuns = 59;
System.out.println("... and Sammy Sosa.");
Slugger s2 = new Slugger();
s2.name = "Sammy Sosa";
s2.team = "Chicago Cubs";
s2.homeRuns = 61;
System.out.println("Mark hits 3 more to reach 62");
s1.homeRuns = s1.homeRuns + 3;
System.out.println("... and then he moves to Atlanta.");
s1.team = "Atlanta Braves";
}
}
Run this play, experience it, strive to understand it. Now let's come back with a question: what are constructors?
They are parameterized initialization procedures.
Data can be specified at the time of creation, such as in the following rewriting of PlayThree:
public class PlayThree {
public static void main(String[] args) {
System.out.println("You are watching PlayThree with Mark McGwire ");
Slugger s1 = new Slugger("Mark McGwire", "St. Louis Cardinals", 59);
System.out.println("... and Sammy Sosa.");
Slugger s2 = new Slugger("Sammy Sosa", "Chicago Cubs", 61);
System.out.println("Mark hits 3 more to reach 62");
s1.homeRuns = s1.homeRuns + 3;
System.out.println("... and then he moves to Atlanta.");
s1.team = "Atlanta Braves";
}
}
For this to be a valid play we need to define the initialization procedure
in the description of class Slugger. Keep the following in mind:
the order in which we pass data to the the initialization procedure is very
important. For example in the code above we pass
In class Slugger we add the initialization procedure (in blue):
public class Slugger {
String name;
String name;
int homeRuns;
Slugger(String n, String t, int h) {
name = n;
team = t;
homeRuns = h;
}
}
So now class Slugger is complete and ready for PlayThree.
(I hope that you enter these programs in your computers, compile and run them). How does the constructor work?
Essentially when it's called the actual parameters ("Sammy Sosa", "Chicago Cubs",
61) match the types (String, String, int) and the order
of the formal arguments (in the abstract definition of the initialization procedure) and for the duration of
the initialization procedure will be known under the formal parameters' names (n, t
and h).
The fields defined by the Slugger data structure definition are called: instance variables and
are going to be available directly (that is, by their names) to the initialization procedure as long as care
is taken to ensure that none of the parameters in the definition has the same name as one of the fields of
the class. That's why we named the parameters n, t and h respectively.
We need to do one more thing and then we will be prepared for the rest of chapter 2 and all of chapter 8, as well
as chapter 4: let's teach the Sluggers to introduce themselves, by reporting to us (upon our request)
their names, teams for which they play, and number of home runs hit that season.
There are many ways of doing this, but one results in the following modification to the Slugger class:
public class Slugger {
String name;
String team;
int homeRuns;
Slugger(String n, String t, int h) {
name = n;
team = t;
homeRuns = h;
}
void talk() {
System.out.println("Hello, my name is " + name +
" and I play for " + team + ".\nI have hit " +
homeRuns + " home runs " + "so far.\n");
}
}
So talk() is a procedure that describes what should happen when
a Slugger is required to talk(). Notice that parentheses don't
contain any formal arguments declarations, so there will be no actual parameters passed to
it when invoked.
The definition of talk() indicates that the function is not
returning anything as a result of being invoked. That's the meaning of the
void with which its definition starts.
Here's PlayFour:
public class PlayFour {
public static void main(String[] args) {
Slugger s1, s2;
s1 = new Slugger("Mark McGwire", "St. Louis Cardinals", 59);
s2 = new Slugger("Sammy Sosa", "Chicago Cubs", 61);
s1.talk();
s2.talk();
s1.homeRuns = s1.homeRuns + 3;
s1.talk();
s1.team = "Atlanta Braves";
s1.talk();
s2.talk();
}
}
Here's the output of this play if we compile and run it:
Before we move on to finish the overview of thefrilled.cs.indiana.edu%javac PlayFour.java frilled.cs.indiana.edu%java PlayFour Hello, my name is Mark McGwire and I play for St. Louis Cardinals. I have hit 59 home runs so far. Hello, my name is Sammy Sosa and I play for Chicago Cubs. I have hit 61 home runs so far. Hello, my name is Mark McGwire and I play for St. Louis Cardinals. I have hit 62 home runs so far. Hello, my name is Mark McGwire and I play for Atlanta Braves. I have hit 62 home runs so far. Hello, my name is Sammy Sosa and I play for Chicago Cubs. I have hit 61 home runs so far. frilled.cs.indiana.edu%
element package we need to
make sure you have been exposed to one more concept, without which some notation will seem
mysterious, probably.
Let's say we write a short play with the three Stooges.
Each Stooge has a name, and can talk().
Beeing stooges they each have a supervisor, another Stooge.
When they talk() they say their name and their supervisor's name.
Here's the Stooge class.
public class Stooge {
String name;
Stooge supervisor;
Stooge(String n) {
name = n;
}
void talk() {
System.out.println("I'm " + name + " Stooge " +
"playing subordinate to " + supervisor.name);
}
}
The initialization procedure only needs to know the name of the Stooge that is being
created since the supervisor fields can be initialized only after all the Stooges are
available. So we do that from the main play called StoogesPlay.
Here's the StoogesPlay:
public class StoogesPlay {
public static void main(String[] args) {
Stooge l = new Stooge("Larry"),
c = new Stooge("Curly"),
m = new Stooge("Moe");
l.supervisor = m;
m.supervisor = c;
c.supervisor = l;
l.talk();
m.talk();
m.supervisor.talk();
}
}
The last line looks very much like
c.out.println();
where c is a reference to a
ConsoleWindow
type of object.
Here's the output of StoogesPlay:
If this last example is a bit tricky (it should not be) work a simpler one, in which anyfrilled.cs.indiana.edu%ls -ld Stooge* -rw------- 1 dgerman 310 Feb 15 02:42 Stooge.java -rw------- 1 dgerman 406 Feb 15 02:47 StoogesPlay.java frilled.cs.indiana.edu%javac StoogesPlay.java frilled.cs.indiana.edu%java StoogesPlay I'm Larry Stooge playing subordinate to Moe I'm Moe Stooge playing subordinate to Curly I'm Curly Stooge playing subordinate to Larry frilled.cs.indiana.edu%
Stooge will have a preferred Slugger and
create the sluggers first then pass them to the initialization procedure of the
Stooge class. But this example should be clear enough as it is.
We will next move to describe
ConsoleWindow and
DrawingWindow classes
element package completely. The vast majority of the examples will be from Chapter 2, which you are encouraged to devour (as in to read up greedily or ravenously) while thinking of this set of lecture notes that you are reading now. All the examples in Chapter 2 will be presented and described by analogy with what has been presented here.
And we are now ready for chapter 4, 5 and 8, in that order.