Chapter 2 · Objects
Classes and objects
Step 1 of 22 · Concept
A class can describe a thing
So far a class has held main and static methods. A class can also describe a kind of thing, such as a bank
account. Your program then makes as many of them as it needs.
In this lesson you will:
- make objects with
newand see where they live in memory, - write a class with fields, a constructor and methods,
- build one class on top of another.
Step 2 of 22 · Concept
Fields, a constructor, methods
This class describes a bank account:
public class Account {
String owner;
int balance;
Account(String owner, int balance) {
this.owner = owner;
this.balance = balance;
}
void deposit(int amount) {
balance += amount;
}
}
| part | in Account | what it is |
|---|---|---|
| fields | owner, balance | the values each account keeps |
| constructor | Account(…) | sets up a new account |
| method | deposit | something each account can do |
An object is one account made from this class. The step A constructor sets up the object explains
this.
Step 3 of 22 · Concept
new makes an object on the heap
Account a = new Account("Ada", 10);
newmakes anAccountobject on the heap, with its ownownerandbalance.- The box
ainmain's frame holds a reference to it: the arrow. a.balancefollows the arrow and reads the field:10.
Step 4 of 22 · Concept
Each object has its own fields
Account a = new Account("Ada", 10);
Account b = new Account("Grace", 20);
a.deposit(5);
- Each
newmakes another object, with fields of its own. a.deposit(5)runsdepositon the objectapoints at. Only that object'sbalancechanges, to 15.b's balance stays 20.
Step 5 of 22 · Quiz
What will it print?
Type exactly what these lines print.
Account a = new Account("Ada", 10);
Account b = new Account("Grace", 20);
a.deposit(5);
System.out.println(a.owner + ": " + a.balance);
System.out.println(b.owner + ": " + b.balance);
Step 6 of 22 · Demo
See two objects run
Two files: Main.java makes the objects, Account.java is the class. Run it and compare with your answer.
Step 7 of 22 · Concept
Two arrows, one object
Account a = new Account("Ada", 10);
Account c = a;
c.deposit(5);
c = acopies the arrow, not the object. Nowaandcpoint at one object.c.deposit(5)changes that object, soa.balanceis 15 too.- Two names for one object is called aliasing.
Step 8 of 22 · Quiz
Which balance changed?
After these lines, what are a.balance and b.balance?
Account a = new Account("Ada", 10);
Account b = new Account("Ada", 10);
Account c = a;
c.deposit(5);
Step 9 of 22 · Concept
null: no object
Account a = new Account("Ada", 10);
Account b = null;
b.deposit(5);
nullmeans "no object". A box that holdsnullhas no arrow.b.deposit(5)has no object to run on. The program stops with aNullPointerException.
Step 10 of 22 · Concept
A constructor sets up the object
Account(String owner, int balance) {
this.owner = owner;
this.balance = balance;
}
- The constructor has the class's name and no return type.
new Account("Ada", 10)makes the object, then runs the constructor to fill in its fields.- Until then, each field holds a default:
0for a number,falsefor aboolean,nullfor an object. - Its parameters have the fields' names.
owneralone is the parameter. thisis a reference to the object being set up.this.owneris its field.
So this.owner = owner; copies the parameter into the field.
Step 11 of 22 · Trace
Watch the constructor run
A constructor gets a frame on the stack, like any method (lesson 6). main sits in Account here to keep the
listing short. Press Next.
public class Account {
String owner;
int balance;
Account(String owner, int balance) {
this.owner = owner;
this.balance = balance;
}
public static void main(String[] args) {
Account a = new Account("Ada", 10);
System.out.println(a.owner);
}
}mainruns. Line 11 is next.newmade the object. Its fields hold their defaults,nulland0. The constructor's frame holdsthisand the parameters.- Line 6 copied the parameter
ownerinto the object's field. - Line 7 set
balance. The constructor ended: its frame is gone, andaholds the arrow. - Line 12 followed
a's arrow and printed the fieldowner:Ada.mainis over, so its frame is gone.
Step 12 of 22 · Concept
Methods that belong to an object
deposit has no static. It is an instance method: you call it on an object.
static method (lesson 6) | instance method | |
|---|---|---|
| written | static String greet(String name) | void deposit(int amount) |
| called on | the class: Greeter.greet("Ada") | an object: a.deposit(5) |
balance inside means | no object, no field | the field of that object |
Inside deposit, this is the object it runs on, and balance is short for this.balance. So
a.deposit(5) changes a's balance, and b.deposit(5) changes b's.
Step 13 of 22 · Concept
Private fields and toString
Right now, any code can write a.balance = -5;. Two words protect the fields:
private: only code insideAccountcan read or change the field.final: the field is set once, in the constructor, and never changes after. An account keeps its owner.
Now main cannot read a.balance. So the class says how to print itself, in a method toString.
println(a) calls a.toString() and prints the text it returns. So does + when it joins an object to text.
Step 14 of 22 · Demo
See toString run
Run it. println(a) prints what toString returns.
Step 15 of 22 · Try it
Try it: private means private
Run it: javac refuses with balance has private access in Account. Replace that line with a.deposit(5);,
which Account allows, and run it again.
Step 16 of 22 · Exercise
Your turn: withdraw
Add a method withdraw(int amount) to Account. It takes amount out of the balance, but only if the balance
is big enough; otherwise it changes nothing. The program must print:
Ada: 20
Ada: 20
The second withdrawal is refused.
withdraw looks like deposit, in Account.java. It changes balance only when there is enough.
Inside void withdraw(int amount), an if (amount <= balance) around balance = balance - amount;.
void withdraw(int amount) {
if (amount <= balance) {
Step 17 of 22 · Concept
One class extends another
class Checking extends Account makes a subclass: a Checking is an Account with more.
- It has every field and method of
Account, and adds its own:chargeFee. - A constructor is not passed down:
Checkingwrites its own. It callssuper(owner, balance), which runsAccount's constructor.supermeans the class it extends. - A
privatefield is hidden even from a subclass. Aprotectedone is not.
Step 18 of 22 · Demo
See a subclass run
Account.java here makes balance protected, so chargeFee can change it. Run it: 10, plus 5, minus a fee
of 2.
Step 19 of 22 · Exercise
Your turn: a savings account
Savings.java holds an empty class. Make Savings extend Account. Give it:
- a constructor
Savings(String owner, int balance)that callssuper(owner, balance), - a method
addInterest()that deposits 10 % of the balance (balance / 10).
The program must print Grace: 220.
Checking.java in the step See a subclass run has the same shape: extends, a constructor with super, one method.
The first line is public class Savings extends Account {. addInterest can call deposit: it is a method of
Savings too.
void addInterest() {
deposit(balance / 10);
}
Step 20 of 22 · Check yourself
Check yourself: rectangles and squares
Write the classes Rectangle and Square. A square is a rectangle with equal sides. Main must print exactly:
3 x 4 has area 12
6 x 8 has area 48
5 x 5 has area 25
Rectangle needs two fields, a constructor, area, scale and toString. Square needs only a constructor.
Step 21 of 22 · Challenge · optional
Challenge: a transfer
Optional. It earns the lesson's third star.
Add a method transfer(Account to, int amount) to Account. It moves amount from this account to to, but
only if this balance is big enough. The program must print:
Ada: 20, Grace: 50
Ada: 65, Grace: 5
Ada: 65, Grace: 5
A parameter can hold a reference. In a.transfer(b, 30), to gets a copy of b's arrow: one object, two names.
So to.deposit(amount) changes the very object b points at. Take the money out of balance first, as in
withdraw.
if (amount <= balance) {
balance = balance - amount;
to.deposit(amount);
}
Step 22 of 22 · Recap
Recap
- A class has fields, a constructor and methods.
newmakes an object of it. - Objects live on the heap; a box holds a reference, an arrow.
nullmeans no object. - Copying a reference gives a second arrow to the same object.
thisis the object a method runs on.privatekeeps other classes out;toStringprints an object.extendsbuilds a subclass; its constructor callssuper(…).
Next: lesson 8 puts Account into a package, a folder of its own.
Review
2 questions from this lesson, in a new order each time. Answer from memory: 2 of 2 right on the first try passes. On a day after you finish the lesson, a pass earns 15 XP.
The review needs JavaScript.
public class Main {
public static void main(String[] args) {
Account a = new Account("Ada", 10);
Account b = new Account("Grace", 20);
a.deposit(5);
System.out.println(a.owner + ": " + a.balance);
System.out.println(b.owner + ": " + b.balance);
}
}
public class Main {
public static void main(String[] args) {
Account a = new Account("Ada", 10);
a.deposit(5);
System.out.println(a);
}
}
public class Main {
public static void main(String[] args) {
Account a = new Account("Ada", 10);
a.balance = -5;
System.out.println(a);
}
}
public class Main {
public static void main(String[] args) {
Account a = new Account("Ada", 50);
a.withdraw(30);
System.out.println(a);
a.withdraw(100);
System.out.println(a);
}
}
public class Main {
public static void main(String[] args) {
Checking c = new Checking("Ada", 10);
c.deposit(5);
c.chargeFee();
System.out.println(c);
}
}
public class Main {
public static void main(String[] args) {
Savings s = new Savings("Grace", 200);
s.addInterest();
System.out.println(s);
}
}
public class Main {
public static void main(String[] args) {
Rectangle r = new Rectangle(3, 4);
System.out.println(r + " has area " + r.area());
r.scale(2);
System.out.println(r + " has area " + r.area());
Square s = new Square(5);
System.out.println(s + " has area " + s.area());
}
}
public class Main {
public static void main(String[] args) {
Account a = new Account("Ada", 50);
Account b = new Account("Grace", 20);
a.transfer(b, 30);
System.out.println(a + ", " + b);
b.transfer(a, 45);
System.out.println(a + ", " + b);
b.transfer(a, 10);
System.out.println(a + ", " + b);
}
}