- Maybe you want a function that returns multiple pieces of data, and you would rather not have to use pass by reference to get that information out.
- Maybe you want to work with information the describes the same thing (such as a midshipman) but the data is heterogeneous (such as a String for the name, and int for the alpha code, and a double for the QPR).
- Maybe you need to move these chuncks around as units, such as nodes in linked lists.
- We already saw these problems in C++, and we know the solution: Structs.
- Objects (in both Java and C++) give us the same ability to group data together that structs do. Objects can do much much more, but lets start here.
- In C++, we might define a struct like this:
struct point
{
double x,y;
};
and write a function that uses it like this:
point midPoint(point left, point right)
{
point middle;
middle.x = (left.x + right.x)/2;
middle.y = (left.y + right.y)/2;
return middle;
}
and use it like this:
int main()
{
point myPoint1, myPoint2;
cout << "Enter point 1: ";
cin >> myPoint1.x >> myPoint1.y;
cout << "Enter point 2: ";
cin >> myPoint2.x >> myPoint2.y;
point r = midPoint(myPoint1,myPoint2);
cout << "MidPoint is (" << r.x
<< ',' << r.y << ")" << endl;
return 0;
}
Note how creating the struct created a new type that can be used like any of the built in types. You can create variables of that type and assign them values like any type.
- Java doesn't have structs at all, only objects, so we'll have to use those. There are some important differences:
- Java defines these with the class keyword. The is a good point to talk about the terminology. These struct-like things are defined in classes. When you have a particular instance of this class (i.e. a chunk of memory for a variable, that is called an object. This distinction will make more sense when you know a little more, but for now, just remember: the class is the definition, the object is the variable, or chunk of allocated memory.
- A class (almost always) must be defined in a new file that defines just that class.
- We may need to add the word public before variables.
- There is no ; at the end of the class definition
- You cannot just create a variable of the type of the class, like we did for point above. You must create a pointer to the object, and then create the object with the new keyword.
- Because you cannot not create a pointer to an object, whenever you create a variable of that type, IT IS AUTOMATICALLY A POINTER AND YOU DO NOT USE THE * OR INDICATE ITS SPECIAL POINTERNESS IN ANY WAY. Java has lots of pointers, but you don't ever talk about them explicitly. There a some tricky ramifications of this we'll talk about later.
- So what does our point look like in java?
in a new file named Point.java (oh, we always capitalize classes)
class Point {
public double x,y;
} //no ;
in the file main:
public static Point midPoint(Point left, Point right)
{
Point middle = new Point();
//even though a pointer, no *
middle.x = (left.x + right.x)/2;
middle.y = (left.y + right.y)/2;
return middle;
}
and also in main:
public static void main(String [] args) {
Point myPoint1 = new Point();
Point myPoint2 = new Point();
Scanner in; //don't forget the import!
System.out.print("Enter Point 1: ");
myPoint1.x = in.nextDouble();
myPoint1.y = in.nextDouble();
System.out.print("Enter Point 2: ");
myPoint2.x = in.nextDouble();
myPoint2.y = in.nextDouble();
Point r;
r = midPoint(myPoint1,myPoint2); // why no new for r??
System.out.println("MidPoint is (" + r.x + "," r.y + ")");
return 0;
}
- Once again, a bit wordier, but we're none the worse for wear.
- What about those subleties we mentioned about the pointer
stuff? Well one is, although there is no explicict pass by
reference in java, any time you you pass in an object, you are
passing it in by reference.
public static void movePoint(Point p, double factor) {
p.x = p.x * factor;
p.y = p.y * factor;
return; //no value needed, modification of point worked.
}
- Another subtlety is that assignment of objects is never a copy, but just a pointer change:
int i = 3;
int j = i; //3 is copied into j
j = 4; //i still 3
Point p = new Point();
p.x = 3;
Point j = i; //j points to i
j.x = 4; //i.x changed to 4!!
- Finally, although objects can be passed by reference, their
pointers cannot! (without some trickery anyway)
public static void swap(Point p, Point q) {
//DOES NOT WORK!!
Point tmp = p;
p = q;
q = p;
return; //FAIL!
}
You can change things inside objects, but not the pointers to objects.
- How's that work (or rather not work)?
Assume the function was called like this:
Point r = new Point();
Point s = new Point();
swap(r,s)
p and q are copies of the original pointers, so p points to the same thing r does, and q points to the same thing p does. changing p.x would also change the Point that r points to, but changing p just moves that pointer, and doesn't change r. (see diagram)
- OK, to test this all out, let's build a simple linked list of char, with an addToEnd(char c) function, a printList() function, and a deleteChar(char c) function.