可以将一个类的定义放在另一类的定义内部,这就是内部类。
使用内部类的原因
- 内部类可以有多个实例,每个实例都有自己的状态信息,并且其外围类对象的信息相互独立
- 在单个外围类中,可以让多个内部类以不同的方式实现一个接口,或继承同一个类。
- 创建内部类对象的时刻并不依赖于外围类对象的创建。
- 内部类并没有令人迷惑的“is-a”关系,它是一个独立的实体
创建内部类
- 如果想从外部类的非静态方法之外的任意位置创建某个内部类的对象,那么必须具体地指明这个对象的类型Fu.Inner。
链接到外部类
- 内部类能访问其外部对象的所有成员,不需要任何特殊条件。
- 内部类还拥有外部类的所有元素的访问权。
- 当某个外部类对象创建了一个内部类对象时,此内部类对象必定会秘密地捕获一个指向那个外围类对象的引用。当你访问此外围类的成员时,就是用那个引用来选择外围类的成员。
使用this和new
- 在拥有外部类对象之前是不可能创建内部类对象的。这是因为内部类对象会暗暗
地连接到创建它的外部类对象上。
public class DotNew{
class InnerClass{
public DotNew outer() {
return DotNew.this;
}
}
public InnerClass inner() {
return new InnerClass();
}
public static void main(String[] args) {
DotNew d = new DotNew();
DotNew.InnerClass in = d.inner();
}
}
内部类与向上转型
在方法和作用域内的内部类
匿名内部类
- 如果定义一个匿名内部类,并且希望它使用一个在外部定义的对象,那么编译器会要求其参数是final的,否则会得到一个编译时错误。
- 优先使用类而不是接口。如果涉及中需要某个接口,必须了解它。
abstract class Base{
public Base(int i) {
System.out.println("Base Constructor,i = " + i);
}
public abstract void f();
}
public class AnonymousConstructor {
public static Base getBase(int i) {
return new Base(i) {
{
System.out.println("Inside instance initializer");
}
@Override
public void f() {
// TODO Auto-generated method stub
System.out.println("In anonymous f()");
}
};
}
public static void main(String[] args) {
Base base = getBase(47);
base.f();
}
}
嵌套类
- 如果不需要内部类对象与其外围对象之间有联系,那么可以将内部类声明为static,通常称为嵌套类。(普通的内部类对象隐式地保存了一个引用,指向创建它的外围类对象)
- 接口内部的内部类
- 从多层嵌套类中访问外部类的成员
为什么使用内部类 (模模糊糊)
- 应用程序框架就是被设计用以解决某类特定问题的一个类或一组类
控制框架
- 控制框架的完整实现是由单个的类创建的,从而使得实现的细节被封装了起来。内部类用来表示解决问题所必须的各种不同的action();
- 内部类能够很容易地访问外围类的任意成员,所以可以避免这种实现变的笨拙。
内部类的继承
class WithInner{
class Inner{}
}
public class InheritInner extends WithInner.Inner{
InheritInner(WithInner w){
w.super();
}
public static void main(String[] args) {
WithInner wi = new WithInner();
InheritInner li = new InheritInner(wi);
}
}
网友评论