Class and object
What you'll learn:
- describe your own type with a class, create objects with
newand explain why two variables can lead to one object; - set an object's fields in a constructor and tell
this.xfromxinside it; - close fields with
privateand tell an object's field from astaticfield; - print an object through
toStringand read aNullPointerExceptionmessage.
Picture the blueprint of a house. It says what every house will have: how many floors, what color the roof is. You cannot live in a blueprint; it is only a description. But one blueprint can give you a whole street. The houses come out alike, yet each has its own roof, and repainting one house leaves its neighbor as it was.
Java works the same way. The blueprint is a class: it describes the data every object will have. A house is an object, which the program builds from the blueprint while it runs.
Why do we need this? Take a point on a plane. It is two numbers, x and y, and they always go together. A hundred points would need two hundred variables, and the x of one point would sit next to the y of another. A class lets you tell Java "a point is a pair of numbers" and then work with a point as one thing:
public class Main {
public static void main(String[] args) {
Point p = new Point();
p.x = 3;
p.y = 4;
System.out.println(p.x + " " + p.y); // 3 4
Point q = new Point();
System.out.println(q.x + " " + q.y); // 0 0
}
}
class Point {
int x;
int y;
}Let's go through the program step by step:
- At the bottom of the file, the class
Pointis declared with two fields,xandy. This is the blueprint. new Point()builds an object from the blueprint, one point, andPoint pdeclares a variable for it.p.x = 3;andp.y = 4;put numbers into the fields of this point. The dot between the variable name and the field name reads as "the fieldxof the pointpleads to".- The first
printlnprints3 4. new Point()builds a second point. Nobody put anything into its fields, so it prints0 0.
What a class describes
A class is the description of a new type: which fields each of its objects will have. Once class Point is declared, the program has a type Point, and you declare a variable of this type the same way as a variable of type int or String.
An object is one concrete thing built from a class with new. An object is also called an instance of the class. What matters about objects:
- each object has its own fields: writing to
p.xdoes not changeq.x; - the fields of a new object get default values, like
staticfields:0for numbers,falseforboolean,nullforString; - you can create as many objects of one class as you like, and each
newbuilds a new one.
The class Point is declared in the same file, after Main, and without the word public. A file may hold only one public class, and the file is named after it: Main.java.
A variable holds an address
Back to the street. The variable p holds not the house itself but a slip of paper with its address. As with an array, this is a reference: new Point() builds the object on the heap and returns a reference to it. Let's see what happens when you copy such a slip:
Point a = new Point();
Point b = a;
b.x = 7;
System.out.println(a.x); // 7Line by line:
Point a = new Point();builds a house and puts its address intoa.Point b = a;copies the slip with the address, not the house. Nowaandblead to one object.b.x = 7;follows the address inband changes a field of that object.a.xprints7: the address inaleads to the same house.
If you now write b = new Point();, the slip b gets the address of a new house. The old house is not affected: a still leads to it, and a.x stays 7.
Here the house picture is not exact. You can reach a real house without a slip if you know the street. A program reaches an object only through a reference: if no variable leads to an object, there is no way to work with it anymore.
An object as a method parameter
Interviewers like to ask this: can a method change an object passed to it? Let's see:
public class Main {
static void move(Point p) {
p.x = 10;
p = new Point();
p.x = 20;
}
public static void main(String[] args) {
Point a = new Point();
move(a);
System.out.println(a.x); // 10
}
}
class Point { int x; int y; }The class Point here is the same, only written on one line. Let's go through the call move(a) step by step:
- The parameter
pgets a copy of the value ofa, that is, a copy of the address. Nowaandplead to one point. p.x = 10;changes a field of that point, andmainwill see the change.p = new Point();writes the address of a new point on the slipp. The slipainmainstays as it was.p.x = 20;changes the new point, whichmainknows nothing about.mainprints10.
The interview answer goes like this: Java always passes arguments by value, and the value of an object variable is a reference. So a method can change an object's fields, but it cannot make the caller's variable lead to another object.
Common mistake
The variable is declared, but the object is never built:
Point p;
p.x = 3; // ✗error: variable p might not have been initializedThe program does not compile. Point p; declares only the slip for an address; nobody built a house, so there is nowhere to put 3. Only new creates an object: Point p = new Point();.
Key points
- A class describes the fields of a new type, and
newbuilds an object from it; each object has its own fields. - A variable of type
Pointholds a reference to an object, soPoint b = acopies the reference, andaandblead to one object. - A method gets a copy of the reference: it can change the object's fields, but assigning to the parameter does not change the caller's variable.
- Without
newthere is no object:Point p;does not create a point.