Chapter 6
Spring 2007
CS 101
Aaron Bloomfield
1
2
More on classes vs. objects
3
A new example: creating a Car class
What properties does a car have in the real world?
Color
Position (x,y)
Fuel in tank
We will implement these properties in our Car class public class Car { private Color color; private int xpos; private int ypos; private int fuel;
//...
}
4
Car’s instance variables public class Car { private Color color; private int xpos; private int ypos; private int fuel;
//...
}
- color
- fuel
+ …
Car
- xpos
- ypos
5
Instance variables and attributes
Default initialization
If the variable is within a method, Java does NOT initialize it
If the variable is within a class, Java initializes it as follows:
Car
Numeric instance variables initialized to 0
- color = null - xpos = 0
Logical instance variables initialized to false
- fuel = 0
+ …
- ypos = 0
Object instance variables initialized to null
6
Car behaviors or methods
What can a car do? And what can you do to a car?
Move it
Change it’s x and y positions
Change it’s color
Fill it up with fuel
For our computer simulation, what else do we want the Car class to do?
Create a new Car
Plot itself on the screen
Each of these behaviors will be written as a method
7
Creating a new car
To create a new Car, we call:
Car c = new Car();
Notice this looks like a method
You are calling a special method called a constructor
A constructor is used to create (or construct) an object
It sets the instance variables to initial values
The constructor: public Car() { fuel = 1000; color = Color.BLUE;
}
8
Constructors
No return type!
For now, all constructors are public
EXACT same name as class public Car() { fuel = 1000; color = Color.BLUE;
}
9
Our Car class so far public class Car { private Color color; private int xpos; private int ypos; private int fuel; public Car() { fuel = 1000; color = Color.BLUE;
} } public class Car { private Color color =
Color.BLUE
; private int xpos; private int ypos; private int fuel = 1000 ; public Car() {
}
}
10
Our Car class so far public class Car { private Color color =
Color.BLUE; private int xpos = 0 ; private int ypos = 0 ; private int fuel = 1000;
Car
- color = Color.BLUE
- fuel = 1000
+ Car()
+ …
- xpos = 0
- ypos = 0 public Car() {
}
}
Called the default constructor
The default constructor has no parameters
If you don’t include one, Java will SOMETIMES put one there automatically 11
AlienSong.mpg
12
Another constructor
Another constructor: public Car (Color c, int x, int y, int f) { color = c; xpos = x; ypos = y; fuel = f;
}
This constructor takes in four parameters
The instance variables in the object are set to those parameters
This is called a specific constructor
An constructor you provide that takes in parameters is called a specific constructor
13
}
Our Car class so far public class Car { private Color color =
Color.BLUE; private int xpos = 0; private int ypos = 0; private int fuel = 1000; public Car() {
}
Car
- color = Color.BLUE
- fuel = 1000
- xpos = 0
- ypos = 0
+ Car()
+ Car (Color, int, int, int)
+ … public Car (Color c, int x, int y, int f) { color = c; xpos = x; ypos = y; fuel = f;
}
14
Using our Car class
Now we can use both our constructors:
Car c1 = new Car();
Car c2 = new Car (Color.BLACK, 1, 2, 500); c1 c2
Car
- color = Color.BLUE
- fuel = 1000
+ Car()
+ Car (Color, int, int, int)
+ …
- xpos = 0
- ypos = 0
Car
- color = Color.BLACK
- fuel = 500
- xpos = 1
- ypos = 2
+ Car()
+ Car (Color, int, int, int)
+ …
15
So what does private mean?
Consider the following code
Note that it’s a different class!
public class CarSimulation { public static void main (String[] args) {
Car c = new Car();
System.out.println (c.fuel);
}
}
Recall that fuel is a private instance variable in the Car class
Private means that code outside the class CANNOT access the variable
For either reading or writing
Java will not compile the above code
If fuel were public, the above code would work 16
So how do we get the fuel of a Car?
Via accessor methods in the Car class: public int getFuel() {
} return fuel; public Color getColor() { return color;
} public int getYPos() { return ypos;
} public int getXPos() {
} return xpos;
As these methods are within the Car class, they can read the private instance variables
As the methods are public, anybody can call them
18
So how do we set the fuel of a Car?
Via mutator methods in the Car class: public void setFuel (int f) {
} fuel = f; public void setColor (Color c) { color = c;
} public void setXPos (int x) { xpos = x;
} public void setYPos (int y) { ypos = y;
}
As these methods are within the Car class, they can read the private instance variables
As the methods are public, anybody can call them
19
Why use all this?
These methods are called a get/set pair
Used with private variables
We’ll see why one uses these later in this slide set
Our Car so far:
Car
- color = Color.BLUE
- fuel = 1000
- xpos = 0
- ypos = 0
+ Car()
+ Car (Color, int, int, int)
+ void setXPos (int x)
+ void setYPos (int y)
+ void setColor (Color c)
+ void setFuel (int f)
+ int getFuel()
+ int getXPos()
+ int getYPos()
+ Color getColor()
+ …
20
Back to our specific constructor public class Car { private Color color =
Color.BLUE; private int xpos = 0; private int ypos = 0; private int fuel = 1000; public class Car { private Color color =
Color.BLUE; private int xpos = 0; private int ypos = 0; private int fuel = 1000;
}
} public Car (Color c, int x, int y, int f) { color = c; xpos = x; ypos = y; fuel = f;
}
} public Car (Color c, int x, int y, int f) { setColor (c); setXPos (x); setYPos (y); setFuel (f);
21
Back to our specific constructor
Using the mutator methods (i.e. the ‘set’ methods) is the preferred way to modify instance variables in a constructor
We’ll see why later
22
23
So what’s left to add to our Car class?
What else we should add:
A mutator that sets both the x and y positions at the same time
A means to “use” the Car’s fuel
A method to paint itself on the screen
Let’s do the first: public void setPos (int x, int y) { setXPos (x); setYPos (y);
}
Notice that it calls the mutator methods 24
Using the Car’s fuel
Whenever the Car moves, it should burn some of the fuel
For each pixel it moves, it uses one unit of fuel
We could make this more realistic, but this is simpler
Math.abs() returns the absolute value public void setXPos (int x) { xpos = x;
} public void setXPos (int x) { fuel -= Math.abs
(getXPos()-x); xpos = x;
} public void setYPos (int y) { ypos = y;
} public void setYPos (int y) { fuel -= Math.abs
(getYPos()-y);
25 ypos = y;
}
Setting both positions at once public void setPos (int x, int y) { setXPos(x); setYPos(y);
}
Notice that to modify the instance variables, the mutator methods are used
26
Drawing the Car
The simple way to have the Car draw itself:
} public void paint (Graphics g) { g.setColor (color); g.fillRect (xpos-50, ypos-100,
100, 200);
This draws a single rectangle that is 100 by 200 pixels in size
Lets use constants for the car’s height and width...
27
Drawing the Car
A better version: private final int CAR_WIDTH = 100; private final int CAR_HEIGHT = 200; public void paint (Graphics g) { g.setColor (color); g.fillRect (getXPos()CAR_WIDTH/2 , getYPos()CAR_HEIGHT/2 ,
CAR_WIDTH , CAR_HEIGHT );
}
This makes it easier to change the car size
We could have made the car size instance variables and set them via mutators
28
Lets add tires!
Drawing the Car private final int CAR_WIDTH = 100; private final int CAR_HEIGHT = 200; private final int TIRE_WIDTH = 20; private final int TIRE_HEIGHT = 40; private final int TIRE_OFFSET = 20; public void paint (Graphics g) { g.setColor (color); g.fillRect (getXPos()-CAR_WIDTH/2, getYPos()-CAR_HEIGHT/2,
CAR_WIDTH, CAR_HEIGHT);
// Draw the tires g.setColor (Color.BLACK); g.fillRect (getXPos()-(CAR_WIDTH/2+TIRE_WIDTH), getYPos()-(CAR_HEIGHT/2-TIRE_OFFSET), TIRE_WIDTH, TIRE_HEIGHT); g.fillRect (getXPos()-(CAR_WIDTH/2+TIRE_WIDTH), getYPos()+(CAR_HEIGHT/2-TIRE_OFFSET-TIRE_HEIGHT),
TIRE_WIDTH, TIRE_HEIGHT); g.fillRect (getXPos()+(CAR_WIDTH/2), getYPos()+(CAR_HEIGHT/2-TIRE_OFFSET-TIRE_HEIGHT),
Don’t worry about this – just know that it draws four tires
TIRE_WIDTH, TIRE_HEIGHT); g.fillRect (getXPos()+(CAR_WIDTH/2), getYPos()-(CAR_HEIGHT/2-TIRE_OFFSET), TIRE_WIDTH, TIRE_HEIGHT);
}
29
What happens when the car runs out of fuel?
We could do a number of things:
Not allow the car to move anymore
Print out a message saying, “fill me up!”
We’ll color the car red
We’ll insert the following code at the beginning of the paint() method: if ( fuel < 0 ) { color = Color.RED;
}
30
Drawing the Car private final int CAR_WIDTH = 100; private final int CAR_HEIGHT = 200; private final int TIRE_WIDTH = 20; private final int TIRE_HEIGHT = 40; private final int TIRE_OFFSET = 20; public void paint (Graphics g) { if ( fuel < 0 ) { color = Color.RED;
} g.setColor (color); g.fillRect (getXPos()-CAR_WIDTH/2, getYPos()-CAR_HEIGHT/2,
CAR_WIDTH, CAR_HEIGHT);
// Draw the tires g.setColor (Color.BLACK); g.fillRect (getXPos()-(CAR_WIDTH/2+TIRE_WIDTH), getYPos()-(CAR_HEIGHT/2-TIRE_OFFSET), TIRE_WIDTH, TIRE_HEIGHT); g.fillRect (getXPos()-(CAR_WIDTH/2+TIRE_WIDTH), getYPos()+(CAR_HEIGHT/2-TIRE_OFFSET-TIRE_HEIGHT),
TIRE_WIDTH, TIRE_HEIGHT); g.fillRect (getXPos()+(CAR_WIDTH/2), getYPos()+(CAR_HEIGHT/2-TIRE_OFFSET-TIRE_HEIGHT),
TIRE_WIDTH, TIRE_HEIGHT); g.fillRect (getXPos()+(CAR_WIDTH/2), getYPos()-(CAR_HEIGHT/2-TIRE_OFFSET), TIRE_WIDTH, TIRE_HEIGHT);
}
31
CarGUI.java
32
1.
2.
3.
4.
5.
Very well! This stuff is easy!
Fairly well – with a little review, I’ll be good
Okay. It’s not great, but it’s not horrible, either
Not well. I’m kinda confused
Not at all. I’m soooooo lost.
20% 20% 20% 20% 20%
V er y w el l!
...
T hi s st uf f i
F ai rly
w el l –
O
w ith
a
li tt.
.
ka y.
I t’s
n ot
N
g re at
, b ot
w el l. u.
..
I’ m
k in
N ot
a t a da
c
...
ll.
I
’m
s oo oo o.
..
33
Cubic_tragedy_m640.mov
34
35
What I’m not expecting you to know yet…
What the static keyword means
And why the main() method is
And why other methods are not
Why you should always call the mutator methods, instead of setting the field directly
Just know that it’s a good programming practice, and follow it
We’ll see why later
Why instance variables are supposed to be private
Just know that it’s a good programming practice, and follow it
Again, we’ll see why soon
36
Terminology
An attribute of a class can be called:
Instance variable or class variable
We’ll see the difference later
Static variable (or static field)
Synonymous with class variable
Field
Generally means either type
Variable
Also means either type
Attribute
Property
Argh!
I will generally use the terms variable or field when I am not differentiating between the two
And instance variable/field and class variable/field when I am
37
The main() method
Consider a class with many methods: public class WhereToStart { public static void foo (int x) {
// ...
} public static void bar () {
// ...
} public static void main (String[] args) {
// ...
}
}
Where does Java start executing the program?
Always at the beginning of the main() method!
38
Running a class without a main() method
Consider the Car class
It had no main() method!
The main() method was in the CarSimulation (or CarGUI) class
So let’s try running it…
39
Car.java
40
Variable initialization
A local variable is NOT initialized to a default value
This is any variable declared within a method
Or within a block within a method
This is pretty stupid, in my opinion
Parameters are initialized to whatever value they are passed
Instance and class variables are initialized to default values
Numbers to zero, booleans to false, references to null
This means any field in a class
Either class variables or instance variables
41
1.
2.
3.
4.
5.
Very well! This stuff is easy!
Fairly well – with a little review, I’ll be good
Okay. It’s not great, but it’s not horrible, either
Not well. I’m kinda confused
Not at all. I’m soooooo lost.
20% 20% 20% 20% 20%
V er y w el l!
...
T hi s st uf f i
F ai rly
w el l –
O
w ith
a
li tt.
.
ka y.
I t’s
n ot
N
g re at
, b ot
w el l. u.
..
I’ m
k in
N ot
a t a da
c
...
ll.
I
’m
s oo oo o.
..
42
Introducing static-ness, visibilities, etc.
44
A Circle class
We are going to develop a Circle class
Perhaps for use in a graphics program
Why?
Partly to review creating classes
Go over some topics that were a bit fuzzy
Constructors and creating objects
Show why one uses the get/set methods instead of directly modifying the instance variables
Discuss visibilities (public, private, etc.)
Discuss the static keyword
45
Circle class properties
What properties does a circle have?
Radius
PI = 3.141592653589793234
Color (if plotting in a graphics program)
(x,y) location
These properties will become instance variables
We are only going to play with the first two (radius and
PI) in this example
Thus, we are ignoring the color and location
46
Our Circle class
Circle c = new Circle(); c public class Circle { double radius;
Note the radius field is not initialized by us double PI = 3.1415926536;
}
Circle
- radius = 0.0
PI = 3.14159…
-
…
+ …
We’re ignoring the public for now
Note the fields are not static
47
Accessing our Circle object
Any variable or method in an object can be accessed by using a period
The period means ‘follow the reference’ c
Example: System.in
Example: System.out.println
(c.radius);
Example: c.PI = 4;
This is bad – PI should have been declared final
(this will be done later)
Circle
- radius = 0.0
PI = 3.14159…
-
…
+ …
48
What’s the output?
public class Circle { double radius; double PI = 3.1415926536;
} public class CircleTest { public static void main (String[] args) { int x;
Circle c = new Circle();
System.out.println (x);
}
}
Java will give a
“variable not initialized” error
When a variable is declared as part of a method, Java does not initialize it to a default value
49
What’s the output now?
public class Circle { double radius; double PI = 3.1415926536;
} public class CircleTest { public static void main (String[] args) { int x;
Circle c = new Circle();
System.out.println (c.radius); Java outputs 0.0!
}
}
When a variable is declared as part of a class, Java does initialize it to a default value
50
What’s going on?
A (method) variable needs to be initialized before it is used
Usually called a local variable
A instance variable is automatically initialized by Java
All numbers are initialized to 0, booleans to false, etc.
This is a bit counter-intuitive…
51
Circle class behaviors
What do we want to do with (and to) our Circle class?
Create circles
Modify circles (mutators)
Find out about our circles’ properties (accessors)
Find the area of the circle
Plot it on the screen (or printer)
A few others…
These will be implemented as methods
52
Calling the Circle constructor
To create a Circle object: c1
Circle c1 = new Circle();
This does four things:
Creates the c1 reference
Creates the Circle object
Makes the c1 reference point to the Circle object
Calls the constructor with no parameters (the ‘default’ constructor)
Circle
- radius = 0.0
PI = 3.14159…
-
…
+ Circle()
+ Circle (double r)
+ …
The constructor is always the first method called when creating (or ‘constructing’) an object
53
Calling the Circle constructor
To create a Circle object: c1
Circle c1 = new Circle( 2.0
);
This does four things:
Creates the c1 reference
Creates the Circle object
Makes the c1 reference point to the Circle object
Calls the constructor with 1 double parameters (the ‘specific’ constructor)
Circle
- radius = 0.0
PI = 3.14159…
-
…
+ Circle()
+ Circle (double r)
+ …
The constructor is always the first method called when creating (or ‘constructing’) an object
54
Constructors
Remember, the purpose of the constructor is to initialize the instance variables
PI is already set, so only radius needs setting public Circle() {
} radius = 1.0;
Note there is no return type for constructors public Circle (double r) { radius = r;
}
Note that the constructor name is the EXACT same as the class name
Note that there are two “methods” with the same name!
55
What happens in memory
Consider: Circle c = new Circle();
A double takes up 8 bytes in memory
Thus, a Circle object takes up 16 bytes of memory
As it contains two doubles
Circle
Shorthand representation c c
- radius = 1.0
- PI = 3.1415926536
-
…
+ Circle()
+ Circle (double r)
+ …
Circle
- radius = 1.0
- PI = 3.14159
56
}
Circle class: our class so far public class Circle { double radius; double PI = 3.1415926536; public Circle() { radius = 1.0;
} public Circle (double r) { radius = r;
}
57
1.
2.
3.
4.
5.
Very well! This stuff is easy!
Fairly well – with a little review, I’ll be good
Okay. It’s not great, but it’s not horrible, either
Not well. I’m kinda confused
Not at all. I’m soooooo lost.
20% 20% 20% 20% 20%
V er y w el l!
...
T hi s st uf f i
F ai rly
w el l –
O
w ith
a
li tt.
.
ka y.
I t’s
n ot
N
g re at
, b ot
w el l. u.
..
I’ m
k in
N ot
a t a da
c
...
ll.
I
’m
s oo oo o.
..
58
59
}
Circle class: our class so far public class Circle { double radius; double PI = 3.1415926536; public Circle() { radius = 1.0;
} public Circle (double r) { radius = r;
}
60
Consider the following code public class CircleTest { public static void main (String[] args) {
Circle c1 = new Circle();
Circle c2 = new Circle();
Circle c3 = new Circle();
Circle c4 = new Circle();
}
}
61
What happens in memory
There are 4 Circle objects in memory
Taking up a total of 4*16 = 64 bytes of memory c1
Circle
- radius = 1.0
- PI = 3.14159
c2
Circle
- radius = 1.0
- PI = 3.14159
c3
Circle
- radius = 1.0
- PI = 3.14159
c4
Circle
- radius = 1.0
- PI = 3.14159
62
Consider the following code public class CircleTest { public static void main (String[] args) {
Circle c1 = new Circle();
//...
Circle c1000000 = new Circle();
}
} public class CircleTest { public static void main (String[] args) {
Vector v = new Vector(); for ( int i = 0; i < 1000000; i++ ) v.add (new Circle());
}
}
These programs create 1 million Circle objects!
63
What happens in memory
There are 1 million Circle objects in memory
Taking up a total of 1,000,000*16 ≈ 16 Mb of memory c1
Circle
- radius = 1.0
- PI = 3.14159
c2
Circle
- radius = 1.0
- PI = 3.14159
… c1000000
Circle
- radius = 1.0
- PI = 3.14159
Note that the final PI field is repeated 1 million times
64
The use of static for fields
If a variable is static , then there is only ONE of that variable for ALL the objects
That variable is shared by all the objects c1
Circle
- radius = 1.0
c2
Circle
- radius = 1.0
c3
…
- radius = 1.0
Circle
- radius = 1.0
PI 3.1415926536
65
More on static fields
What does the following print
Note that PI is not final
Circle c1 = new Circle();
Circle c2 = new Circle();
Circle c3 = new Circle();
Circle c4 = new Circle(); c1.PI = 4.3;
System.out.println (c2.PI);
It prints 4.3
Note you can refer to static fields by object.variable
66
Even more on static fields
There is only one copy of a static field no matter how many objects are declared in memory
Even if there are zero objects declared!
The one field is “common” to all the objects
Static variables are called class variables
As there is one such variable for all the objects of the class
Whereas non-static variables are called instance variables
Thus, you can refer to a static field by using the class name:
Circle.PI
67
Even even more on static fields
This program also prints 4.3:
Circle c1 = new Circle();
Circle c2 = new Circle();
Circle c3 = new Circle();
Circle c4 = new Circle();
Circle.PI = 4.3;
System.out.println (c2.PI);
68
Even even even more on static fields
We’ve seen static fields used with their class names:
System.in
(type: InputStream)
System.out
Math.PI
(type: OutputStream)
(type: double)
Integer.MAX_VALUE
(type: int)
Game.BOARD_X_COORD
(in HW J6)
69
1.
2.
3.
4.
5.
Very well! This stuff is easy!
Fairly well – with a little review, I’ll be good
Okay. It’s not great, but it’s not horrible, either
Not well. I’m kinda confused
Not at all. I’m soooooo lost.
20% 20% 20% 20% 20%
V er y w el l!
...
T hi s st uf f i
F ai rly
w el l –
O
w ith
a
li tt.
.
ka y.
I t’s
n ot
N
g re at
, b ot
w el l. u.
..
I’ m
k in
N ot
a t a da
c
...
ll.
I
’m
s oo oo o.
..
70
71
Back to our Circle class public class Circle { double radius; final static double PI = 3.1415926536; public Circle() { radius = 1.0;
}
Note that PI is now final and static public Circle (double r) { radius = r;
}
}
But it doesn’t do much!
72
Adding a method public class Circle { double radius; final static double PI = 3.1415926536;
// Constructors...
double computeArea () { return PI*radius*radius;
}
}
Note that a (non-static) method can use both instance and class variables
73
Using that method public class CircleTest { public static void main (String[] args) {
Circle c = new Circle(); c.radius = 2.0; double area = c.computeArea();
System.out.println (area);
}
}
Prints 12.566370614356
74
What happens when that method is called public class Circle { double radius; final static double PI = 3.1415926536; public Circle() { radius = 1.0;
} area
12.566
// other constructor double computeArea () { return PI*radius*radius;
}
} public class CircleTest { public static void main (String[] args) {
Circle c = new Circle(); c.radius = 2.0; double area = c.computeArea();
System.out.println (area);
}
} c
- radius = 2.0
PI = 3.14159…
-
…
75
}
Review of our Circle class public class Circle { double radius; final static double PI = 3.1415926536; public Circle() {
}
Slight change from before public Circle (double r) { radius = r;
} double computeArea () { return PI*radius*radius;
}
76
A note about methods/variable order
Within a method, a variable must be declared before it is used
In a class, methods and variables can be declared in any order
This is different than C++
77
Review of static for fields
If a variable is static , then there is only ONE of that variable for ALL the objects
That variable is shared by all the objects c1
Circle
- radius = 1.0
c2
Circle
- radius = 1.0
c3
…
- radius = 1.0
Circle
- radius = 1.0
PI 3.1415926536
79
Adding another method double oneOverRadius() { return 1.0/radius;
}
I couldn’t think of a good reason to divide something by the radius…
80
What happens now?
Code in class CircleTest’s main() method
Circle c = new Circle(); // c.radius is now 0.0
System.out.println (c.oneOverRadius());
Java won’t crash, but many other programming languages (C and
C++, in particular) will
So we’ll call this a ‘crash’ for the sake of this lecture
Java prints “Infinity”
Not what we wanted, though!
81
One way to fix this… public class Circle { double radius = 1.0; final static double PI = 3.1415926536;
// Constructors...
double computeArea () { return PI*radius*radius;
} double oneOverRadius() { return 1.0/radius;
}
}
Note that the radius variable is now initialized to 1.0
82
Back to our program…
This code will now run properly:
Circle c = new Circle(); // c.radius = 1.0
System.out.println (c.oneOverRadius());
But this code will “crash”:
Circle c = new Circle(); // c.radius = 1.0
c.radius = 0.0;
System.out.println (c.oneOverRadius());
83
Where the “crash” occurs public class CircleTest { public static void main
(String[] args) {
Circle c = new Circle();
// c.radius = 1.0
public class Circle { double radius = 1.0; final static double PI =
3.1415926536; c.radius = 0.0;
} double computeArea () { return PI*radius*radius;
}
}
System.out.println
(c.oneOverRadius()); double oneOverRadius() {
} return 1.0/radius;
Here is the badly written code
Here is where the “crash” occurs
84
Motivation for private fields
Problem: We do not want people using our Circle class to be able to modify the fields on their own
Solution: Don’t allow other code to modify the radius field
Give it private visibility
private means that only code within the class can modify the field
85
One way to fix this… public class Circle { private double radius = 1.0; final static double PI = 3.1415926536;
// Constructors...
double computeArea () { return PI*radius*radius;
} double oneOverRadius() { return 1.0/radius;
}
}
Note that the radius variable is now private
86
87
Back to our program…
This code will now not compile:
Circle c = new Circle(); // c.radius = 1.0
c.radius = 0.0;
System.out.println (c.oneOverRadius());
Java will give a compile-time error:
radius has private access in Circle
88
Back to our program…
This code will also not compile:
Circle c = new Circle(); // c.radius = 1.0
System.out.println (c.radius);
Java will give the same compile-time error:
radius has private access in Circle
89
The problem now…
But now you can’t modify a Circle’s radius!
Or find out what it is
Solution: Use a get/set methods in Circle:
A mutator method: void setRadius (double r) { radius = r;
}
An accessor method: double getRadius () { return radius;
}
90
Our Circle class so far public class Circle { private double radius = 1.0; final static double PI = 3.1415926536;
// Constructors...
} double computeArea () { return PI*radius*radius;
} double oneOverRadius() { return 1.0/radius;
} void setRadius (double r) { radius = r;
} double getRadius () { return radius;
}
91
Using the get/set methods public class CircleTest { public static void main
(String[] args) {
Circle c = new Circle(); c.setRadius (1.0);
System.out.println
(c.computeArea());
System.out.println
(c.getRadius());
}
}
Here a method is invoked public class Circle { private double radius = 1.0; final static double PI =
3.1415926536; double computeArea () { return PI*radius*radius;
} double oneOverRadius() { return 1.0/radius;
} void setRadius (double r) { radius = r;
}
} double getRadius () { return radius;
}
Wait! Another problem!
public class CircleTest { public static void main (String[] args) {
Circle c = new Circle(); c.setRadius (0.0);
Here is the problem now…
System.out.println (c.oneOverRadius());
}
}
93
This problem is easily fixed
Change the setRadius() method to the following void setRadius (double r) { if ( r > 0.0 ) radius = r; else radius = 1.0;
}
Now there is (almost) no way for code outside the Circle class to change the radius to zero
This is the purpose of mutators
To prevent changing the fields to a “bad” value
We’ll see another motivation in a bit
94
Visibilities in Java
There are four visibilities:
private : Only code within the same class can access the field or method
Note: “access” means reading or writing the field, or invoking the method
public : Any code, anywhere, can access the field or method
protected : Used with inheritance
We won’t get to that this semester
default : Almost the same as public
This is the default (duh!)
Note that it can’t be specified like the others
Also called ‘package’
95
A few notes on visibilities
You can NOT specify visibilities for method variables
Any method variable can only be accessed within that method
Think of it as public within the method (after it’s defined) and private outside the method
You can also specify visibilities for methods and classes
We will see this a bit in this course
96
1.
2.
3.
4.
5.
Very well! This stuff is easy!
Fairly well – with a little review, I’ll be good
Okay. It’s not great, but it’s not horrible, either
Not well. I’m kinda confused
Not at all. I’m soooooo lost.
20% 20% 20% 20% 20%
V er y w el l!
...
T hi s st uf f i
F ai rly
w el l –
O
w ith
a
li tt.
.
ka y.
I t’s
n ot
N
g re at
, b ot
w el l. u.
..
I’ m
k in
N ot
a t a da
c
...
ll.
I
’m
s oo oo o.
..
97
#include<stdlib.h> typedef unsigned int uint; char ctb[512]="33733b2663236b763e7e362b6e2e667bd393db0643034b96de9ed60b4e0e4\
69b57175f82c787cf125a1a528fca8ac21fd999d10049094190d898d001480840913d7d35246\ d2d65743c7c34256c2c6475dd9dd5044d0d4594dc9cd4054c0c449559195180c989c11058185\
081c888c011d797df0247074f92da9ad20f4a0a429f53135b86c383cb165e1e568bce8ec61bb\
3f3bba6e3a3ebf6befeb6abeeaee6fb37773f2267276f723a7a322f6a2a627fb9f9b1a0e9a9e\
1f0b8f8b0a1e8a8e0f15d1d5584cd8dc5145c1c5485cc8cc415bdfdb5a4edade5f4bcfcb4a5e\ cace4f539793120692961703878302168286071b7f7bfa2e7a7eff2bafab2afeaaae2ff"; typedef unsigned char uchar;uint tb0[11]={5,0,1,2,3,4,0,1,2,3,4};uchar* F=NULL; uint lf0,lf1,out;void
ReadKey(uchar* key){int i;char hst[3]; hst[2]=0;if(F==\
NULL){F=malloc(256);for(i=0;i<256;i++){hst[0]=ctb[2*i];hst[1]=ctb[2*i+1];F[i]=\ strtol(hst,NULL,16);}}out=0;lf0=(key[1]<<9)|key[0]|0x100;lf1=(key[4]<<16)|(key\
[3]<<8)|key[2];lf1=((lf1&0xfffff8)<<1)|(lf1&0x7)|0x8;}uchar Cipher(int sw1,\ int sw2){int i,a,b,x=0,y=0;for(i=0;i<8;i++){a=((lf0>>2)^(lf0>>16))&1;b=((lf1\
>>12)^(lf1>>20)^(lf1>>21)^(lf1>>24))&1;lf0=(lf0<<1)|a;lf1=(lf1<<1)|b;x=(x>>1)\
|(a<<7);y=(y>>1)|(b<<7);}x^=sw1;y^=sw2;return out=(out>>8)+x+y;} void \
CSSdescramble(uchar *sec,uchar *key){uint i;uchar *end=sec+0x800;uchar KEY[5]; for(i=0;i<5;i++)KEY[i]=key[i]^sec[0x54+i];ReadKey(KEY);sec+=0x80;while(sec!=\ end)*sec++=F[*sec]^Cipher(255,0);}void CSStitlekey1(uchar *key,uchar *im) {uchar k[5];int i;
ReadKey(im);for(i=0;i<5;i++)k[i]=Cipher(0,0);for(i=9;i>=0;\ i--
)key[tb0[i+1]]=k[tb0[i+1]]^F[key[tb0[i+1]]]^key[tb0[i]];}void CSStitlekey2\ (uchar *key,uchar
*im){uchar k[5];int i;ReadKey(im);for(i=0;i<5;i++)k[i]=\ Cipher(0,255);for(i=9;i>=0;i--
)key[tb0[i+1]]=k[tb0[i+1]]^F[key[tb0[i+1]]]^key\ [tb0[i]];}void CSSdecrypttitlekey(uchar
*tkey,uchar *dkey){int i;uchar im1[6]; uchar im2[6]={0x51,0x67,0x67,0xc5,0xe0,0x00};for(i=0;i<6;i++)im1[i]=dkey[i];
CSStitlekey1(im1,im2);CSStitlekey2(tkey,im1);}
98
99
How to decrypt a
DVD: in haiku form.
(Thanks, Prof. D. S. T.)
------------------------
(I abandon my exclusive rights to make or perform copies of this work, U. S. Code
Title Seventeen, section
One Hundred and Six.)
Muse! When we learned to count, little did we know all the things we could do some day by shuffling those numbers: Pythagoras said "All is number" long before he saw computers and their effects, or what they could do
Table Zero is:
Five, zero, one, two, three, four, oh, one, two, three, four.
Table One is long: two to the eighth power bytes.
Ready? Here they are:
Fifty one; then one hundred fifteen; fifty nine; thirty eight; ninety nine; thirty five; one hundred seven; one hundred eighteen; sixty two; one hundred twenty six; fifty four; forty three; one hundred ten; then
100
The world’s first illegal prime number:
4856507896573978293098418946942861377074420873513579240196520736686985134010472
3744696879743992611751097377770102744752804905883138403754970998790965395522701
1712157025974666993240226834596619606034851742497735846851885567457025712547499
9648219418465571008411908625971694797079915200486670997592359606132072597379799
3618860631691447358830024533697278181391479795551339994939488289984691783610018
2597890103160196183503434489568705384520853804584241565482488933380474758711283
3959896852232544608408971119771276941207958624405471613210050064598201769617718
0947811362200272344827224932325954723468800292777649790614812984042834572014634
8968547169082354737835661972186224969431622716663939055430241564732924855248991
2257394665486271404821171381243882177176029841255244647445055834628144883356319
0272531959043928387376407391689125792405501562088978716337599910788708490815909
7548019285768451988596305323823490558092032999603234471140776019847163531161713
0785760848622363702835701049612595681846785965333100770179916146744725492728334
8691600064758591746278121269007351830924153010630289329566584366200080047677896
7984382090797619859493646309380586336721469695975027968771205724996666980561453
3820741203159337703099491527469183565937621022200681267982734457609380203044791
2277498091795593838712100058876668925844870047077255249706044465212713040432118
2610103591186476662963858495087448497373476861420880529443
101
102
All this info from http://www-2.cs.cmu.edu/~dst/DeCSS/Gallery/
Or do a Google search for “decss gallery”
103
104
Overriding methods (and constructors)
Consider the following code:
Creates a Circle of radius 1.0
Circle c1 = new Circle ();
Circle c2 = new Circle (2.0);
Creates a Circle of radius 2.0
Java knows which constructor to call by the list of parameters
This is called “overloading”
Meaning it means multiple things, depending on the context
We’ve seen overloading before:
3+4 Performs integer addition
3.0+4.0
“3”+”4”
Performs floating-point addition
Performs string concatenation
The ‘+’ operator is overloaded
105
Overriding methods (and constructors), take 2
The following Circle constructors would not be allowed:
We are assuming PI is not final for this example public Circle() { radius = 1.0;
} public Circle (double r) { radius = r;
} public Circle (double p) {
PI = p;
}
When Circle(1.0) is called, which one is meant?
106
Using mutators in the constructor
Our second constructor has a problem: public Circle (double r) { radius = r;
}
Consider the following code:
Circle c = new Circle (0.0);
System.out.println ( c.oneOverRadius() );
The method is dividing by zero (again)
107
Using mutators in the constructor
This is easily fixed!
Our revised constructors: public Circle() { setRadius (1.0);
} public Circle (double r) { setRadius (r);
}
The mutator will properly set the radius (and won’t set it to zero)
108
Why we always use the mutators
Consider a modified version of our circle class: class Circle { double radius; double diameter;
String size;
// ...
Our mutator now looks like this:
That’s a lot of code to copy if you decide not to call the mutator!
void setRadius (double r) { if ( radius <= 0.0 ) radius = 1.0; else radius = r; diameter = 2*radius; if ( radius < 1.0 ) size = “small”; else if ( radius < 5.0 ) size = “medium”; else if ( radius < 10.0 ) size = “large”; else size = “huge”;
}
109
http://www.google.com/tisp/
http://mail.google.com/mail/help/paper/
111
An aside: scoping issues
Consider this class: class Foo { int x = 0; public Foo (int x) { x = x;
}
}
Which x is being referred to in the constructor?
Remember that Java will use the most recent x
So this doesn’t set the instance variable!
Instead, it sets the parameter equal to itself
113
An aside: scoping issues
Let’s modify that class: Another solution: class Foo { int x = 0; public Foo (int x) { this.x = x;
}
} class Foo { int x = 0; public Foo ( int y ) { x = y;
}
}
The ‘this.x’ means the instance variable x
And the ‘x’ means the parameter
Now this does the right thing
By renaming the parameter, we achieve the same effect
This very relevant to HW 7!
114
Back to the static discussion
Remember that there is one (and only one) static PI field, regardless of how many objects are declared
Consider the following method: double getPI() { return PI;
}
It doesn’t read or modify the “state” of any object
In this example, it doesn’t read/write the radius
In fact, that particular method doesn’t care anything about the objects declared
It’s only accessing a static field
115
Make getPI() static
Consider the following: static double getPI() { return PI;
}
As the method is static, it can ONLY access static fields
A static method does not care about the “state” of an object
Examples: Math.sin(), Math.tan(), Math.cos()
They don’t care about the state of any Math object
They only perform the computation
116
Invoking static methods
As with static fields, they can be called using either an object or the class name:
Circle c = new Circle();
System.out.println (c.getPI());
System.out.println (Circle.getPI());
Static methods are also called class methods
117
static methods and nonstatic fields
Consider the following (illegal) Circle method: static double getRadius() { return radius;
}
And the code to invoke it: public static void main (String[] args) {
Circle c1 = new Circle();
Circle c2 = new Circle();
Circle c3 = new Circle();
Circle c4 = new Circle();
System.out.println (Circle.getRadius());
}
118
What happening in memory
There are no Circle objects in memory
Which radius field does Circle.getRadius() want?
c1
Circle
- radius = 1.0
c2
Circle
- radius = 1.0
c3
…
- radius = 1.0
Circle
- radius = 1.0
PI 3.1415926536
119
The main static lesson
A static method cannot access or modify the state of the object it is a part of
If you remember nothing else about static methods, remember this!
120
static and nonstatic rules
Non-static fields and methods can ONLY be accessed by the object name
Static fields and methods can be accessed by EITHER the class name or the object name
Non-static methods can refer to BOTH static and non-static fields
Static methods can ONLY access static fields of the class they are part of
121
1.
2.
3.
4.
5.
Very well! This stuff is easy!
Fairly well – with a little review, I’ll be good
Okay. It’s not great, but it’s not horrible, either
Not well. I’m kinda confused
Not at all. I’m soooooo lost.
20% 20% 20% 20% 20%
V er y w el l!
...
T hi s st uf f i
F ai rly
w el l –
O
w ith
a
li tt.
.
ka y.
I t’s
n ot
N
g re at
, b ot
w el l. u.
..
I’ m
k in
N ot
a t a da
c
...
ll.
I
’m
s oo oo o.
..
122
123
Back to our main() method public static void main (String[] args)
We’ll learn about arrays in chapter 8
The method does not return a value
Any code anywhere can call this method
It’s a static method:
•Can’t access non-static fields or methods directly
•Can be called only by the class name
124
Implications of main() being static
It can call other static methods within the same class class StaticMethods { static void method1() {
System.out.println
(“hi!”) ;
} public static void main (String args[]) { method1();
}
}
Note that we didn’t have to prefix method1() with a object
Java assumes that it is in the same class
125
Another use of static methods
Let’s say we want each Circle object to have a unique identifier
The identifier will be a positive integer
So in the Circle class, we add a instance variable:
int id = 0;
Thus, each Circle object will have it’s own id number
To keep track of the last assigned id number, we will use a class variable
static int lastAssignedID = 0;
Thus, for all Circle objects created, we will have a single lastAssignedID field
126
Circle ID numbers
We can then create a method to obtain a unique ID number: public static int getID() { return ++lastAssignedID;
}
This method is static, and only can access static fields
In our Circle constructors, we put the following line:
id = getID();
127
128
129
Debugging Java code
In Main.java: In Error1.java: public class Main { public static void main
(String args[]) {
Error1 e1 = new Error1(); e1.foo(); e1.bar();
}
}
This will cause a null pointer exception!
public class Error1 { public Error1() { } public void foo() {
String s = null;
System.out.println
(s.substring(5));
}
} public void bar() { foo();
}
130
Errors/Main.java
131
What the error output means
The error output:
Exception in thread "main" java.lang.NullPointerException
at Error1.foo(Error1.java:6) at Main.main(Main.java:4)
This means that:
A null point exception happened
In the Error1.foo() method on line 6 of Error1.java
And that was called from Main.main() on line 4 of
Main.java
Note that the top two lines tell the most useful information
So we comment out the e1.foo() call in main() 132
Debugging Java code
In Main.java: In Error1.java: public class Main { public static void main
(String args[]) {
Error1 e1 = new Error1();
//e1.foo(); e1.bar();
}
} public class Error1 { public Error1() { } public void foo() {
String s = null;
System.out.println
(s.substring(5));
}
} public void bar() { foo();
}
133
Errors/Main.java
134
What the error output means
The error output:
Exception in thread "main" java.lang.NullPointerException
at Error1.foo(Error1.java:6) at Error1.bar(Error1.java:10) at Main.main(Main.java:5)
This means that:
A null point exception happened
In the Error1.foo() method on line 6 of Error1.java
And that was called from Error1.bar() on line 10 of Error.java
And that was called from Main.main() on line 5 of Main.java
Again, note that the top two lines tell the most useful information
135
cog.mov
136
137
Calling a method
Consider two Strings:
String s = “foo” ;
String t = “bar” ;
Calling s.substring(2) is different than calling t.substring(2)
Why?
Because of the object it is being called out of
The method works the same in both cases (returns the substring)
But it returns different results
Whenever we are calling a method, we also need to know which object we are calling it out of
138
Return values
Many methods return a value
Math.cos()
String.valueOf()
Consider: double d = Math.cos (90 * Math.PI/180.0);
Let’s consider the Math.cos() method public double cos (double a) { double c = 0.0;
// compute cos somehow into a variable c return c ;
}
The value c in the cos() method is copied into d
139
The return keyword
The return keyword does a few things:
Immediately terminate the current method
Pass the value back to whoever called the method
You can have a return anywhere you want
Inside loops, ifs, etc.
You can have as may returns as you want as well: public String foo (int x) { if ( x == 1 ) return “one” ; else if ( x == 2 ) return “two” ; else return “other” ;
} 140
More on returns
Consider this class: public class Foo {
// Default constructor omitted on this slide public String bar (String s) {
String t = “CS 101 ” + “ ” + s; return t;
}
}
And the code to invoke it:
Foo w = new Foo();
String x = “rules” ;
String y = foo.bar (x);
System.out.println (y);
What happens in memory?
141
String x = “rules” ; w this
Foo
+ Foo()
+ bar (String s): String
+ … x s t y
“rules"
“CS 101 rules"
}
String t = “CS 101 ” + “ ” + s;
142
Returning an object from a method
We could rewrite our bar() method a number of ways: public String bar (String s) {
String t = “CS 101 ” + “ ” + s; return t;
} public String bar (String s) { return new String (“CS 101 ” + “ ” + s);
} public String bar (String s) { return “CS 101 ” + “ ” + s;
}
143
Returning a non-object from a method
In other words, returning a primitive type from a method public foo () {
// ...
return x + y;
}
This method evaluates x+y, then returns that value to the caller
144
145
146
147
148
What we’ve seen so far
An example of creating a class
Car
Up next: another example
Rational
Represents rational numbers
A rational number is any number that can be expressed as a fraction
Both the numerator and denominator must be integers!
Discussed in section 4.8 of the textbook
149
What properties should our Rational class have?
The numerator (top part of the fraction)
The denominator (bottom part of the fraction)
Not much else…
150
What do we want our Rational class to do?
Obviously, the ability to create new Rational objects
Setting the numerator and denominator
Getting the values of the numerator and denominator
Perform basic operations with rational numbers: + - * /
Ability to print to the screen
151
Our first take at our Rational class
Our first take
Rational
- numerator = 0 - denominator = 0 public class Rational { private int numerator; private int denominator;
//...
}
+ …
This does not represent a valid Rational number!
Why not?
Java initializes instance variables to zero
Both the numerator and denominator are thus set to zero
0/0 is not a valid number!
152
Our next take at our Rational class
Our next take public class Rational { private int numerator = 0 ; private int denominator = 1 ;
//...
}
Rational
- numerator = 0 - denominator = 1
We’ve defined the attributes of our class
+ …
Next up: the behaviors
153
The default constructor
Ready?
public Rational() {
}
Rational
- numerator = 0 - denominator = 1
+ Rational()
+ …
Yawn!
Note that we could have initialized the instance variables here instead
The default constructor is called that because, if you don’t specify ANY constructors, then Java includes one by default
Default constructors do not take parameters 154
The specific constructor
Called the specific constructor because it is one that the user specifies
They take one or more parameters public Rational (int num, int denom) { setNumerator (num); setDenominator (denom);
Rational
} - numerator = 0 - denominator = 1
Note that the specific constructor calls the mutator methods instead of setting the instance variables directly
We’ll see why later
+ Rational()
+ Rational (int num, int denom)
+ …
155
Accessor methods
Our two accessor methods: public int getNumerator () { return numerator;
} public int getDenominator () { return denominator;
}
Rational
- numerator = 0 - denominator = 1
+ Rational()
+ Rational (int num, int denom)
+ int getNumerator()
+ int getDemonimator()
+ …
156
Mutator methods
Our two mutator methods: public void setNumerator (int towhat) { numerator = towhat;
} public void setDenominator (int towhat) { denominator = towhat;
}
157
Rational addition
How to do Rational addition: a b
c d
ad
bc bd
Our add() method: public Rational add (Rational other) {
}
158
The this keyword this
Returns:
Rational
- numerator = 5 - denominator = 6
+ Rational ()
+ Rational (int n, int d)
+ Rational add (Rational other)
+ …
- numerator = 1 - denominator = 2
Rational
- numerator = 1 - denominator = 3
+ Rational ()
+ Rational (int n, int d)
+ Rational add (Rational other)
+ …
159
The this keyword
this is a reference to whatever object we are currently in
Will not work in static methods
We’ll see why later
Note that the main() method is a static method
While we’re at it, when defining a class, note that NONE of the methods so far were static
160
Rational addition
How to do Rational addition: a b
c d
ad
bc bd
Our add() method: public Rational add (Rational other) { int a = this.getNumerator(); int b = this.getDenominator(); int c = other.getNumerator(); int d = other.getDenominator(); return new Rational (a*d+b*c, b*d);
}
161
Rational addition
The following method is equivalent:
Our add() method: public Rational add (Rational other) { int a = getNumerator(); int b = getDenominator(); int c = other.getNumerator(); int d = other.getDenominator(); return new Rational (a*d+b*c, b*d);
}
162
Rational addition
The following method is equivalent, but not preferred:
Our add() method: public Rational add (Rational other) { int a = numerator; int b = denominator; int c = other.numerator; int d = other.nenominator; return new Rational (a*d+b*c, b*d);
}
163
Rational addition
The following method is equivalent, but not preferred:
Our add() method: public Rational add (Rational other) { int a = this.
numerator; int b = this.
denominator; int c = other.numerator; int d = other.nenominator; return new Rational (a*d+b*c, b*d);
}
164
Rational subtraction
How to do Rational subtraction: a b
c d
ad
bc bd
Our subtract() method: public Rational subtract (Rational other) { int a = this.getNumerator(); int b = this.getDenominator(); int c = other.getNumerator(); int d = other.getDenominator(); return new Rational ( a*d-b*c, b*d );
}
165
Rational multiplication
How to do Rational multiplication: a b c
* d
ac bd
Our multiply() method: public Rational multiply (Rational other) { int a = this.getNumerator(); int b = this.getDenominator(); int c = other.getNumerator(); int d = other.getDenominator(); return new Rational ( a*c, b*d );
}
166
Rational division
How to do Rational division: a b
c d
ad bc
Our divide() method: public Rational divide (Rational other) { int a = this.getNumerator(); int b = this.getDenominator(); int c = other.getNumerator(); int d = other.getDenominator(); return new Rational ( a*d, b*c );
}
167
Printing it to the screen
If we try printing a Rational object to the screen:
Rational r = new Rational (1,2);
System.out.println (r);
We get the following:
Rational@82ba41
Ideally, we’d like something more informative printed to the screen
The question is: how does Java know how to print a custom class to the screen?
168
The toString() method
When an object is put into a print statement:
Rational r = new Rational (1,2);
System.out.println (r);
Java will try to call the toString() method to covert the object to a String
If the toString() method is not found, a default one is included
Hence the Rational@82ba41 from the previous slide
So let’s include our own toString() method
169
The toString() method
Our toString() method is defined as follows: public String toString () { return getNumerator() + "/" + getDenominator();
}
Note that the prototype must ALWAYS be defined as shown
The prototype is the ‘ public String toString() ’
170
Printing it to the screen
Now, when we try printing a Rational object to the screen:
Rational r = new Rational (1,2);
System.out.println (r);
We get the following:
1/2
Which is what we wanted!
Note that the following two lines are (mostly) equivalent:
System.out.println (r);
System.out.println (r.toString());
171
Our full Rational class
Rational
- numerator = 0 - denominator = 1
+ Rational()
+ Rational (int num, int denom)
+ int getNumerator()
+ int getDemonimator()
+ void setNumerator (int num)
+ void setDenominator (int denom)
+ Rational add (Rational other)
+ Rational subtract (Rational other)
+ Rational multiply (Rational other)
+ Rational divide (Rational other)
+ String toString()
172
Our Rational class in use, part 1 of 4
This code is in a main() method of a RationalDemo class
First, we extract the values for our first Rational object:
Scanner stdin = new Scanner(System.in);
System.out.println();
// extract values for rationals r and s
Rational r = new Rational();
System.out.print("Enter numerator of a rational number: "); int a = stdin.nextInt();
System.out.print("Enter denominator of a rational number: "); int b = stdin.nextInt(); r.setNumerator(a); r.setDenominator(b);
173
Our Rational class in use, part 2 of 4
Next, we extract the values for our second Rational object:
Rational s = new Rational();
System.out.print("Enter numerator of a rational number: "); int c = stdin.nextInt();
System.out.print("Enter denominator of a rational number: “) ; int d = stdin.nextInt(); s.setNumerator(c); s.setDenominator(d);
Notice that I didn’t create another Scanner object!
Doing so would be bad
I used the same one
174
Our Rational class in use, part 3 of 4
Next, we do the arithmetic:
// operate on r and s
Rational sum = r.add(s);
Rational difference = r.subtract(s);
Rational product = r.multiply(s);
Rational quotient = r.divide(s);
175
Our Rational class in use, part 4 of 4
Lastly, we print the results
// display operation results
System.out.println("For r = " + r.toString() + " and s = "
System.out.println("
+ s.toString()); r + s = " + sum.toString());
System.out.println("
System.out.println("
System.out.println("
System.out.println(); r - s = " + difference.toString()); r * s = " + product.toString()); r / s = " + quotient.toString());
176
RationalDemo.java
177
Other things we might want to add to our
Rational class
The ability to reduce the fraction
So that 2/4 becomes 1/2
Not as easy as it sounds!
More complicated arithmetic
Such as exponents, etc.
Invert
Switches the numerator and denominator
Negate
Changes the rational number into its (additive) negation
We won’t see any of that here
178
a) b) c) d) e)
Very well! This stuff is so easy.
With a little review, I’ll be good.
Not very well at all.
I’m so lost. What’s a class again?
I’d rather not answer this question, thanks.
179