java 内部类
/**个人理解,如果发现有不当之处,还请谅解并告知*/
将一个类的定义放在另一个类的定义内部,就是内部类。内部类一般分以下几种
1.普通内部类
1)
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
public class OuterClass { class Inner{ private String name; Inner(String input){ this.name = input; } } public static void main(String[] args) { OuterClass outerClass = new OuterClass(); Inner inner = outerClass.new Inner("this is inner"); System.err.println(inner.name); } }
注:创建内部类对象的方法是使用 ".new" 来进行,在拥有一个外部类对象之前,是不能创建内部类 对象的 。
内部类主要用以隐藏名字和组织代码,此外,当用OuterClass创建Inner对象时,该对象会隐秘的获取一个指向OuterClass的引用,因此,创建的内部类对象会自动拥有外部类所有成员的访问权。
2)常用于隐藏实现
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
public class OuterClass { public SuperInterface superInterface(String words) { class Inner implements SuperInterface { private String greeting; private Inner(String outerGreeting){ this.greeting = outerGreeting; } @Override public String sayHello() { return greeting; } } return new Inner(words); } public static void main(String[] args) { OuterClass outerClass = new OuterClass(); SuperInterface superInterface = outerClass.superInterface("Here you are"); System.err.println(superInterface.sayHello()); } } interface SuperInterface{ String sayHello(); }
2.匿名内部类
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
public class OuterClass { public SuperInterface superInterface(String words){ return new SuperInterface(){ private String greeting = words; @Override public String sayHello() { System.err.println("inner"+greeting); return greeting; } }; } public static void main(String[] args) { OuterClass outerClass = new OuterClass(); SuperInterface superInterface = outerClass.superInterface("Hello"); System.err.println(superInterface.sayHello()); } } interface SuperInterface { String sayHello(); }
匿名内部类是指创建一个继承/实现自另一个外部类的匿名对象,并通过向上转型返回一个对外部类的引用,如上面代码所示,通过new生成一个实现了SuperInterface的匿名类对象的引用,然后自动向上转型为指向SuperInterface的引用。
注:java8之前,如果匿名内部类需要使用一个外部定义的对象(如上面代码中的入参words),会要求参数必须为final类型的,java8之后,会自动的声明为隐式的final类型。
3.嵌套类
嵌套类又称为静态内部类,和普通内部类不同的是,嵌套类不需要内部类对象与其外围对象有联系,只需要将类声明为static。
1)创建嵌套类对象并不需要其外部对象
2)不能从嵌套类对象访问非静态外部类对象
3)嵌套类可以作为接口的一部分
例
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
public interface ClassInterface { void sayHello(); class ClassImpl implements ClassInterface{ @Override public void sayHello() { System.err.println("Hello"); } public static void main(String[] args) { new ClassImpl().sayHello(); } } }
由于匿名内部类允许继承多个非接口类型(抽象类,类),使得 多重继承 得以实现。
和内部类相关的其他概念:
1.闭包(Closure)
闭包又叫词法闭包(Lexical Closure)或函数闭包(Function Closure)
概念一:闭包就是能够读取其他函数内部变量的函数;
概念二:闭包是引用了自由变量的函数;
因此,Java中的内部类就可以看做是一个闭包,因为内部类能够访问外部类的所有变量(相当于自由变量);
java中常用的迭代器模式就是应用内部类来实现的,例:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
public class Sequence { /** * 保存数据 */ private Object[] items; private int next = 0; /** * 初始化数组 */ public Sequence(int size) { items = new Object[size]; } /** * 添加数据 */ public void add(Object data){ if(next<items.length){ items[next++] = data; } } private class SequenceSelector implements Selector { private int i; /** * 如果不在末尾,计数器加1 */ @Override public void next() { if (i < items.length) { i++; } } /** * 是否在末尾 */ @Override public boolean end() { return i == items.length; } /** * 返回当前对象 */ @Override public Object current() { return items[i]; } } public Selector selector(){ return new SequenceSelector(); } public static void main(String[] args) { Sequence sequence = new Sequence(10); for (int i = 0; i < 10; i++) { sequence.add(Integer.toString(i)); } Selector selector = sequence.selector(); while (!selector.end()){ System.err.print(selector.current()+","); selector.next(); } } } interface Selector { void next(); boolean end(); Object current(); }
ps小王知识点:过了很久终于我愿抬头看,你就对面敲打键盘