Visibilities and Static-ness - PowerPoint PPT Presentation

About This Presentation
Title:

Visibilities and Static-ness

Description:

Visibilities and Static-ness Aaron Bloomfield CS 101-E – PowerPoint PPT presentation

Number of Views:89
Avg rating:3.0/5.0
Slides: 56
Provided by: AaronBlo3
Category:

less

Transcript and Presenter's Notes

Title: Visibilities and Static-ness


1
Visibilities and Static-ness
  • Aaron Bloomfield
  • CS 101-E

2
Our 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
3
Using 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
4
Accessing 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)
5
Whats 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
6
Whats 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!
7
Whats 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

8
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

9
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()

10
What happens in memory
  • There are 4 Circle objects in memory
  • Taking up a total of 416 64 bytes of memory

11
Consider 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!
12
What 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
13
The 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)
14
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)

Note you can refer to static fields
by object.field
15
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
  • Thus, you can refer to a static field by using
    the class name
  • Circle.Pi

16
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)

17
Even 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

18
A bit of humor
19
Back 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
20
Adding 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
21
Using 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
22
Adding another method
  • double oneOverRadius()
  • return 1.0/radius
  • I couldnt think of a good reason to divide
    something by the radius

23
What 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!

24
One 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

25
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())

26
Where 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
27
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 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

28
One 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

29
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

30
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

31
The 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

32
Our 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

33
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())
  • 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
34
Wait! 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
35
This 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

36
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 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

37
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
    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)

38
Constructors
  • 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
39
Constructors, 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

40
Constructors, 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!
41
Overriding 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
42
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?
43
Constructors, 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)
44
Constructors, 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

45
A bit of humor
46
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

47
The 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

48
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 dont care about the state of the Math class
  • They only perform the computation

49
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())

50
static 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())

51
What 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?

52
The main static lesson
  • A static method cannot access or modify the state
    of the object

53
static 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

54
Back 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

55
A bit of humor
Write a Comment
User Comments (0)
About PowerShow.com