简单说内部类

  • 将一个类定义在另一个类的定义内部,就是内部类,而这里的另一个类被称为外围类(或外部类)。
  • 内部类对象被外围类(外部类)创建时,会自动拥有一个指向该外围类的引用,还包含外围类对象的信息(闭包)。这意味着,内部类可以直接操作外围类的成员,即是是私有(private)的成员属性与方法,而无需实例出外围类的对象(因为自动拥有)。
  • 由于Java的继承是单继承,而每个内部类都能够独立地继承自一个(接口的)实现,也即,内部类为外围类提供了“可以继承多个具体或抽象的类”的能力。
  • 类的实质是一种新的数据类型,创建私有(private)的内部类即同理创建一个具有新数据结构的私有成员。

匿名内部类

匿名内部类通过一个返回值为基类接口(向上转型)的方法创建出一个没有类名的对象。简单来看:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
class A {
void say() {
System.out.println("I am A.");
}
}

public class B {
public A createA() {
return new A() {
@Override
public void say() {
System.out.println("I am inside B.");
}
};
}

public static void main(String[] args) {
B b = new B();
A a = b.createA();
a.say();
}
}

/**
* Output:
* I am inside B.
*/

匿名内部类简化了代码,由于不具有类名,匿名内部类只被使用一次。接下来看看工厂方法中使用匿名内部类以简化代码。

工厂方法

1. 先看不使用匿名内部类实现的工厂方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
interface Cycle {
void ride();
}

interface CycleFactory {
Cycle getCycle();
}

class Bicycle implements Cycle {
@Override
public void ride() {
System.out.println("Bicycle rides.");
}
}

class BicycleFactory implements CycleFactory {
@Override
public Cycle getCycle() {
return new Bicycle();
}
}

public class Factory {
public static void cycleConsumer(CycleFactory factory) {
Cycle cycle = factory.getCycle();
cycle.ride();
}

public static void main(String[] args) {
cycleConsumer(new BicycleFactory());
}
}

2. 再看使用了匿名内部类的工厂方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
interface Cycle {
void ride();
}

interface CycleFactory {
Cycle getCycle();
}

class Bicycle implements Cycle {
@Override
public void ride() {
System.out.println("Bicycle rides.");
}

public static CycleFactory factory = new CycleFactory() {
@Override
public Cycle getCycle() {
return new Bicycle();
}
}; // 通过一个静态成员变量(类属性)来保存工厂生成的Bicycle
}

public class Factory {
public static void cycleConsumer(CycleFactory factory) {
Cycle cycle = factory.getCycle();
cycle.ride();
}

public static void main(String[] args) {
cycleConsumer(Bicycle.factory); // 不需要实例工厂类
}
}

3. 对比

  • 通过在外围类中创建一个返回类型为工厂接口(CycleFactory)的方法,来创建一个Bicycle的工厂,并将该工厂用类属性(静态成员变量)保存,从而可以直接访问该静态成员变量以访问其工厂。
  • 工厂只需要一个,故使用匿名内部类创建工厂对象并由类属性保存,即可通过使用该类属性让工厂生产对象。