5.1. 内部类
一般的调用形式如下:
内部类有如下几点特性:
- 在另一个类的定义内部被定义;
- 生成一个内部类的对象时,它就与生成它的外部类的对象产生一个关联;
- 内部类拥有其外围类所有元素的访问权;
- 内部类的对象只能在与其外围类对象相关联的情况下才能被创建;
import java.util.*;
interface CanDisplay {
void display();
}
public class Program {
private String content = "This is an Outer object.";
private class Inner implements CanDisplay {
@Override
public void display() {
System.out.println(content);
}
}
public Inner getDisplayer() {
return new Inner();
}
public static void main(String[] args) {
Program obj = new Program();
Inner displayer = obj.getDisplayer();
displayer.display();
}
}
5.2. .this
与 .new
.this
用于在内部类中获取外部类的引用:
class Outer {
public class Inner {
public Outer outer() {
return Outer.this;
}
}
public Inner inner() {
return new Inner();
}
}
.new
基于一个外部类的对象创建一个与其关联的内部类对象:
class Outer {
public class Inner {}
}
public class Program {
public static void main(String[] args) {
Outer outer = new Outer();
Outer.Inner inner = outer.new Inner();
}
}
5.3. 使用 private 内部类实现接口以隐藏实现
可以在内部类中实现一个接口,然后在外部类的方法中通过这个接口类型返回内部类的引用。
这种情况下,内部类对使用者是完全隐藏的,但是可以通过这种方式来获取满足特定接口的内部对象引用。
import java.util.*;
interface CanDisplay {
void display();
}
class Outer {
private String content = "This is an Outer object.";
private class Inner implements CanDisplay {
@Override
public void display() {
System.out.println(content);
}
}
public CanDisplay getDisplayer() {
return new Inner();
}
}
public class Program {
public static void main(String[] args) {
Outer obj = new Outer();
CanDisplay displayer = obj.getDisplayer();
displayer.display();
}
}
5.4. 在函数及任意作用域中定义内部类
这种情况,内部类会被编译,但是在作用域(花括号)之外,不能调用。
这个类不能被调用,但是如果这个内部类实现了接口并且返回,则对象仍然是存在的。
细节略。
5.5. 匿名内部类
如果有这样一种定义:
import java.util.*;
class Base {
int content;
public Base(String s) {
content = s;
}
};
public class Program {
class Inner extends Base {
private int i = 11;
private String str;
public Inner(String s) {
str = s;
}
public int value() { return i; }
}
public Base inner(String s) {
return new Inner(s);
}
public static void main(String[] args) {
Program outer = new Program();
Base inner = outer.inner("Hello");
}
}
我们可以用如下的匿名内部类的写法这样来写:
import java.util.*;
class Base {
int content;
public Base(String s) {
content = s;
}
};
public class Program {
public Base inner(String s) {
return new Base(s) {
private int i = 11;
private String str;
public int value() { return i; }
{ // 内部实例初始化
str = s;
}
};
}
public static void main(String[] args) {
Program outer = new Program();
Base inner = outer.inner("Hello");
}
}
这种情况是直接返回一个匿名类的对象,这个类没有名字,继承于 Base,而且是立即定义之后做返回的,而且返回时被向上转型为其基类 Base。
如果这个匿名内部类继承时调用一个带参数的构造函数,直接在 new 后面的基类(或接口)按照其接口签名返回即可。
5.6. 嵌套类(静态内部类)
如果一个内部类加上 static 修饰,这就是一个静态内部类,又称嵌套类。
嵌套类的对象本身与外部类的对象本身不存在前面描述的关联性。
这种情况下,无法通过 Outer.this
的方法获取外部的成员变量。
5.7. 接口内部的类
在接口内部可以放置内部类(可以实现外部接口本身);
接口内部类是自动 public static 的,因此这个内部类属于一个嵌套类。
可以使用这种方法来为接口定义一个实现,并且加入 main 方法用于测试。
5.8. 内部类的继承
如果要继承内部类,需要特殊的语法以确认其与外部类对象之间的关联:
class WithInner {
class Inner {}
}
public class InheriInner extends WithInner.Inner {
// 注意其构造函数需要传入外部类的对象进行初始化
IneritInner(WithInner wi) {
wi.super();
}
public static void main(String[] args) {
WithInner wi = new WithInner();
InheritInner ii = new InheritInner(wi);
}
}
5.9. 内部类的覆盖
如果外部类被派生,其内部类不会发生改变。
TODO: 详细暂且略过
5.10. 局部内部类
TODO: 略
【转载请附】愿以此功德,回向 >>
原文链接:http://www.huangwenchao.com.cn/2015/02/java-cheatsheet-5.html【Java cheatsheet (V)】