Title: Visibilities and Static-ness
1Visibilities and Static-ness
- Aaron Bloomfield
- CS 101-E
2Our Circle class
- We are going to write a Circle class
- Somebody else is going to use it
- public class Circle
- double radius
- double Pi 3.1415926536
Note the radius field is not initialized
Remember that a variable of a class is called a
field
Note the fields are not static
Were ignoring the public for now
3Using our Circle class
Note its a different class
public class CircleTest public static void
main (String args) int x 5 Circle c
new Circle()
public class CircleTest public static void
main (String args) int x 5 Circle c
new Circle()
Remember that a variable of a method is just
called a variable
Circle is the class
c is the object
Note the new
4Accessing our Circle object
- Any field or method in an object can be accessed
by using a period - Example System.in
- Example c.radius 10
- Example c.Pi 4
This is bad Pi should have been declared
final (this will be done later)
5Whats 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
6Whats 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!
7Whats going on?
- A (method) variable needs to be initialized
before it is used - A field (class variable) is automatically
initialized by Java - All doubles are initialized to 0.0, ints to 0,
etc. - This is a bit counter-intuitive
8What 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
9Consider 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()
-
10What happens in memory
- There are 4 Circle objects in memory
- Taking up a total of 416 64 bytes of memory
11Consider the following code
- public class CircleTest
- public static void main (String args)
Circle c1 new Circle() - //...
- Circle c1000000 new Circle()
-
This program creates 1 million Circle objects!
12What happens in memory
- There are 1 million Circle objects in memory
- Taking up a total of 1,000,00016 16 Mb of
memory
Note that the final Pi field is repeated 1
million times
13The use of static for fields
- If a field is static, then there is only ONE of
that field for ALL the objects
Total memory usage 8 Mb 8 bytes
(1,000,00011,000,001 doubles)
Total memory usage 16 bytes (112 doubles)
Total memory usage 40 bytes (415 doubles)
14More 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)
Note you can refer to static fields
by object.field
15Even 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
- Thus, you can refer to a static field by using
the class name - Circle.Pi
16Even 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)
17Even even even more on static fields
- Weve seen static fields used with their class
names - System.in (type InputStream)
- System.out (type OutputStream)
- Math.PI (type double)
- Integer.MAX_VALUE (type int)
- Non-static fields are generally not called
dynamic fields - Just non-static, or no qualifier at all
18A bit of humor
19Back to our Circle class
- public class Circle
- double radius
- final static double Pi 3.1415926536
-
- But it doesnt do much!
Note that Pi is now final and static
20Adding a method
- public class Circle
- double radius
- final static double Pi 3.1415926536
- double computeArea ()
- return Piradiusradius
-
Note that a (non-static) method can use all the
fields
21Using that method
- public class CircleTest
- public static void main (String args)
- Circle c new Circle()
- c.radius 2.0
- System.out.println (c.computeArea())
-
Prints 12.566370614356
22Adding another method
- double oneOverRadius()
- return 1.0/radius
-
- I couldnt think of a good reason to divide
something by the radius
23What happens now?
- Code in class CircleTests main() method
- Circle c new Circle() // c.radius 0.0
- System.out.println (c.oneOverRadius())
- Java wont crash, but many other programming
languages (C and C, especially) will - Java prints Infinity
- Not what we wanted, though!
24One way to fix this
Note that the radius field is now initialized to
1.0
- public class Circle
- double radius 1.0
- final static double Pi 3.1415926536
- double computeArea ()
- return Piradiusradius
-
- double oneOverRadius()
- return 1.0/radius
-
25Back 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())
26Where the crash occurs
- public class CircleTest
- public static void main
- (String args)
- Circle c new Circle()
- // c.radius 1.0
- c.radius 0.0
- System.out.println
- (c.oneOverRadius())
-
public class Circle double radius
1.0 final static double Pi 3.1415926536 dou
ble computeArea () return
Piradiusradius double oneOverRadius()
return 1.0/radius
Here is the badly written code
Here is where the crash occurs
27Motivation for private fields
- Problem We do not want people using our Circle
class to be able to modify the fields on their
own - Solution Dont allow other code to modify the
radius field - Give it private visibility
- private means that only code within the class can
modify the field
28One way to fix this
Note that the radius field is now private
- public class Circle
- private double radius 1.0
- final static double Pi 3.1415926536
- double computeArea ()
- return Piradiusradius
-
- double oneOverRadius()
- return 1.0/radius
-
29Back 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
30Back 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
31The problem now
- But now you cant have a Circle with a radius
other than 1.0! - Solution Use a get/set methods in Circle
- void setRadius (double r)
- radius r
-
-
- double getRadius ()
- return radius
-
32Our Circle class so far
- public class Circle
- double radius 1.0
- final static double Pi 3.1415926536
- double computeArea ()
- return Piradiusradius
-
- double oneOverRadius()
- return 1.0/radius
-
- void setRadius (double r)
- radius r
-
-
- double getRadius ()
- return radius
-
33Using 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())
-
- public class Circle
- private double radius 1.0
- final static double Pi 3.1415926536
- double computeArea ()
- return Piradiusradius
-
- double oneOverRadius()
- return 1.0/radius
-
- void setRadius (double r)
- radius r
-
-
- double getRadius ()
- return radius
-
Here a method is invoked
Here the change to radius occurs
34Wait! Another problem!
- public class CircleTest
- public static void main (String args)
- Circle c new Circle()
- c.setRadius (0.0)
- System.out.println (c.oneOverRadius())
-
Here is the problem now
35This problem is easily fixed
- Change the setRadius method to the following
- void setRadius (double r)
- if ( r gt 0.0 )
- radius r
-
- Now there is no way for code outside the Circle
class to change the radius to zero
36Visibilities 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 wont get to that this semester
- package Almost the same as public
- This is the default
- Note that it cant be specified like the others
37A 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
its defined) and private outside the method - You can also specify visibilities for methods and
classes - More on that later in the course (or next course)
38Constructors
- When you create a object, you often have to do
some initialization - You have to construct the object
- public class Circle
- String name
- public Circle()
- Scanner scanner new Scanner(System.in)
- System.out.println (Enter the Circles
name) - name scanner.next()
-
- //...
Note the different method declaration
39Constructors, take 2
- Now when a Circle is created
- Circle c new Circle()
- Java will ask for the Circles name, and put it
in the name field - Okay, so this isnt the greatest example
40Constructors, take 3
- More useful constructors for our Circle class
- public Circle()
- radius 1.0
-
- public Circle (double r)
- radius r
-
Note there is no return type for constructors
Note that the constructor name is the EXACT
same as the class name
Note that there are two methods with the same
name!
41Overriding methods (and constructors)
- Consider the following code
- Circle c1 new Circle ()
- Circle c2 new Circle (2.0)
- Java knows which constructor to call by the list
of parameters - This is called overloading
Creates a Circle of radius 1.0
Creates a Circle of radius 2.0
42Overriding 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?
43Constructors, take 4
- 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 1 by zero (again)
44Constructors, take 5
- Our revised constructors
- public Circle()
- radius 1.0
-
- public Circle (double r)
- if ( r lt 0.0 )
- radius 1.0
- else
- radius r
45A bit of humor
46Back 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
-
47The getPi() method
- It doesnt read or modify the state of any
object - In this example, it doesnt read/write the radius
- In fact, that particular method doesnt care
anything about the objects declared - Its only accessing a static field
48Make 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 dont care about the state of the Math class
- They only perform the computation
49Invoking 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())
50static methods and non-static 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())
-
51What happening in memory
- There are 1 million Circle objects in memory
- There are no Circle objects in memory
- There are 4 Circle objects in memory
- Which radius field does Circle.getRadius() want?
52The main static lesson
- A static method cannot access or modify the state
of the object
53static and non-static 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
54Back to our main() method
- public static void main (String args)
The method does not return a value
Any code anywhere can call this method
- Its a static method
- Cant access non-static fields
- Can be called only by the class name
55A bit of humor