Inner Classes
An inner class provides a shorthand for creating small classes
whose meaning is clearer if kept in the immediate context.
A static inner class is just a class that lives inside
another class. For exmaple:
| Destroyer.java |
| 1 | public class Destroyer { |
| 2 | public static class Turret{ |
| 3 | final String name; |
| 4 | Direction dir; |
| 5 | public Turret(String n) { name = n; } |
| 6 | public String toString() { return name; } |
| 7 | } |
| 8 | |
| 9 | Turret fore, aft; |
| 10 | public Destroyer() { |
| 11 | fore = new Turret("Fore"); |
| 12 | aft = new Turret("Aft"); |
| 13 | } |
| 14 | |
| 15 | public static void main(String[] args) { |
| 16 | Destroyer b = new Destroyer(); |
| 17 | System.out.println("fore="+b.fore+" aft="+b.aft); |
| 18 | } |
| 19 | } |
$ javac Destroyer.java
| $ java Destroyer
fore=Fore aft=Aft
|
Sometimes you want the inner class to know about the class it
is inside of.
| Bank.java |
| 1 | public class Bank { |
| 2 | int balance; |
| 3 | public class TellerMachine { |
| 4 | double deposit; |
| 5 | public void makeDeposit(int a) { |
| 6 | // the TellerMachine makes use of the outer class field "balance" |
| 7 | balance += a; |
| 8 | deposit += a; |
| 9 | } |
| 10 | public String toString() { |
| 11 | // the TellerMachine makes use of the outer class field "balance" |
| 12 | return "total="+balance+" this TellerMachine="+deposit; |
| 13 | } |
| 14 | } |
| 15 | // construct in the normal way |
| 16 | TellerMachine a1 = new TellerMachine(); |
| 17 | TellerMachine a2 = new TellerMachine(); |
| 18 | |
| 19 | public static void main(String[] args) { |
| 20 | Bank acc = new Bank(); |
| 21 | acc.a1.makeDeposit(1); |
| 22 | acc.a2.makeDeposit(2); |
| 23 | |
| 24 | // special constructor for inner classes |
| 25 | TellerMachine a3 = acc.new TellerMachine(); |
| 26 | a3.makeDeposit(3); |
| 27 | System.out.println("TellerMachine 1="+acc.a1); |
| 28 | System.out.println("TellerMachine 2="+acc.a2); |
| 29 | System.out.println("TellerMachine 3="+a3); |
| 30 | } |
| 31 | } |
$ javac Bank.java
| $ java Bank
TellerMachine 1=total=6 this TellerMachine=1.0
TellerMachine 2=total=6 this TellerMachine=2.0
TellerMachine 3=total=6 this TellerMachine=3.0
|
Java defines an interface called Runnable, which has a single
public method called "void run()". We can create a number of
anonymous inner classes that implement it.
| Anon.java |
| 1 | public class Anon { |
| 2 | public static void main(String[] args) { |
| 3 | // Creates an anonymous inner class. Note |
| 4 | // the () is a call to a constructor. |
| 5 | Runnable taskA = new Runnable() { |
| 6 | public void run() { |
| 7 | System.out.println("task A"); |
| 8 | } |
| 9 | }; |
| 10 | Runnable taskB = new Runnable() { |
| 11 | // instance initializer, similar to a constructor |
| 12 | { letter = 'B'; } |
| 13 | char letter; |
| 14 | public void run() { |
| 15 | System.out.println("task "+letter); |
| 16 | } |
| 17 | }; |
| 18 | Runnable taskC = new Runnable() { |
| 19 | public void run() { |
| 20 | System.out.println("task C"); |
| 21 | } |
| 22 | }; |
| 23 | Runnable[] toDoList = new Runnable[]{taskA,taskB,taskC}; |
| 24 | for(Runnable whatsNext : toDoList) { |
| 25 | whatsNext.run(); |
| 26 | } |
| 27 | } |
| 28 | } |
$ javac Anon.java
| $ java Anon
task A
task B
task C
|
In the above code, we implement the Runnable interface three times,
but in no case do we give the class a name. It is, therefore, anonymous.
|