内部类的作用
Java是单继承,它通过接口实现了多重继承。当只有抽象类或具体类,而没有接口时,可以用匿名内部类实现多重继承。
内部类分类
- 普通内部类
- 匿名内部类
- 嵌套类
匿名内部类
public class Demo {
prvivate int n;
public E make() {
return new E() {...};
}
}
make方法的return语句意为:根据方法体实例化对象,然后将其向上转型为基类E的引用。
如果我们要在匿名内部类的方法体内部使用外部类的成员引用,则必须将此引用用final
修饰。
通过匿名内部类实现多重继承与接口有所差异:通过多个接口继承产生的实例化对象可以向上转型为多个目标接口;而匿名内部类产生的实例化对象只能向上转型为一个基类引用。即通过匿名内部类的多重继承是一个子类对一个基类,接口则是一个子类对多个接口。
嵌套类
用static声明的内部类,这通常称为嵌套类。
创建嵌套类对象不需要其外围类的对象;不能从嵌套类的对象中访问非静态的外围类对象。
声明和创建
当在外围类的静态方法或者外围类之外调用new
操作符创建内部类对象时,必须先创建外围类,然后OuterInstanceName.new Inner()
创建内部类对象。
当在外围类之外声明内部类引用时,必须指定具体类型为OuterClassName.InnerClassName
下面是代码测试:
在Parcle.java文件中,Parcle类是外围类,Inner是内部类。在外围类中可以直接用InnerClassName
声明内部类对象,在非静态方法里也可以直接用new Inner()
创建内部类对象。
public class Parcle {
private String name;
public Parcle(String name) {
this.name = name;
}
public Parcle() {
this("unName");
}
class Inner {
public void value() {
System.out.println(name);
}
}
public Inner to() {
return new Inner();
}
public void print() {
Inner inner = new Inner();
inner.value();
}
/*
public static void print2() {
Parcle parcle = new Parcle("hello");
// Inner inner = parcle.new Inner();
Inner inner = parcle.to();
inner.value();
}*/
public static void main(String[] args) {
// 构建内部类对象时,需要一个指向其外围类对象的引用,如果编译器访问不到这个引用就会报错。
// 错误的创建方式
// Parcle.Inner inner = new Inner();
Parcle parcle = new Parcle("OuterClassName.InnerClassName格式声明内部类引用");
Parcle.Inner inner = parcle.new Inner();
inner.value();
Parcle parcle1 = new Parcle("InnerClassName格式声明内部类引用");
Inner inner1 = parcle1.new Inner();
inner1.value();
Parcle parcle2 = new Parcle("OuterClassName.InnerClassName格式声明内部类引用");
Parcle.Inner inner2 = parcle2.to();
inner2.value();
Parcle parcle3 = new Parcle("InnerClassName格式声明内部类引用");
Inner inner3 = parcle3.to();
inner3.value();
}
}
在Test.java文件里,创建一个Test类。在Test类里必须用OuterClassName.InnerClassName
声明内部类引用,OuterInstanceName.new Inner()
创建内部类对象。
public class Test {
public void print() {
Parcle parcle1 = new Parcle("外围类之外创建内部类对象,情况一");
// 错误的声明方式
// Inner inner = parcle.new Inner();
// 正确的声明方式
Parcle.Inner inner1 = parcle1.new Inner();
inner1.value();
Parcle parcle2 = new Parcle("外围类之外创建内部类对象,情况二");
Parcle.Inner inner2 = parcle2.to();
inner2.value();
}
public static void main(String[] args) {
Parcle parcle = new Parcle();
Parcle.Inner inner = parcle.new Inner();
inner.value();
new Test().print();
}
}