What We Will Cover
Continuations
Homework Questions?
About null
- The keyword
null is a special value that can be assigned to any class type
- It means that no objects has been assigned yet
Quick Quiz
The term overloaded refers to:
- An error where more than one method matches a method call.
- Two or more methods in the same program that have the same name.
- Method calls where there are too many actual parameters.
- Two or more methods in different programs that have the same name.
^ top
7.1: Variables and Object References
Objectives
At the end of the lesson the student will be able to:
- Describe what is meant by local shadowing
- Discuss how reference variables differ from primitive variables
- Explain the steps a program follows to instantiate an object
- Describe what happens to objects that are no longer needed
|
^ top
7.1.1: Instance Variables and Local Shadowing
- Recall that variables declared in a method can only be used within that method
- When the method finishes executing, local variables disappear
- Thus, variables declared in one method cannot be used in another
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
public class LocalVariables {
public void initializeNumber() {
int number = 9;
}
public void showNumber() {
// Following produces compiler error
//System.out.println("Number: " + number);
}
public static void main(String[] args) {
LocalVariables obj = new LocalVariables();
obj.initializeNumber();
obj.showNumber();
}
}
|
- On the other hand, variables declared outside methods can be used in any method
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
public class InstanceVariables {
private int number;
public void initializeNumber() {
number = 9;
}
public void showNumber() {
System.out.println("Number: " + number);
}
public static void main(String[] args) {
InstanceVariables obj = new InstanceVariables();
obj.initializeNumber();
obj.showNumber();
}
}
|
- What if a local variable has the same name as a class variable?
- Known as local shadowing
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
public class LocalShadowing {
private int number;
public void initializeNumber() {
int number = 9;
}
public void showNumber() {
System.out.println("Number: " + number);
}
public static void main(String[] args) {
LocalShadowing obj = new LocalShadowing();
obj.initializeNumber();
obj.showNumber();
}
}
|
- Local variables with same name as a class variable hide the class variable
- Any use of the variable's name will refer to the method variable
- This is the source of many an elusive bug
- Thus, you should not use the same name for a local variable and a class variable
CheckStyle to the Rescue!
- One nice feature of CheckStyle is that it catches shadowed variables
- Be sure to run CheckStyle and pay attention to the error messages
^ top
7.1.2: Primitive Types vs. Reference Types
- We can divide data types in Java into two categories: primitive and reference types
Primitive Types
- Recall that main memory is organized as a long list of numbered locations
- When we declare a primitive variable, we set aside one or more bytes of memory for that variable
- When we store data in a primitive variable, we assign values directly to a memory location
- For instance, when we declare:
int num1, num2;
We set aside space for two int variables somewhere in memory
When we assign values to the variables
num1 = 12;
num2 = 34;
The values are stored directly in a the memory locations
Reference Types
- All non-primitive variables are called reference variables
- Reference variables store the location of objects in memory
- Rather than the actual object in memory
- Known as indirect addressing
- For instance, when we declare:
Product prod;
We set aside space for a reference variable that can refer to an object
When we create an object we create another location in memory to store the data of the object
prod = new Product();
When we assign an object to a reference variable, we store the location of the object in main memory
This is known as indirect addressing
References and Pointers
- Some people say that Java does not have pointers
- This is really just a matter of semantics
- Why else do we get a
NullPointerException?
- What these people mean is that Java does not have pointer arithmetic
- A source of many bugs in C++
- In addition, Java automatically dereferences pointers as needed
^ top
7.1.3: Creating Objects
- What actually happens when we instantiate an object in memory?
- There are two main steps:
- Allocate memory space for all the variables of the object
- Call a constructor of the object to initialize the variables
Allocating Memory
- The
new operator causes your program to set aside space in memory for an object
- The amount of memory set is aside is determined by the variables declared in the class
- For example, if we have a
Product class defined with two variables:
public class Product {
private String name;
private double price;
// other parts of the class
Space in memory gets allocated for the two variables
Note that variables have default values when the object is created
Calling a Constructor
- After memory is allocated, the specified constructor gets called
- For example, if we have a
Product class with the following constructor
public Product(String newName, double newPrice) {
setName(newName);
setPrice(newPrice);
}
And we coded something like the following to instantiate the object
Product prod = new Product("milk", 3.95);
After the statement finishes executing, our memory diagram looks like:
^ top
7.1.4: Cleaning Up Unused Objects
- What happens to an object that is no longer needed?
- Some object-oriented languages require the programmer to manually deallocate memory
- This is a common source of bugs known as memory leaks
- If the programmer forgets to deallocate memory often enough, the program no longer has enough memory to run within
- However, Java uses a process known as automatic garbage collection to return objects to memory
- An object is marked for garbage collection if no variable in the program references the object
- Java keeps track of which variables refer to which object and performs garbage collection automatically
- You can manually choose to run the garbage collector as well
System.gc();
^ top
7.1.5: Summary
- Local variables with same name as a class variable hide the class variable
- You should not use the same name for a local variable and a class variable
- All non-primitive data types are known as reference types
- Programs use variables of reference types to store locations of objects in the computer's memory
- When an object is created, it gets memory space for all its instance variables
- When an object is no longer referred to by any reference variable in a program, the unused memory is automatically reclaimed ("garbage collected")
Check Yourself
- What is meant by the term "local shadowing"?
- How do reference variables differ from primitive variables?
- What happens when the
new operator is called?
- What happens to objects that are no longer needed in a program?
^ top
Exercise 7.1
In this exercise we explore the problem of local shadowing.
Specifications
- Start a text file named exercise7.txt.
- Prepare the exercise header as described in the HowTo on submitting exercises
- Label this exercise: Exercise 7.1
- Save the following code as
MyRectangle.java.
- The code has errors that prevent its correct operation. Correct the errors and save your corrected code along with your other exercises for this lesson.
- In addition, record the answers to the following questions in exercise7.txt.
Q1: What error messages are displayed by the compiler, if any, before you correct the errors?
Q2: What error message is displayed by CheckStyle before you correct the errors?
Q3: Which method contains the errors?
Q4: What is the name of these type of errors?
/**
* MyRectangle.java
* Represents a rectangle.
*
* @author Ed Parrish
* @version 1.0 11/09/04
*/
public class MyRectangle {
public static final double LENGTH = 3.0;
public static final double WIDTH = 5.0;
private double length, width;
/**
* Initializes the variables of a MyRectangle object.
*
* @param length The length of the rectangle.
* @param width The width of the rectangle.
*/
public MyRectangle(double length, double width) {
length = length;
width = width;
}
/**
* Returns a String representation of this object.
*
* @return A String representation of this object.
*/
public String toString() {
return "length: " + length + ", width: " + width;
}
/**
* The main method used to test the class.
*
* @param args Not used.
*/
public static void main(String[] args) {
MyRectangle rec = new MyRectangle(LENGTH, WIDTH);
System.out.println(rec.toString());
}
}
^ top
7.2: Using Objects in Programs
Objectives
At the end of the lesson the student will be able to:
- Code classes that use other objects
- Describe how to pass objects to methods
- Code methods to return objects
- Discuss the meaning of the
this keyword
|
^ top
7.2.1: Objects as Instance Variables
- In OOP, only the simplest programs use a single object
- More commonly, several objects work together in a program
- Each object performs one specialized task
- One of the tasks may be to control the operation of the entire program
- In this section we look at how use multiple objects in a program
Updated Product2 Class
- Before we start, lets recall our
Product class
- Below we have an updated class with an added constructor
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
|
public class Product2 {
private String name;
private double price;
public Product2() {
name = "Unknown";
price = 0.0;
}
public Product2(String newName, double newPrice) {
setName(newName);
setPrice(newPrice);
}
public void setName(String newName) {
if (newName == null || newName.length() == 0) {
name = "Unknown";
} else {
name = newName;
}
}
public String getName() {
return name;
}
public void setPrice(double newPrice) {
if (newPrice > 0.0) {
price = newPrice;
} else {
price = 0.0;
}
}
public double getPrice() {
return price;
}
public String toString() {
return "The product is: " + name
+ " and the price is: " + price;
}
}
|
^ top
7.2.2: Example Application
- The following example uses the
Product2 class
- What do you notice that is new about this code?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
|
public class ProductOrder {
private Product2 prod;
private int quantity;
public ProductOrder() { }
public ProductOrder(String name, double price,
int prodQuantity) {
prod = new Product2(name, price);
quantity = prodQuantity;
}
public void setProduct(Product2 newProd) {
prod = newProd;
}
public Product2 getProduct() {
return prod;
}
public void setQuantity(int newQuantity) {
if (newQuantity > 0) {
quantity = newQuantity;
} else {
quantity = 0;
}
}
public int getQuantity() {
return quantity;
}
public double getTotal() {
return quantity * prod.getPrice();
}
public String toString() {
return "Name: " + prod.getName()
+ "\nPrice: " + prod.getPrice()
+ "\nQuantity: " + quantity
+ "\nTotal Amount: " + getTotal() + "\n";
}
}
|
- Note how an object of the
Product class is stored as part of the ProductOrder class
- Also note how the
Product class is initialized
- When using another class, you do not need to know the inner workings of the other class
- You only need to know the publicly available methods
- Note that the
getTotal() method does not simply return a value
- Instead, it calculates the total by using data stored in the class
- Uses the
getPrice() method to extract data from the Product class
Another Example Class
ProductOrderApp is another driver application
- Has a main function that starts an application
- What do you notice that is new about this code?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
|
import java.util.Scanner;
public class ProductOrderApp{
private Scanner input = new Scanner(System.in);
public static void main(String[] args) {
ProductOrderApp app = new ProductOrderApp();
app.runApp();
}
public void runApp() {
String answer = "y";
while (answer.charAt(0) == 'y') {
ProductOrder po = getPO();
System.out.print("\nYou entered:\n"
+ po.toString());
System.out.print("\nEnter another PO? ");
answer = input.next();
input.nextLine();
}
}
public ProductOrder getPO() {
System.out.print("\nEnter product name: ");
String name = input.nextLine();
System.out.print("Enter price for a "
+ name + ": ");
double price = input.nextDouble();
System.out.print("Enter number of "
+ name + " requested: ");
int qty = input.nextInt();
return new ProductOrder(name, price, qty);
}
}
|
- Note that we have two applications sharing the same class
Product
- Though one is used indirectly
- This is an example of code reuse
^ top
7.2.3: Classes as Method Parameters
- Objects can be passed to methods as arguments
- We saw this in the
ProductOrder class:
public void setProduct(Product2 newProd) {
prod = newProd;
}
We can test this by changing ProductOrderApp
Product2 prod = new Product2(name, price);
ProductOrder po = new ProductOrder();
po.setProduct(prod);
po.setQuantity(qty);
return po;
^ top
7.2.4: Returning Objects from Methods
- Class types can be returned from functions
- We saw this in the previous code:
public Product2 getProduct() {
return prod;
}
^ top
7.2.5: Using the this Keyword
- Look again at the code for one of the constructors of
Product2
public Product2(String newName, double newPrice) {
setName(newName);
setPrice(newPrice);
}
Note how we call the setName() and setPrice() methods
Compare this to how we call these methods from outside the class
Product2 milk = new Product2();
milk.setName("Milk");
milk.setPrice(3.95);
Whenever we call a method of an object, we must use the object name, a dot and the method name
However, inside the class definition, we did not use an object name
The reason for the difference is that inside the class definition, the name of the object is understood
Name this Object
- Even though it is not often used, there is a name for the object available to the programmer
- The name of the object inside the class definition goes by the somewhat unusual name:
this
- You can use the
this keyword in the class definition if you like
- For instance, we could recode our constructor slightly to:
public Product2(String newName, double newPrice) {
this.setName(newName);
this.setPrice(newPrice);
}
Since this is understood, its use is optional
Programmers seldom use the this keyword but there are some situations where it is useful
We will look at those situations as they arise
^ top
7.2.6: Summary
- Object-oriented programs use one or more objects to perform their tasks
- Objects can be part of the data for other classes
public class ProductOrder {
private Product2 prod;
// rest of class definition
Different applications can use the same classes to create objects
A class may use another class as a type for a member variable
Classes can be method parameters
For example:
public void setProduct(Product2 newProd) {
prod = newProd;
}
Objects can be returned from methods as well
public Product2 getProduct() {
return prod;
}
Inside the class definition, you can refer to the object name using the keyword: this
- Its use is optional and thus rarely used
Check Yourself
- How do you code an object as an instance variable of another class?
- How do you code a method with an object parameter?
- How do you code a method to return an object?
- What is the name of an object inside a class definition?
^ top
Exercise 7.2
In this exercise, we use a class as a variable type of another class.
Specifications
- Save the following starter code files as
Book.java and BookOrder.java.
- In the
BookOrder class, add the following methods:
- A constructor that takes a title, price and quantity and saves the data in the
aBook and quantity variables.
- A
setBook() method with a Book object parameter that assigns the aBook variable to the method parameter.
- A
getBook() method that simply returns the aBook variable.
- A
main() method that instantiates one or more BookOrder objects and calls each of the new methods you have written.
- Submit your updated
BookOrder.java file along with your other exercises for this lesson.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
|
public class Book {
private String title;
private double price;
public Book() {
title = "Unknown";
price = 0.0;
}
public Book(String newTitle, double newPrice) {
setTitle(newTitle);
setPrice(newPrice);
}
public void setTitle(String newTitle) {
if (newTitle == null || newTitle.length() == 0) {
title = "Unknown";
} else {
title = newTitle;
}
}
public String getTitle() {
return title;
}
public void setPrice(double newPrice) {
if (newPrice > 0.0) {
price = newPrice;
} else {
price = 0.0;
}
}
public double getPrice() {
return price;
}
}
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
|
public class BookOrder {
private Book aBook;
private int quantity;
public BookOrder() { }
public void setQuantity(int newQuantity) {
if (newQuantity > 0) {
quantity = newQuantity;
} else {
quantity = 0;
}
}
public int getQuantity() {
return quantity;
}
public double getTotal() {
return quantity * aBook.getPrice();
}
public String toString() {
return "Title: " + aBook.getTitle()
+ "\nPrice: " + aBook.getPrice()
+ "\nQuantity: " + quantity
+ "\nTotal Amount: " + getTotal() + "\n";
}
public static void main(String[] args) {
}
}
|
^ top
7.3: Static Fields and Methods
Objectives
At the end of the lesson the student will be able to:
- Code static fields and methods in a class
- Call static fields and methods from other classes
- Describe when to use static fields and methods
|
^ top
7.3.1: About Static Fields and Methods
- Static variables and methods are not part of an object, but are common to the entire class
- Sometimes called class fields and class methods
- Calling the
new operator on a class does not create space for static variables
- Instead, a static variable has only one memory location
- This memory location can be accessed by static methods and by any instance of the class
- Thus, all objects of a class share a static variable
- A static variable is coded like instance variables except that the word static is added
- For example:
private static int numObjs = 0;
public static final double PI = 3.14159;
Note that final static variables are one of the few times variables should be declared public
A static method can either access static variables or its parameters
However, a static method cannot access instance variables unless it has access to an object reference
A static method is coded like an instance method but with the word static added
public static int getNumObjs() {
return numObjs;
}
Static methods are often used as general purpose methods, such as the Math methods
You can call static methods using the name of the class rather than an object reference
For example, to call the sqrt() method of the Math class:
Math.sqrt(4); // returns 2
^ top
7.3.2: Example Using static Fields and Methods
- Classic example: keep track of how many objects of a class are created
- First add an object count variable to the class
private static int numObjs = 0;
Need to increment the variable whenever a new object is instantiated
Can add an increment statement to the object constructors
public Product3() {
name = "Unknown";
price = 0.0;
numObjs++;
}
public Product3(String newName, double newPrice) {
setName(newName);
setPrice(newPrice);
numObjs++;
}
Also need a method to retrieve the count
public static int getNumObjs() {
return numObjs;
}
Note that a static method does not have an object reference
Thus cannot refer to a (non-static) instance variable of the class
Likewise, a static method cannot call a non-static method of the class
Putting everything together we get the Product2 class
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
|
public class Product3 {
// Instance variables
private String name;
private double price;
private static int numObjs = 0;
// Constructors
public Product3() {
name = "Unknown";
price = 0.0;
numObjs++;
}
public Product3(String newName, double newPrice) {
setName(newName);
setPrice(newPrice);
numObjs++;
}
public void setName(String newName) {
if (newName == null || newName.length() == 0) {
name = "Unknown";
} else {
name = newName;
}
}
public String getName() {
return name;
}
public void setPrice(double newPrice) {
if (newPrice > 0.0) {
price = newPrice;
} else {
price = 0.0;
}
}
public double getPrice() {
return price;
}
public static int getNumObjs() {
return numObjs;
}
public String toString() {
return "The product is: " + name
+ " and the price is: " + price;
}
// For testing
public static void main(String[] args) {
Product3 milk = new Product3("Milk", 3.95);
Product3 bread = new Product3("Bread", 1.98);
System.out.println(milk);
System.out.println(bread);
System.out.println("Number of products="
+ getNumObjs());
}
}
|
^ top
7.3.3: When to Use Static Fields and Methods
- When you need multiple objects of a class, use regular fields and methods
- If you only need a general purpose utility method, use static methods
- For example, the Math methods
- When you need constants shared by many classes, use
final static fields
- For example:
Math.PI (approximately 3.14159)
Math.E (base of natural logarithms, approximately 2.72)
Further Information
^ top
7.3.4: Static Imports
- A static import is a Java feature that simplifies references to
static constants and methods of a class
- For example, you could import the static fields and methods of the
Math class as shown in the following example:
1
2
3
4
5
6
7
8
9
|
import static java.lang.Math.*;
public class MathStuff {
public static void main(String[] args) {
System.out.println("E: " + E);
System.out.println("PI: " + PI);
System.out.println("pow(2, 3): " + pow(2, 3));
}
}
|
Taming println()
- One of the annoying constructs in Java is the amount of typing to print something to the console
System.out.println("hello");
You can shorten the amount of typing somewhat by using a static import statement:
import static java.lang.System.*;
or
import static java.lang.System.out;
Now you can print to the console using:
out.println("hello");
^ top
7.3.5: Summary
- Static variables and methods are not part of an object, but are common to the entire class
- Calling the
new operator on a class does not create space for static variables
- Instead, a static variable has only one memory location
- This memory location can be accessed by static methods and by any instance of the class
- Thus, all objects of a class share a static variable
- A static variable is coded like instance variables except that the word static is added
private static int numObjs = 0;
public static final double PI = 3.14159;
A static method can either access static variables or its parameters
However, a static method cannot access instance variables unless it has access to an object reference
A static method is coded like an instance method but with the word static added
public static int getNumObjs() {
return numObjs;
}
You can call static methods using the name of the class rather than an object reference
Math.sqrt(4); // returns 2
When you need multiple objects of a class, use regular fields and methods
If you only need a general purpose utility method, use static methods
When you need constants shared by many classes, use final static variables
Java lets you import static variables and methods into your code using a static import like:
import static java.lang.System.out;
We used this feature to shorten the code needed to use println()
out.println("hello");
Check Yourself
- How do you code a static variable?
- If you create 10 objects from a class, how many memory locations does you program have for a
static variable?
- How do you code a static method?
- How do you call a static method?
- Can a static method access an instance variable?
- When should you code static methods rather than instance methods?
- What is the purpose of a static import?
- How do you code a static import?
^ top
Exercise 7.3
In this exercise we add a static variable and method to a class.
Specifications
- Save the following starter code file as
Book.java.
- Add a
static variable to the Book class for counting the number of Book objects that get created.
- Increment the
static variable in the constructors of the class.
- Add a method that returns the number of
Book objects that get created.
- Add a
main() method that creates two or more Book objects and then displays the number.
- Submit your updated
Book.java file along with your other exercises for this lesson.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
|
public class Book {
private String title;
private double price;
public Book() {
title = "Unknown";
price = 0.0;
}
public Book(String newTitle, double newPrice) {
setTitle(newTitle);
setPrice(newPrice);
}
public void setTitle(String newTitle) {
if (newTitle == null || newTitle.length() == 0) {
title = "Unknown";
} else {
title = newTitle;
}
}
public String getTitle() {
return title;
}
public void setPrice(double newPrice) {
if (newPrice > 0.0) {
price = newPrice;
} else {
price = 0.0;
}
}
public double getPrice() {
return price;
}
}
|
^ top
7.4: Midterm Preparation
Objectives
At the end of the lesson the student will be able to:
- Discuss how to prepare for the first midterm exam
- Describe how to take the first midterm exam
|
^ top
7.4.1: About the Exam
- You must attend the exam or you will receive a score of zero (0)
- Except by prior arrangement with the instructor
- I am using WebCT to administer the test
- The exam is closed books and closed notes
- However, you may have one 3" x 5" card of notes for the exam
- You must turn in your 3" x 5" card after the exam
- You may use your computer, but only to take the exam in WebCT
- You may have a sheet of blank scratch paper
- You may NOT use the computer to compile or run programs
- You may NOT use the computer to view documents on the Internet
- You may NOT use a calculator or other electronic device
- You may NOT communicate with anyone but the instructor during the exam
^ top
7.4.2: Recommended Preparation
- Work through the Practice Midterm Exam questions in WebCT
- Working the problems in groups is encouraged
- Get explanations for anything you do not understand
- Review the instructor's notes and make sure you can answer the Check Yourself questions, making notes about anything that you do not know
- Review your notes and prepare your 3" x 5" card
- Review your homework assignments and solutions
- Review your CodeLab exercises
- You should be prepared to write short programs that solve problems using:
- Mathematical expressions
- Conditional statements
- Main loops
- Counting loops
- Method definitions
- Class definitions
- A few more tips:
- I avoid using true/false questions
- I try to use questions containing actual code
- More quiz tips: Tips for Students Taking Multiple Choice Tests
^ top
7.4.3: Exam Taking Tips
- Save after every answer -- you can always choose another answer
- If you get stuck on a question, make your best guess and return later
- If you are equally uncertain between two choices, go with first impression
- You do not need to comment code for tests and exams
- Unless specifically instructed to in the exam question
- Use the full time available
- More quiz tips: Basic Rules For Taking a Multiple-Choice Test
^ top
7.4.4: Questions and Answers
^ top
Wrap Up
^ top
Home
| WebCT
| Announcements
| Schedule
| Expectations
| Course info
Help
| FAQ's
| HowTo's
| Links
Last Updated: October 27 2005 @15:53:27
|