一、背景
之前的所有类都有自己的名字,但是有时候如果某个接口的实现类(或者某个父类的子类)只需要使用一次,此时这样的类如果我们单独定义出来则需要单独为其创建一个“*.java”文件。那么感觉浪费,为了避免这样的浪费可以将这个只使用一次的类定义成匿名内部类直接在需要的地方使用。
如果要使用匿名内部类必须在抽象类或者接口的基础上实现。匿名内部类一般可以作为方法的参数传递,也可以在方法中直接定义。
也许初学者或者工作中很少用到匿名内部类,但是自从jdk1.8出现lambda表达式函数式编程,就需要理解匿名内部类啦。
二、概念
定义:匿名内部类其实就是没有名字的内部类
说明:在调用包含有接口类型参数的方法时,通常为了简化代码,可以直接通过匿名内部类的形式传入一个接口类型的参数,在匿名内部类中直接完成方法实现
三、抽象类实践
定义一个抽象类
public abstract class Animal {
public abstract void eat();
}
定义一个抽象类的子类
public class Dog extends Animal{
@Override
public void eat() {
System.out.println("狗吃肉");
}
}
匿名内部类实践
public static void main(String[] args) {
//定义实现类的写法
Dog dog=new Dog();
dog.eat();
//不定义实现类,匿名内部类写法
new Animal() {
@Override
public void eat() {
System.out.println("狗吃肉");
}
}.eat();
//整体就等效于:是Animal父类的子类对象
Animal animal = new Animal() {
@Override
public void eat() {
System.out.println("狗吃肉");
}
};
//调用eat
animal.eat();
}
四、匿名内部类访问局部变量
通过匿名内部类访问局部变量,在JDK8版本之前,必须加final关键字,JDK8及以后可以不加,默认给你带了final关键字,此后不能修改
public static void main(String[] args) {
//整体就等效于:是Animal父类的子类对象
//通过匿名内部类访问局部变量,在JDK8版本之前,必须加final关键字
String name = "路虎";
Animal animal = new Animal() {
@Override
public void eat() {
System.out.println(name + "在吃肉");
}
};
//调用eat
animal.eat();
}
五、接口实践
public interface Inter {
void method();
}
public static void main(String[] args) {
/* //匿名内部类写法
Inter inter = new Inter() {
@Override
public void method() {
System.out.println("我是重写后的method方法");
}
};
inter.method();
//lambda表达式实现
Inter inter1 = () -> System.out.println("我是重写后的method方法");
inter1.method();
((Inter) () -> System.out.println("我是重写后的method方法")).method();*/
//接口函数调用
function(new Inter() {
@Override
public void method() {
System.out.println("我是重写后的method方法");
}
});
//lambda简化
function(()->{
System.out.println("我是重写后的method方法");
}
);
}
public static void function(Inter i){
i.method();
}