1.内部类
1.1内部类的限制
a.在外部类的非静态方法之外的任何位置创建内部类的对象的时候,不能直接调用内部类的构造函数,而是应该借助外部类的对象进行对象的创建
b.不能含有static函数(这里不包含嵌套类)
1.2内部的特权
a.内部类可以直接使用外部类的所有属性(包含static属性)
b.内部类可以被private修饰,这样的话内部类就只能在外部类中进行使用,在一般的类中就不能使用。
1.3创建内部类对象
条件---必须依赖外部类对象(除了嵌套类),这也是为什么内部类可以访问外部类属性的原因(内部类包含一个外部类的引用)
非静态内部类对象有着指向其外部类对象的引用
外部类中
a.静态函数---利用this,直接创建内部类对象
b.非静态函数-先创建外部类对象,再创建内部类对象
一般类中
a.先创建外部类对象,再创建内部类对象
1.4.几种特殊的内部类
a.局部内部类
---1)函数内部
只能在函数内部使用,若要在外部使用,必须实现接口,向上转型
public static Myinterface g(){ class Inner1 implements Myinterface{ private String label="yangyun"; @Override public String toString(){ return String.format(""+label); } } return new Inner1(); }
}
---2).代码内部---if语句中
b.匿名内部类--利用接口或者是父类(没有构造函数)
interface Content{int value();} public Content getContent(){ return new Content(){ int num=100; public int value(){ return num*10; } }; }
c.嵌套内部类---静态内部类
静态内部类的特征
1.创建嵌套类对象的时候并不需要创建外部类的对象--(一般的内部类必须借助外部类的对象)
2.不能使用外部类的非静态属性
3.普通的内部类中不能包含static字段,嵌套类就可以
1.5传入内部类中的参数必须是final的--重点
注意:只是局部变量必须是final,一般的外部类属性不必是final的
public Myinterface f(final String m){ return new Myinterface(){ private String name=m; }; }
原因
- 通过反编译可以知道,传入的变量拷贝了一份被内部类使用
- 为了保证数据的一致性,要求传入的数据必须是final
1.7 接口中能不能有内部类
可以有嵌套类---接口中的属性,必须是public、static、final的
interface Myinterface{ class MyInner{ private String info="ABC"; @Override public String toString(){ return info; } } }
1.8回调与闭包
- 闭包
- 从字面上很难理解闭包什么玩意,闭包是一个可调用对象,包含了一些创建该对象的作用域中的信息(就是外部类对象的引用),从这个定义来看,内部类就是Java的闭包,js中是通过内部函数进行实现的,Java中必报的实现方式就是内部类。
- 回调
- 回调就是内部类调用外部类函数的过程,利用外部类的引用
1.9内部类的总结
java中的内部类和接口加在一起,可以解决常被C++程序员抱怨java中存在的一个问题——没有多继承。实际上,C++的多继承设计起来很复杂,而java通过内部类加上接口,可以很好的实现多继承的效果,内部类可以嵌套很多层。
参考文献
http://progress.iteye.com/blog/582460
http://lovejavaei.iteye.com/blog/401167
http://flowercat.iteye.com/blog/33371
http://blog.csdn.net/yu422560654/article/details/7001797