内部类使用方法
在外部类内部使用内部类
与平常使用普通类一样,但是只要注意:不要在外部类的静态成员(包括静态方法和静态初始化块)中使用非静态内部类。
在外部类以外使用非静态内部类
在外部类以外的地方定义内部类(包含静态和非静态两种)变量的格式如下:
OuterClass.InnerClass varName
在外部类以外的地方创建非静态内部类实例变量的格式如下:
OuterInstance.new InnerConstructor()
创建非静态内部类的子类时,必须保证让子类构造器可以调用非静态内部类的构造器,所以必须存在一个外部类对象
public class SubClass extends Out.In
{
public SubClass(Out out)
{
out.super("hello")
}
}
在外部类以外使用静态内部类
在外部类以外地方创建静态内部类实例的语法格式
new OuterClass.InnerConstructor()
局部内部类
把内部类放在方法里定义,则这个内部类就是一个局部内部类。
局部成员(包含局部方法和局部内部类)上一级为方法,所以使用static修饰没有任何意义。且局部成员作用域为方法,所以也无法从其他程序单元调用另一个方法内的局部变量,因此局部成员也就没有访问控制修饰符。
public class LocalInnerClass
{
public static void main(String[] args)
{
// 定义局部内部类
class InnerBase
{
int a;
}
// 定义局部内部类的子类
class InnerSub extends InnerBase
{
int b;
}
}
编译时,会产生3个.class文件,LocalInnerClass.class、LocalInnerClass
1InnerBase.class和LocalInnerClass
1InnerSub.class
局部内部类的class文件的文件名比成员内部类的class文件名多一个数字,是因为同一个类中可能有两个以上同名的内部类(处于不同方法中)
匿名内部类
匿名内部类适合创建只需要一次使用的类
格式:
new 实现接口() | 父类构造器(实参列表)
{
//匿名内部类的类体部分
};
匿名内部类必须继承一个父类,或实现一个接口,且最多只能实现一个。
有以下规则:
1. 匿名内部类不能是抽象类
2. 匿名内部类不能定义构造器
interface Product
{
public double getPrice();
}
publci static void main(String[] args)
{
Product p = new Product()
{
publci double getPrice()
{
return 500.8;
}
}
}
创建匿名内部类时,必须实现接口或抽象父类里的所有抽象方法
如果局部变量被匿名内部类访问,那么该局部变量相当于自动使用final修饰。
nterface A
{
void test();
}
public class ATest
{
public static void main(String[] args)
{
int age = 8;
// 由于age局部变量被匿名内部类访问了,因此age相当于被final修饰了
A a = new A()
{
public void test()
// 从Java 8开始,匿名内部类、局部内部类允许访问非final的局部变量
System.out.println(age);
}
};
}
}