Objects as Parameters
Estimated time to read: 4 minutes
Using an Object as a Parameter¶
First, let’s create a class called Cupcake:
class Cupcake {
String flavor;
boolean sprinkles;
public Cupcake(String type, boolean hasSprinkles) {
flavor = type;
sprinkles = hasSprinkles;
}
}
Now, we’ll create a class called Bakery whose constructor accepts an object of Cupcake as a parameter:
java
class Bakery {
Cupcake bakeryCupcake;
double price;
String giveTotal;
public Bakery(Cupcake cupcakeType, double priceOf) {
bakeryCupcake = cupcakeType;
price = priceOf;
giveTotal = "The " + bakeryCupcake.flavor + " cupcake is €" + price;
}
}
Inside the main() method of the Bakery class, we’ll create a new Cupcake object called chocolateSprinkle. Then, we’ll create a new Bakery object, called myBakery, that takes the chocolateSprinkle object as a parameter:
public static void main(String[] args) {
Cupcake chocolateSprinkle = new Cupcake("chocolate", true);
// Add your code below
Bakery myBakery = new Bakery(chocolateSprinkle, 3.25);
System.out.println(myBakery.giveTotal);
}
When we run this program, we get the following output:
The chocolate cupcake is €3.25
Creating a Copy of an Object¶
If we use an object as a parameter for a constructor method, it’s a good programming practice to not modify said object unless the situation requires it. If we do find ourselves needing to modify an object sent as a parameter, we should set the instance variable to hold a copy of the referenced object instead of the original object.
Let’s say we added the line bakeryCupcake.flavor = "vanilla";to our Bakery constructor that changes the flavor value of the chocolateSprinkle object to "vanilla".
public Bakery(Cupcake cupcakeType, double priceOf) {
bakeryCupcake = cupcakeType;
// change cupcake object flavor to vanilla
bakeryCupcake.flavor = "vanilla";
price = priceOf;
giveTotal = "The " + bakeryCupcake.flavor + " cupcake is €" + price;
}
class Cupcake {
String flavor;
boolean sprinkles;
public Cupcake(String type, boolean hasSprinkles) {
flavor = type;
sprinkles = hasSprinkles;
}
}
class Bakery {
Cupcake bakeryCupcake;
double price;
String giveTotal;
public Bakery(Cupcake cupcakeType, double priceOf) {
bakeryCupcake = cupcakeType;
price = priceOf;
// Uncomment line below
bakeryCupcake.flavor = "vanilla";
giveTotal = "The " + bakeryCupcake.flavor + " cupcake is €" + price;
}
public static void main(String[] args) {
Cupcake chocolateSprinkle = new Cupcake("chocolate", true);
// Create an object that takes in an object as a parameter
Bakery myBakery = new Bakery(chocolateSprinkle, 3.25);
// Output a value of parameter object
System.out.println("Our object sent as a parameter has a flavor value of " + myBakery.bakeryCupcake.flavor);
// Output a value of original object
}
}
See how the Bakery constructor is impacting the flavor instance variable of our chocolateSprinkle object instead of only changing bakeryCupcake? Both of their flavor instance variables now have a value of "vanilla".
Why did this happen? When an object is sent as an argument, the value sent to the parameter is a reference to the original object and not a copy of the original object; therefore, whenever we make a change to our parameter object, we are also making a change to our original object. Note that this doesn’t happen with primitive values because the parameter value is initialized with a copy of the argument value.
To only change the value of the parameter object and not the original object, we’ll discuss how to create a copy of an object.
One way to create a copy of an object is to make a copy constructor. The copy constructor is an additional class constructor; remember, a class can have multiple constructors as long as each constructor has its own unique signature. Copy constructors create a copy of an object by taking in an object and setting the values of the new object to the same values of the parameter object.
class Cupcake {
String flavor;
boolean sprinkles;
// original constructor
public Cupcake(String type, boolean hasSprinkles) {
flavor = type;
sprinkles = hasSprinkles;
}
// copy constructor
public Cupcake(Cupcake copy) {
flavor = copy.flavor;
sprinkles = copy.sprinkles;
}
}
public Bakery(Cupcake cupcakeType, double priceOf) {
// Create a copy Cupcake object
Cupcake copy = new Cupcake(cupcakeType);
// set bakeryCupcake to hold value of object copy
bakeryCupcake = copy;
price = priceOf;
bakeryCupcake.flavor = "vanila";
giveTotal = "The " + bakeryCupcake.flavor + " cupcake is €" + price;
}
In our constructor, we created a new object, copy, that calls the copy constructor in order to create and store a copy of our parameter object cupcakeType. Then, we set our instance variable, bakeryCupcake to store the value of copy.
Now that we have a copy of the object, we don’t have to worry about an object sent as a parameter to the Bakery class changing the state of our Cupcake objects, like chocolateSprinkle. By adding a copy constructor to our code, our output changes.
class Cupcake {
String flavor;
boolean sprinkles;
public Cupcake(String type, boolean hasSprinkles) {
flavor = type;
sprinkles = hasSprinkles;
}
// copy constructor
public Cupcake(Cupcake copy) {
flavor = copy.flavor;
sprinkles = copy.sprinkles;
}
}
class Bakery {
Cupcake bakeryCupcake;
double price;
String giveTotal;
public Bakery(Cupcake cupcakeType, double priceOf) {
// Create a copy Cupcake object
Cupcake copy = new Cupcake(cupcakeType);
// set bakeryCupcake to hold value of object copy
bakeryCupcake = copy;
price = priceOf;
bakeryCupcake.flavor = "vanila";
giveTotal = "The " + bakeryCupcake.flavor + " cupcake is €" + price;
}
public static void main(String[] args) {
Cupcake chocolateSprinkle = new Cupcake("chocolate", true);
Bakery myBakery = new Bakery(chocolateSprinkle, 3.25);
// Output a value of parameter object
System.out.println("Our object sent as a parameter has a flavor of " + myBakery.bakeryCupcake.flavor);
// Output a value of original object
System.out.println("Our original object has a flavor of " + chocolateSprinkle.flavor);
}
}
- Objects can be sent as a parameter to a constructor.
- In order to avoid changing the state of the original object, it’s best practice to create a copy of the object sent as a parameter.
- One method of copying an object is creating a copy constructor that copies the attributes of an object into a new object.