局部内部类
1、如何声明?
【修饰符】 class 外部类 【extends 父类】 【implements 父接口们】{
【修饰符】 返回值类型 **方法**名(【形参列表】){
【修饰符】 class 内部类 【extends 父类】 【implemends 父接口们】{
}
}
}
说明:局部内部类的修饰符
(1)权限修饰符:没有
(2)static没有
(3)abstract可以有
(4)final可以有
2、使用
(1)局部内部类有作用域
(2)局部内部类中是否能使用外部类的非静态成员变量,是要看所在的方法是否是静态的
(3)局部内部类可以使用所在方法的局部变量,但是该局部变量必须加final声明
如果在JDK1.8之前必须要手动加final
在JDK1.8之后,自动加final也就是默认是final
3、局部内部类也有字节码文件
外部类$数字内部类
4、成员
局部内部类中不能有静态的成员
public class TestLocalInner {
}
class Outer{
private static int i;
private int j;
public void outTest() {
int a = 10;// 局部变量
//a = 20;
class Inner{
public void test() {
System.out.println(i);
System.out.println(j);
System.out.println(a);
}
}
Inner in = new Inner();
in.test();
}//Inner的作用域只能到这里
public static void outMethod() {
class Inner{
public void test() {
System.out.println(i);
// System.out.println(j);//这里不能用j,是因为这个方法outMethod是静态方法
}
}
}
}
匿名内部类
1、声明格式
位置:在创建对象的位置
特点:一边声明类一边创建对象,匿名内部类只有唯一的对象
new 父类(【形参列表】){
};
new 接口(接口没有形参列表){
};
2、匿名内部类是一种特殊的局部内部类,凡是局部内部类的限制,匿名内部类都有
(1)在匿名内部类中使用外部类的方法的局部变量,需要加final修饰
(2)在匿名内部类中使用外部内部类的非静态成员变量,要受到所在方法的限制,
所在方法是静态的话,就不能使外部类的非静态的成员
3、字节码
外部类$数字.class
4、成员
不能有静态成员
5、匿名内部类没有名字,也没有修饰符
public class TestNoNameInner {
public static void main(String[] args) {
Object obj = new Object();//这个创建的是父类的对象
System.out.println(obj.getClass());//运行时类型
//匿名内部类,创建的是子类的对象
Object in = new Object() {
};
System.out.println(in.getClass());//运行时类型
//创建MyClass子类的匿名内部类的对象
//多态引用
MyClass my = new MyClass() {
@Override
public void test() {
// TODO Auto-generated method stub
System.out.println("子类重写父类的抽象方法");
}
};
my.test();//直接用my调用,应为子类重写了父类的方法,直接调用子类中重写的方法
MyClass my2 = new MyClass("有参构造") {
@Override
public void test() {
// TODO Auto-generated method stub
System.out.println("子类重写父类的抽象方法");
}
};
my2.test();
//创建MyInter的实现类的匿名内部类对象
//多态引用
MyInter my3 = new MyInter() {
@Override
public void test() {
// TODO Auto-generated method stub
System.out.println("实现接口的抽象方法");
}
};
my3.test();
}
}
abstract class MyClass{
private String info;
public MyClass() {
super();
}
public MyClass(String info) {
super();
this.info = info;
}
public abstract void test();
}
interface MyInter{
void test();
}
面试题
题目:
(1)用匿名内部类的形式创建一个Object的子类
(2)并且在子类中声明一个方法 public void test(){}
打印一句话
(3)调用这个方法
public class TestObject {
public static void main(String[] args) {
/* //多态引用,编译时,看父类
Object obj = new Object() {
public void test() {
System.out.println("XXX");
}
};
//这里也没有办法强转,因为子类是匿名的
obj.test();*/
//用匿名内部类的匿名对象.方法
new Object() {
public void test() {
System.out.println("XXX");
}
}.test();
}
}