Object References
> Click or hit Control-Enter to run Example.main above
Review: Simple Polymorphism
public class Dog extends Pet {
Dog() {
super("dog");
}
public void woof() {
// Code not included
}
}
public class Cat extends Pet {
Cat() {
super("cat");
}
public void meow() {
// Code not included
}
}
Review: Simple Polymorphism
Given the child classes shown above, implement their parent class Pet
.
Pet
should provide a single public class method called speak
that takes a
single argument which could be a Dog
, a Cat
, or another kind of Pet
not
shown above.
speak
should work as follows:
-
When
speak
is called with aDog
argument it should callwoof
on thatDog
instance. -
When
speak
is called with aCat
argument it should callmeow
on thatCat
instance. -
When
speak
is called on otherPet
descendants it should not do anything.
Review: Simple Polymorphism
Pet
should also provide a single constructor taking a single String
argument.
As shown above, that String
indicates the type of that Pet
.
You may or may not find this useful when implementing speak
.
Note that there are several ways to approach this problem, but all use forms of Java polymorphism.
> Click or hit Control-Enter to run Example.main above
This is Not a Class on Java Internals
You should learn to think in Java, not worry (yet) about what is going on below.
But We’ll Do A Bit of Java Internals
Either because it’s
-
important
-
interesting
-
fun
-
or some combination of the above.
References
Reference: a value that enables a program to indirectly access a particular datum, such as a variable’s value or a record, in the computer’s memory or in some other storage device. The reference is said to refer to the datum, and accessing the datum is called dereferencing the reference.
Java Reference Variables
class Person { }
/*
* me is declared to hold a reference to an object of type Person,
* but currently refers to nothing.
*/
Person me;
/*
* Initializing an instance to null is another way of indicating
* that it currently refers to nothing.
*/
Person you = null;
me = new Person(); // Now me refers to a new Person object
you = me; // Now me and you refer to the same Person object
System.out.println(you == me);
you = new Person(); // Now you refers to a new Person object
System.out.println(you == me);
We can refer to a Java variable that refers to an object as a reference variable.
> Click or hit Control-Enter to run the code above
References Are Not Objects
References are not the thing the refer to.
What are some real-world examples of references?
-
A phone number: which refers to a phone
-
A street address: which refers to a physical location
-
A social security number: which refers to a person
Copying References
Copying a reference does not copy the object it refers to.
-
Copying a phone number doesn’t copy the phone. Anyone with the number can call the same person.
-
Copying a street address doesn’t copy the location. Anyone with the address can navigate to the same spot.
-
Copying a social security number doesn’t copy the person 1. Anyone with social security number may be able to impersonate that person.
> Click or hit Control-Enter to run the code above
Copying References
class Person {
public int age;
}
Person me;
Copying References
class Person {
public int age;
}
Person me = new Person();
Copying References
class Person {
public int age;
}
Person me = new Person();
Person you = me;
Copying References
class Person {
public int age;
}
Person me = new Person();
Person you = me;
me.age = 10;
Copying References
class Person {
public int age;
}
Person me = new Person();
Person you = me;
me.age = 10;
System.out.println(you.age);
> Click or hit Control-Enter to run the code above
Swapping References
class Person {
public int age;
Person(int setAge) {
this.age = setAge;
}
}
Person me = new Person(38);
Person you = new Person(18);
Swapping References
class Person {
public int age;
Person(int setAge) {
this.age = setAge;
}
}
Person me = new Person(38);
Person you = new Person(18);
Person tmp = me;
Swapping References
class Person {
public int age;
Person(int setAge) {
this.age = setAge;
}
}
Person me = new Person(38);
Person you = new Person(18);
Person tmp = me;
me = you;
Swapping References
class Person {
public int age;
Person(int setAge) {
this.age = setAge;
}
}
Person me = new Person(38);
Person you = new Person(18);
Person tmp = me;
me = you;
you = tmp;
Swapping References
class Person {
public int age;
Person(int setAge) {
this.age = setAge;
}
}
Person me = new Person(38);
Person you = new Person(18);
Person tmp = me;
me = you;
you = tmp;
// Now we can discard tmp
> Click or hit Control-Enter to run the code above
Pass By Reference
class Person {
public int age;
Person(int setAge) {
this.age = setAge;
}
}
int birthday(Person toSet) {
toSet.age++;
return toSet.age;
}
Person me = new Person(38);
System.out.println(birthday(me));
System.out.println(me.age);
In Java methods receive a copy of a reference to the passed object.
So they can modify the object the reference refers to.
Pass By Reference
class Person {
public int age;
Person(int setAge) {
this.age = setAge;
}
}
int birthday(Person toSet) {
toSet.age++;
return toSet.age;
}
Person me = new Person(38);
Pass By Reference
class Person {
public int age;
Person(int setAge) {
this.age = setAge;
}
}
int birthday(Person toSet) {
toSet.age++;
return toSet.age;
}
Person me = new Person(38);
System.out.println(birthday(me));
Pass By Reference
class Person {
public int age;
Person(int setAge) {
this.age = setAge;
}
}
int birthday(Person toSet) {
toSet.age++;
return toSet.age;
}
Person me = new Person(38);
System.out.println(birthday(me));
System.out.println(me.age);
> Click or hit Control-Enter to run Example.main above
Arrays Store Object References
class Person {
public int age;
Person(int setAge) {
this.age = setAge;
}
}
Person[] people = new Person[4];
for (int i = 0; i < people.length; i++) {
people[i] = new Person(18 + i);
}
Person[] samePeople = new Person[4];
for (int i = 0; i < people.length; i++) {
samePeople[i] = people[i];
}
for (int i = 0; i < people.length; i++) {
people[i].age++;
}
for (int i = 0; i < samePeople.length; i++) {
System.out.println(samePeople[i].age);
}
So copying an array as above only copies the object references, not the objects themselves.
> Click or hit Control-Enter to run Example.main above
How To Copy Objects
public class Person {
public int age;
Person(int setAge) {
this.age = setAge;
}
Person(Person other) {
this.age = other.age;
}
}
If we want to copy an object, we have a few options:
-
Object
provides aclone
method -
You can implement a copy constructor as shown above
Shallow v. Deep Copies
public class Person {
public Pet pet;
Person(Person other) {
this.pet = other.pet;
}
}
What is a potential problem with the copy constructor shown above?
-
It only copies the reference to the
Pet
object. So both the existing and the new object will share the samePet
object. -
This is called a shallow copy. A deep copy copies all of the objects so the old and new object share nothing.
Reference v. Object Equality
public class Person {
public int age;
Person(int setAge) {
this.age = setAge;
}
boolean equals(Person other) {
return this.age == other.age;
}
}
Person me = new Person(38);
Person other = new Person(38);
System.out.println(me == other);
System.out.println(me.equals(other));
-
If two references are equal then they refer to the same object, and
.equals
is almost always true. -
If two references are not equal, the class may still define
.equals
to be true depending on the value of the instance variables.
> Click or hit Control-Enter to run the code above
References v. Objects
When matching method signatures Java uses the type of the reference, not the type of the object.
-
If the reference type doesn’t match, Java will upcast until it finds a match or the call fails
CS Cat Does Taxes
> Click or hit Control-Enter to run Example.main above
> Click or hit Control-Enter to run Example.main above
Announcements
-
MP3 is due Monday! Office hours all day today.
-
I will not hold my weekly office hours today—I’m out of town this weekend.