概述:
1、成员内部类
2、静态嵌套类
3、方法内部类
4、匿名内部类
共性:
1、内部类是一个独立的类,在编译后内部类会被编译成一个独立的class文件,
但是一般这个class文件一般前面都会以外部类命名,之后跟着$。
类似, FunctionInnerClass$1Inner.class
2、内部类不能用普通的方式访问。内部类可以理解为外部类的一个成员,
因此内部类可以自由访问外部类的成员变量,无论是否是private。
下面分别来看看不同类型的内部类:
1、成员内部类
class Outer {
class Inner{}
}
编译此java,会产生两个class文件,Outer.class和Outer$Inner.class。
注意:成员内部类中不容许有静态的声明,因为成员内部类可以看成外部类的成员,如果此类并非静态,那么当然不可以
声明任何静态的。
如何访问成员内部类?——方法只有一个,那就是通过外部类的对象!这其中也分为两种情况。
A:从外部类的非静态方法中实例化内部类对象
class Outer
{
private int i = 10;
public void makeInner()
{
Inner in = new Inner();
in.seeOuter();
}
class Inner
{
public void seeOuter()
{
System.out.print(i);
}
}
}
似乎没有创建外部对象却也new了Inner类,但事实上我们可以想想如果不调用makeInner方法,也就无法创建
Inner。因此仍然会先创建外部类的对象。
B:从外部类的静态方法中实例化内部类对象
class Outer
{
private int i = 10;
class Inner
{
public void seeOuter()
{
System.out.print(i);
}
}
public static void main(String[] args)
{
Outer out = new Outer();
Outer.Inner in = out.new Inner();
//Outer.Inner in = new Outer().new Inner();
in.seeOuter();
}
}
还是那个规则,必须先创建外部类对象,然后才可以创建内部类。
成员内部类的this:
class Outer
{
class Inner
{
public void seeOuter()
{
System.out.println(this);
System.out.println(Outer.this);
}
}
}
2、方法内部类
class Outer
{
public void doSomething()
{
class Inner
{
public void seeOuter()
{
}
}
}
}
注意:
a、方法内部类只能在定义该内部类的方法中实例化,不可以在此方法外对其实例化。
b、方法内部类对象不能使用该内部类所在方法的非final局部变量。
因为方法的局部变量位于栈,只存在于该方法的生命期内。当一个方法结束,其栈结构被删除,
局部变量也就消失。但是该方法结束之后,在方法内创建的内部类对象可能仍然存在于堆中。
也就是,不能保存局部变量的存活期和方法内部类对象的一样长,因此内部类对象不能使用它们。
class Outer
{
public void doSomething()
{
final int a =10;
class Inner
{
public void seeOuter()、
{
System.out.println(a);
}
}
Inner in = new Inner();
in.seeOuter();
}
public static void main(String[] args)
{
Outer out = new Outer();
out.doSomething();
}
}
3、匿名内部类
a、继承方式的匿名内部类
class Car
{
public void drive()
{
System.out.println("Driving a car!");
}
}
class Test
{
public static void main(String[] args)
{
Car car = new Car(){
public void drive()
{
System.out.println("Driving another car!");
}
};
car.drive();
}
}
建立匿名内部类的关键是重写父类的一个或多个方法。
b、接口方式的匿名内部类
interface Vehicle
{
public void drive();
}
class Test
{
public static void main(String[] args) {
Vehicle v = new Vehicle(){
public void drive(){
System.out.println("Driving a car!");
}
};
v.drive();
}
}
接口方式的匿名内部类看似实在实例化一个接口,事实上,应该说是在实现一个接口。
c、参数方式的匿名内部类
class Bar
{
void doStuff(Foo f){}
}
interface Foo
{
void foo();
}
class Test
{
static void go()
{
Bar b = new Bar();
b.doStuff(new Foo(){
public void foo(){
System.out.println("foofy");
}
});
}
}
4、静态嵌套类
静态乔套类不属于内部类。因为内部类与外部类共享一种特殊关系,应该准确地说是对实例的
共享关系。而静态潜逃类则没有上述关系。它只是位置在另一个类的内部,也被称为顶级嵌套类。
静态的含义是该内部类可以向其他静态成员一样,没有外部类对象时,也是可以访问它。静态嵌套类
不能访问外部类的成员和方法。
class Outer
{
static class Inner{}
}
class Test
{
public static void main(String[] args){
Outer.Inner n = new Outer.Inner();
}
}