Java语言 - 嵌套类(nested class)

嵌套类(nested class)指被定义在一个类的内部的类。
嵌套类有四种:

  • 静态成员类
  • 非静态成员类
  • 局部类
  • 匿名类

除了静态成员类外的三种又被称为内部类。
嵌套类存在的目的是为外围类(enclosing class)提供服务。通常基于下列原因使用嵌套类。

  • 内部类的方法可以访问 外围类的的数据包括私有数据。
  • 内部类可以对同一包中的其他类隐藏起来。
  • 使用匿名内部类可以定义一个代码简洁的回调函数。
  • 实现多继承。
  • 避免修改接口而实现同一个类中两种同名方法的调用。

    使用嵌套类的好处可以命名控制和安全控制。

一. 如果一个嵌套类不需访问外围类的实例,可以定义为静态成员类。
静态成员类可以访问外围类的静态域和方法。
公有的静态嵌套类对象创建:

EnclosingClass.MemberClass clazz =  new EnclosingClass.MemberClass();

非公有的静态嵌套类,只能在外围类内部使用;通常实现一个接口,通过外围类的一个方法返回它的实例。例如 Collections类有个私有静态成员类:

static class UnmodifiableList<E> extends UnmodifiableCollection<E> implements List<E> {...};

public static <T> List<T> unmodifiableList(List<? extends T> list) {
    return (list instanceof RandomAccess ?
            new UnmodifiableRandomAccessList<>(list) :
            new UnmodifiableList<>(list));
}

二. 如果一个嵌套类需要访问外围类的实例,可以定义为非静态成员类。非静态成员类的实例拥有一个外围类实例的引用。
公有非静态成员类的对象创建:

EnclosingClass.MemeberClass clazz = new EnclosingClass().new MemeberClass(); 

私有的非静态成员类,只能在外围类内部使用;通常实现一个接口,通过外围类的一个实例方法返回它的实例。不能通过外围类的一个静态方法返回它的实例
例如 ArrayList 有一个私有的非静态成员类 Itr:

private class Itr implements Iterator<E> {...}
public Iterator<E> iterator() {
    return new Itr();
}

也可以通过enclosingInstance.new MemberClass()来创建一个非静态成员类的实例。

三. 局部内部类的作用域在方法内部。限定符只能是final or abstract。
和其他嵌套类一样,局部内部类可以访问外围类和方法本地变量。Java 7中, 只能访问final本地变量。

四. 匿名内部类。
只创建这个类的对象,没有类名,通常是实现一个接口。

Runnable runnable = new Runnable(){
    public void run(){
         System.out.println("Hi");
    };
};
new Thread(runnable).start();

示例: 如果一个类已有个方法,它需要实现一个接口,接口有同名方法,可以用嵌套类解决方法同名问题。

接口Incrementable 有一个方法increment();

interface Incrementable {
    void increment();
}

类 Callee 有同样的方法 increment()

class Callee {
    private int i = 0;
    void incr() {
        i++;
        System.out.println(i);
    }
    void increment() {
        System.out.println("MyIncrement.increment()");
    }
}

如果类Callee 需要实现 Incrementable 接口,将出现重复的increment()方法,可以使用嵌套类解决这个问题:

class Callee {
    private int i = 0;
    void incr() {
        i++;
        System.out.println(i);
    }
    void increment() {
        System.out.println("MyIncrement.increment()");
    }
    private class Closure implements Incrementable {
        public void increment() {
            incr();
        }
    }
    public Incrementable getCallBackReference() {
        return new Closure();
    }
    public static void main(String[] args) {
        Callee callee = new Callee();
        callee.increment();
        callee.getCallBackReference().increment();
    }
}

上面的例子就是内部类的Adapter模式。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值