Welcome to Lesson 8!
Learning Objectives for Today's Lesson
By the end of today's lesson, you should know...
- What is a constructor?
- How do you use method overloading with constructors?
- What is a default constructor?
- The differences between primitive and reference types
- How to use objects as method parameters and return types
- What is the difference between heap and stack memory?
- Where are objects stored?
- Where are reference variables and primitives stored?
1. Constructors and Initialization
Introducing Constructors
Defining a Constructor
public Phone() {
brand = "Unknown brand";
model = "Unknown model";
price = 0.0;
}
- Constructors must use the same name and capitalization as the class name
- Constructors can have zero or more parameters, just like other methods
- Constructors also have no return type (not even void!)
Example of Phone Class with Constructor
/**
* Phone.java example
* @author parrishj
*
*/
public class Phone {
private String brand;
private String model;
private double price;
/**Constructor(s)*/
/**
* Creates a new Phone object
* with default values
*/
public Phone() {
brand = "Unknown brand";
model = "Unknown model";
price = 0.0;
}
/**Accessors*/
/**
* Returns the brand of phone
* e.g. iPhone or Samsung
* @return the brand
*/
public String getBrand() {
return brand;
}
/**
* Returns the phone's model
* e.g. 7 or Galaxy S5
* @return the model
*/
public String getModel() {
return model;
}
/**
* Returns the phone's current
* market price
* @return the price
*/
public double getPrice() {
return price;
}
/**Mutators*/
/**
* Assigns a brand to the phone
* e.g. iPhone or Samsung
* @param newBrand the brand of phone
*/
public void setBrand(String newBrand) {
brand = newBrand;
}
/**
* Assigns a model to the phone
* e.g. 7 or Galaxy S5
* @param newModel the phone's model
*/
public void setModel(String newModel) {
model = newModel;
}
/**
* Assigns the phone the current
* market price for that brand
* and model
* @param newPrice the market price
*/
public void setPrice(double newPrice) {
price = newPrice;
}
/**Additional Methods*/
/**
* Displays a message alerting the user
* that the phone is now making a call
*/
public void makeCall() {
System.out.println(brand + " is now making a call.");
}
/**
* Displays a message alerting the user
* that the phone is now making a call
* to a specified person
* @param name the person who is being called
*/
public void makeCall(String name) {
System.out.println(brand + " is now calling " + name);
}
/**
* Returns a String of all the important
* information about the phone, including
* brand, model and price
* @return the important phone information
*/
@Override public String toString() {
return "Brand: " + brand
+ "\nModel: " + model
+ "\nPrice: " + price;
}
}
public class PhoneTest {
public static void main(String[] args) {
Phone iphone = new Phone(); //calls our constructor
System.out.println(iphone); //calls toString()
}
}
Multiple Constructors
- We can write a class with more than one constructor
- In other words, we can overload the constructor by defining multiple versions of it in a single class
- All constructors have the same name as the class, but have different parameter lists
- The technique of defining multiple constructors is known as constructor overloading
- Having multiple constructors allows us to create an object in different ways
- By allowing different ways of creating an object, we make our classes more flexible and easier to reuse
- A good constructor will assign values to each member variable of the class.
- Below are examples of well-written constructors:
Example: Constructor with no Parameters
- If you do not want to accept arguments for instance variables, write a constructor with no parameters:
- Note that constructors with no parameters are sometimes called default constructors
- A default constructor sets instance variables to default values
public Phone() {
brand = "Unknown brand";
model = "Unknown model";
price = 0.0;
}
Example: Constructor with one Parameter
public Phone(String theBrand, String theModel) {
brand = theBrand;
model = theModel;
price = 0.0;
}
Example: Constructor with two Parameters
Implicit Default Constructors
- If the programmer does not define a constructor, then the compiler supplies an empty one like the following:
public Phone() {}
- However, if the programmer defines any constructor, the compiler does not provide one
- Best practice is to always define your own no-parameter constructor
Example Phone Class with Overloaded Constructors
/**
* Phone.java example
* @author parrishj
*
*/
public class Phone {
public String brand;
public String model;
public double price;
/**Constructor(s)*/
/**
* Creates a new Phone object
* with default values
*/
public Phone() {
brand = "Unknown brand";
model = "Unknown model";
price = 0.0;
}
/**
* Creates a new Phone object
* with default values, except
* for the brand
* @param theBrand the brand of
* the phone
* e.g. iPhone or Samsung
*/
public Phone(String theBrand) {
brand = theBrand;
model = "Unknown model";
price = 0.0;
}
/**
* Creates a new Phone object
* @param theBrand the brand of
* the phone e.g. iPhone or Samsung
* @param theModel the phone's
* model. e.g. 7 or Galaxy S7
* @param price the phone's price
* in dollars
*/
public Phone(String theBrand, String theModel, double thePrice) {
brand = theBrand;
model = theModel;
price = thePrice;
}
/**Accessors*/
/**
* Returns the brand of phone
* e.g. iPhone or Samsung
* @return the brand
*/
public String getBrand() {
return brand;
}
/**
* Returns the phone's model
* e.g. 7 or Galaxy
* @return the model
*/
public String getModel() {
return model;
}
/**
* Returns the phone's current
* market price
* @return the price
*/
public double getPrice() {
return price;
}
/**Mutators*/
/**
* Assigns a brand to the phone
* e.g. iPhone or Samsung
* @param newBrand the brand of phone
*/
public void setBrand(String newBrand) {
brand = newBrand;
}
/**
* Assigns a model to the phone
* e.g. 7 or Galaxy
* @param newModel the phone's model
*/
public void setModel(String newModel) {
model = newModel;
}
/**
* Assigns the phone the current
* market price for that brand
* and model
* @param newPrice the market price
*/
public void setPrice(double newPrice) {
price = newPrice;
}
/**Additional Methods*/
/**
* Displays a message alerting the user
* that the phone is now making a call
*/
public void makeCall() {
System.out.println(brand + " is now making a call.");
}
/**
* Displays a message alerting the user
* that the phone is now making a call
* to a specified person
* @param name the person who is being called
*/
public void makeCall(String name) {
System.out.println(brand + " is now calling " + name);
}
/**
* Returns a String of all the important
* information about the phone, including
* brand, model and price
* @return the important phone information
*/
@Override public String toString() {
return "Brand: " + brand
+ "\nModel: " + model
+ "\nPrice: " + price;
}
}
Defining Objects from Overloaded Constructors
- If a class has more than one constructor, our program must decide which constructor to call
- The way that Java resolves which constructor to call is by matching the arguments to the parameter list
- Constructor matching is done based on the number and types of the parameters
- Also, the matching only works if the order is correct
- For example, assume our class has the following three constructors:
public Phone() {...}
public Phone(String theBrand) {...}
public Phone(String theBrand, String theModel, double thePrice) {...}
- Creating the following objects calls the indicated constructor
Phone phone1 = new Phone();
Phone phone2 = new Phone("Samsung");
Phone phone3 = new Phone("Samsung", "Galaxy S5", 139.99);
- Note that names play no role in matching, only the number and type in the correct order
Default Values
Activity 8.1: A Person Class with Overloaded Constructor (10 pts)
- Open up your Person.java class from the last activity.
- Now, add two constructors to your class as specified below:
- The first constructor is a default constructor
- It takes in no parameters
- It sets the the name field to have a default value of "name unknown"
- It sets the age field to have a default value of 0
- It sets the gender field to have a default value of "gender unknown"
- The second constructor overloads the first
- It takes in 3 parameters - a String for the name, an int for the age, a String for the gender
- It assigns name, age and gender the values passed in as parameters
- Copy and paste the new test file below into PersonTest.java (you can erase the old contents of the file):
/** * PersonTest.java * @author * CIS 36B, Activity 8.1 */
import java.util.Scanner;
public class PersonTest { public static void main(String[] args) { Scanner input = new Scanner(System.in); String name, gender; int age; Person person; System.out.print("Welcome!\n\nEnter your name: "); name = input.nextLine(); System.out.print("Enter your age: "); age = input.nextInt(); System.out.print("Enter your gender: "); gender = input.next();
person = //call 3-argument constructor here
System.out.println("\nYour Summary:\n" + person); } } - When you get the correct output (as shown below), upload Person.java and PersonTest.java to Canvas
Sample Output (Note that user input may vary):
Welcome!
Enter your name: Bao Li Enter your age: 29 Enter your gender: Male
Your Summary: Name: Bao Li Age: 29 Gender: Male
2. Working with Objects and References
Reference Types
- Data types in Java are divided into two categories: primitive and reference types
- All nonprimitive (that is class) types are reference types
Address Analogy
- By analogy, a reference variable is like the address of a house
- The address is a small identifier from which we can find a much larger object
- One of the advantages of addresses is that they are much easier to work with than actual houses
- For instance, if we want to locate people on a street by name, we could rearrange all the houses in alphabetical order by name
- An easier way is to make a list of last names with their addresses
- The address is the reference to the house object
- We get the same benefits when programming: it is often easier to work with references to objects rather than actual objects
- Other examples of references abound in real life: telephone numbers, e-mail addresses, social-security numbers, etc.
- Each reference type refers to and makes it easier to access a resource
Initial State
- You can initialize reference types to the value
null
Scanner input = null;
null is a keyword that means a "nothing" or "no value"
- A reference variable can only have one of two possible values:
null or a memory address - We can see this memory address when we print an Object that does not have a toString method defined
- If the reference type is a class variable, as opposed to a local variable, then Java initializes it to
null by default
References vs. Pointers
- Pointers are the most primitive and error-prone reference type
- They simply store a memory address
- In C/C++, you can actually manipulate pointers with arithmetic or even by assigning an arbitrary value
- A reference type in Java is like a pointer but without direct manipulation
- With references, you get the main benefits of a pointer but without many of the errors
- With fewer errors, you get more bug-free programs
- Also, you get additional features like automatic de-referencing and garbage collection
Heap and Stack Memory- Java uses two types of memory - heap and stack memory
- Stack memory stores local variables (primitives and reference variables) and information about each method call.
- Throughout
the execution of a program, the amount of stack memory currently in use
grows and shrinks as methods are called and methods return (end).
- Heap memory stores objects.
- All of the data about the object.
- Reference variables in the stack memory point to objects on the heap
- Reference variables simply store the address of the object in the heap
- An object is shared by all reference variables to this object
- Once
an object no longer has a reference variable referencing it in the
stack memory, it is removed by the automatic garbage collection.
- Note: we will talk about the String pool later this quarter
Group Activity - How Many Distinct Objects Are Created In the Below Program?Student s1 = new Student("Jackie Chan", 3.5); Student s2 = s1; s2 = new Student("Sandra Avila", 4.0); Student s3 = new Student("Basil Awad", 3.9);
s3 = new Student("Pham Van Duc", 3.75); s2 = s3; Student s4 = s1;
Objects as Method Parameters
- Java passes the value stored in a variable the same way for both primitive types and reference types
- When a method is called, the value of each argument is copied to its corresponding parameter
- Thus an argument's value can never be changed within a method
- However, copying a reference value to a parameter has certain implications
- The method gets access to the exact same object because it has a reference to the object
- You can see this situation in the following diagram:
- Since the method has been provided with the memory address of the object, the method can directly change the object.
- Compare to calling a method on a primitive: When calling a method with a primitive parameter, can the method change the value of the original primitive variable?
- Also, you can see the effects of passing a reference in the following program
Passing an Object to a Method
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 PassObject {
public static void main(String[] args) {
Coffee java = new Coffee("Expresso");
System.out.println("In main(): "
+ java.getFlavor());
changeData(java, "Latte");
System.out.println("In main(): "
+ java.getFlavor());
}
public static void changeData(Coffee cup, String flavor) {
System.out.println("Changing the flavor: "
+ cup.getFlavor());
cup.setFlavor(flavor);
}
}
class Coffee {
private String flavor;
public Coffee(String newFlavor) {
flavor = newFlavor;
}
public String getFlavor() {
return flavor;
}
public void setFlavor(String newFlavor) {
flavor = newFlavor;
}
}
|
Returning an Object
- Methods can return a reference to an object
- You can see how a reference is returned in the following code
Returning an Object from a Method
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
|
public class ReturnObject {
public static void main(String[] args) {
Coffee java = brew("Latte");
System.out.println("In main() I got: "
+ java.getFlavor());
System.out.println("Thank you!");
}
public static Coffee brew(String flavor) {
System.out.println("Brewing coffee");
Coffee cup = new Coffee(flavor);
return cup;
}
}
class Coffee {
private String flavor;
public Coffee(String newFlavor) {
flavor = newFlavor;
}
public String getFlavor() {
return flavor;
}
public void setFlavor(String newFlavor) {
flavor = newFlavor;
}
}
|
Activity 8.2: Personal Address (10 pts)
- Open up Person.java class from the last activity.
- Let's make some changes to this class.
- First, we are going to add a new class called Address to interact with the Person class.
- Add a new file to the folder where Person and PersonTest are stored. Name this file Address.java
public class Address { private int number; private String street;
/** * Default constructor for the Address class
* Initializes number to 0 and street to * "Street unknown"
*/
public Address() { //write default constructor here
}
/** * Constructor for the Address class * @param number the street number * @param street the name of the street */ public Address(int theNumber, String theStreet) {
//write two-argument constructor here
}
/** * Returns the street number portion * of the address * @return the street number */ public int getNumber() { return number; }
/** * Returns the name portion of the * address * @return the name of the street */ public String getStreet() { return street; }
//add setters here
/** * Displays an address in the format number + " " + street;
* @return a String containing the address
*/ //Write a toString() method for Address here! } - Next, open your Person.java class.
- Add an additional member variable:
private Address address;
- Also alter your multiple argument constructor to pass in an address variable:
public Person(... Address newAddress)- Update this constructor:
- Assign a value to the new member variable address
- Additionally, update your default constructor to assign address a value of new Address(). In other words, you will call the Address default constructor to initialize the address member variable to have default values.
- Next, add a getter and setter method for the address variable to your Person class.
public Address getAddress() { //fill in method body here
}
public void setAddress(Address a) { //fill in method body here
}
- Finally, alter your toString method for Person as follows:
@Override public String toString() { return "Name: " + name + "\nAge: " + age + "\nGender: " + gender + "\nAddress: " + //fill in here!; }
- Copy
and paste the new test file below into PersonTest.java (you can erase
the old contents of the file), and update the incomplete line.
/** * PersonTest.java * @author * CIS 36B, Activity 8.2 */
import java.util.Scanner;
public class PersonTest { public static void main(String[] args) { Scanner input = new Scanner(System.in); String name, gender, street; int age, number; Person person1; System.out.print("Welcome!\n\nEnter your name: "); name = input.nextLine(); System.out.print("Enter your age: "); age = input.nextInt(); System.out.print("Enter your gender: "); gender = input.next(); System.out.print("Enter the street number of your address: "); number = input.nextInt(); System.out.print("Enter the name of your street: "); input.nextLine(); street = input.nextLine(); Address address = //call Address constructor here person1 = //call Person constructor here System.out.println("\nYour Summary:\n" + person1);
input.close();
} } - When you get the correct output (as shown below), upload Address.java, Person.java and PersonTest.java to Canvas
Sample Output (Note that user input may vary):
Welcome!
Enter your name: Wen Li Enter your age: 23 Enter your gender: Male Enter the street number of your address: 2141 Enter the name of your street: W. Elm Ave
Your Summary: Name: Wen Li Age: 23 Gender: Male Address: 2141 W. Elm Ave
Wrap Up:
- Answer the practice exam questions on Canvas from this lesson.
Upcoming Assignments:- Activities 8.1 and 8.2 due Thursday at 11:59pm
- Lesson 8 Practice Exam Questions due Thursday at 11:59pm
- Quiz 4 due Friday at 11:59pm
- Peer Reviews of Lesson 7 and 8 Practice Exam Questions due Saturday at 11:59pm
- Lab 4 due Monday at 11:59pm
~ Have a Great Weekend! ~ |