Java 中引入内部类的意义?

关注者
699
被浏览
82,737

24 个回答

题目问的是内部类,结果答案都是匿名类,,,,


首先说内部类的意义,事实上很多面向对象的语言都支持内部类,例如C#。一般来说内部类常见的场景就是搭桥,例如.NET里面几乎所有的IEnumerator的实现全部都是内部类实现的。这是因为一般来说容器的枚举器需要访问容器的私有成员才能正常工作,而如果容器直接实现IEnumerator接口,又难以实现并发枚举。内部类是这种场景的绝佳方案。


而Java因为木有闭包、木有委托、木有事件等等一切让程序员写代码更爽的东西,所以内部类的意义更为重大。

本质上委托类型和只有一个方法的接口是等价的,虽然C#里面的委托类型木有这么定义,但是Java后来打的lambda的补丁就是把只有一个方法的接口当委托使。一个public方法的委托实例很好做,但是一个private方法的委托实例要如何实现呢?自然是内部类就好了,,,



至于Java的匿名类则是Java语言绝无仅有的语法糖之一,不过题目问的是内部类,你们都回答匿名类干嘛?匿了,,,,

1.完善多重继承

  1. C++作为比较早期的面向对象编程语言,摸着石头过河,不幸的当了炮灰。比如多重继承,Java是不太欢迎继承的。因为继承耦合度太高。比如你是一个人,你想会飞,于是就继承了鸟这个类,然后你顺便拥有了一对翅膀和厚厚的羽毛,可这些玩意你并不需要。所以Java发明了接口,以契约的方式向你提供功能。想想看,你的程序里成员变量会比函数多吗?况且多重继承会遇到死亡菱形问题,就是两个父类有同样名字的函数,你继承谁的呢?其实C++也可以做到这些,那就是定义没有成员变量的纯虚类,而且所有函数都是纯虚函数。可是这些都是要靠程序员自己把握,并没有把这些功能集成到类似Interface这样的语法里。
  2. 所以Java只支持单重继承,想扩展功能,去实现接口吧。很快Java的设计者就发现了他们犯了矫枉过正的错误,多重继承还是有一定用处的。比如每一个人都是同时继承父亲和母亲两个类,要不然你的身体里怎么能留着父母的血呢?Java内部类应运而生。

2.实现事件驱动系统

  1. 用来开发GUI的Java Swing使用了大量内部类,主要用来响应各种事件。Swing的工作就是在事件就绪的时候执行事件,至于事件具体怎么做,这由事件决定。这里面有两个问题:1.事件必须要用到继承2.事件必须能访问到Swing。所以必须把事件写成内部类。

3.闭包。

  1. 内部类是面向对象的闭包,因为它不仅包含创建内部类的作用域的信息,还自动拥有一个指向此外围类对象的引用,在此作用域内,内部类有权操作所有的成员,包括private成员。一般使用一个库或类时,是你主动调用人家的API,这个叫Call,有的时候这样不能满足需要,需要你注册(注入)你自己的程序(比如一个对象),然后让人家在合适的时候来调用你,这叫Callback。

  2. 当父类和实现的接口出现同名函数时,你又不想父类的函数被覆盖,回调可以帮你解决这个问题。

    本帖主要参考了《Thinking in Java》关于内部类的讲解以及13、内部类(闭包与回调)