使用内部类最吸引人的原因是:
每个内部类都能独立地继承自一个(接口的)实现,所以无论外围类是否已经继承了某个(接口)的实现,对于内部类都没有影响。如果没有内部类提供的可以继承多个具体的或抽象的类的能力,一些设计与编程问题就很难解决。从这个角度看,内部类使得多重继承的解决方案变得完整。接口解决了部分问题,而内部类有效地实现了“多重继承”。也就是说,内部类允许你继承多个非接口类型(类或抽象类)。
考虑下面的这种情形,你必须在一个类中以某种方式实现两个接口。由于接口的灵活性,我们有两种选择:只使用单一的一个类;或者使用一个内部类。
// two ways that a class can implement mutiple interfaces
interface A{}
interface B{}
class X implements A, B{}
class Y implements A{
B makeB{
// Anonymous inner class
return new B(){};
}
}
public class MutiInterfaces{
static void takesA( A a ){}
static void takesB( B b ){}
public static void main( String[] args ){
X x = new X();
Y y = new Y();
takesA(x);
takesA(y);
takesB(x);
takesB( y.makeB() );//注意这里
}
}
通常遇到问题的时候,问题本身就能给出某些指引,告诉你应该使用单独一个类,或是使用内部类。
如果要继承的是抽象的类或具体的类,而不是接口,那么只能使用内部类才能实现多重继承。
class D{}
abstract class E{}
class Z extends D{
E makeE(){
return new E(){};
}
}
public class mutiImplementation{
static void takesD( D d ){}
static void takesE( E e ){}
public static void main( String[] args ){
Z z = new Z();
takesD(z);
takesE( z.makeE) );
}
}
从上面这个例子,我们可以看出,的确,如果继承的为非接口,要实现多继承,的确得用内部类了。
使用内部类,可以获得其他一些特性:
1 内部类可以有多个实例,每个实例都有自己的状态信息,并且与其外围类对象的信息相互独立。
2 在单个外围类中,你可以让多个内部类以不同的方式实现同一个接口,或继承同一个类。
3 创建内部类对象的时刻并不依赖于外围类对象的创建。
4 内部类并没有令人迷惑的”is a“ 关系;它就是一个独立的实体。举个例子,如果sequence.java不使用内部类,你就必须要声明”sequence 是一个 selector“,对于一个特定的sequence只能有一个selector。然而使用内部类你可以很容易地就拥有另一个方法getRselector(),用来生成一个反方向遍历序列的selector。只有内部类才有这种灵活性。