一.成员内部类
在一个类中使用内部类,可以在内部类中直接存取所在其所在类的私有成员变量
语法:
public class OuterClass{
private class InnerClass{
//...
}
}
在内部类中可以随意使用外部的成员方法以及成员变量,尽管这些类成员被修饰为private.
内部类一定要绑定在外部类的实力上,如果从外部类中初始化一个内部类对象,那么内部类对象就会绑定在外部类对象上.
public class OuterClass{
innerClass in=new innerClass();//在外部类实例化内部类对象引用
public void ouf(){
in.inf();//在外部类方法中调用内部方法
}
class innerClass{
innerClass(){//内部类构造方法
}
public void inf(){//内部类成员方法
}
int y=0;//定义内部类成员变量
}
public innerClass doit(){//外部类方法,返回直接值为内部类引用
in.y=4;
return new innerClass();//返回内部类引用
}
public static void main(String args[]){
OuterClass out=new OuterClass();
//内部对象实例化操作必须在外部或外部类的非静态方法中实现
OuterClass.innerClass in=out.doit();
OuterClass.innerClass2=out.new innerClass();
}
}
注意
1.如果在外部类和非静态方法之外实例化内部类对象,需要使用外部类.内部类的形式指定该对象的类型.
2.内部类对象会依赖于外部类对象,除非已经存在一个外部类对象,否则类中不会出现内部类对象.
内部类向上转型为接口
如果一个权限修饰符为private的内部了向上转型为其父类对象,或者直接向上转型为一个接口,在程序中就可以完全隐藏内部类的具体实现过程.可以在外部提供一个接口,在接口中声明一个方法.
package com.java;
interface OutInterface{//定义一个接口
public void f();
}
public class InterfaceInner{
public static void main(String args[]){
OuterClass2 out=new OuterClass2();//实例化一个OuterClass2对象
//调用doit()方法,返回一个OuterInterface接口
OutInterface outinter=out.doit();
outinter.f();//调用f()方法
}
}
class OuterClass2{
//定义一个内部类实现OutInterface接口
private class InnerClass implements OutInterface{
InnerClass(String s){//内部类构造方法
System.out.println(s);
}
public void f(){//实现接口中的f()方法
System.out.println("访问内部类中的f()方法");
}
}
public OutInterface doit(){//定义一个方法,返回值类型为OutInterface接口
return new InnerClass("访问内部构造方法");
}
}
注意:非内部类不能被声明为private或protected访问类型
使用this关键字获取内部类与外部类的引用
如果在外部类中定义的成员变量与内部类的成员变量名称相同,可以使用this关键字.
public class TheSameName{
private int x;
private class Inner{
private int x=9;
public void doit(int_x){
x++;//调用的是形参x
this.x++;//调用内部类的变量x
TheSameName.this.x++;//调用外部类的变量x
}
}
}
局部内部类
内部类不仅可以在类中进行定义,还可以在类的几部位置定义,如在类的方法或任意的作用域中均可以定义内部类.
interface OutInterface2{//定义一个接口
}
class OuterClass3{
public OutInterface2 doit(final String x){//doit()方法参数为final类型
//在doit()方法中定义一个内部类
class InnerClass2 implements OutInterface2{
InnerClass2(String s){
s=x;
System.out.println(s);
}
}
return new InnerClass("doit");
}
}
匿名内部类
class OuterClass4{
public OutInterface2 doit(){//定义doit()方法
return new OutInterface2(){//声明匿名内部类
private int o=0;
public int getValue(){
return i;
}
};
}
}
说明:匿名内部类编译以后,会产生以”外部类名$序号”为名称的.class文件,序列号以1~n排列,分别代表1~n个匿名内部类.
静态内部类
在内部类前面加修饰符static,这个内部类就变成了静态内部类了.
1.如果创建静态内部类的对象,不需要其外部类的对象
2.不能从静态内部类的对象中访问非静态外部类的对象
public class StaticInnerClass{
int x=100;
static class Inner{
void doitInner(){
}
public static void main(String args[]){
System.out.println("a");
}
}
}
内部类的继承
内部类跟其他的普通类一样可以被继承,但是继承内部类比继承普通类复杂,需要设置专门的语法来完成.
public class OutputInnerClass extends ClassA.ClassB{//继承内部类ClassB
public OutputInnerClass(ClassA a){
a.super();
}
}
class ClassB{
class ClassB
}