内部内的使用和Lambda表达式

本文介绍Java中的匿名内部类概念及其应用场景,并通过示例对比匿名内部类与Lambda表达式的使用方式,展示了如何利用Lambda表达式简化代码。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

os:内部内的重点是匿名内部内,成员内部内和局部内部内比较简单,就不陈述了。

匿名内部类

谁没有名字:匿名内部类指的是接口的实现类 或者 抽象类的子类没有名字。
前提:
    1)必须要有一个接口、抽象类(普通类也可以,但是方法不会强制重写,不建议)
    2)格式:
        new 接口/抽象类(){
            //复写抽象方法
        }
    3)本质:匿名内部类的本质其实是一个接口的实现类【对象】,或者抽象类的子类【对象】。

public abstract class Animal {
    public abstract void eat();
} 


public class Demo2 {
    public static void main(String[] args) {
        //创建Animal的子类对象
        new Animal(){
            @Override
            public void eat() {
                System.out.println("狗吃骨头");
            }
        }.eat();

        //Animal a接收Animal的子类对象。 这是多态的体现
        Animal a = new Animal(){
            @Override
            public void eat() {
                System.out.println("狗吃骨头");
            }
        };

        a.eat();
        a.eat();
    }
}

匿名内部类的实际运用

使用场景:
    在实际运用中,如果方法的参数是父类类型,那么调用方法时可以传递子类对象,但是为了图省事不想写子类,那么这个时候可以使用匿名内部类。

public class Demo2 {
    public static void main(String[] args) { 
        //调用方法,传递Animal子类对象
        feed(new Animal() {
            @Override
            public void eat() {
                System.out.println("够吃骨头");
            }
        });

        //调用方法,传递Animal子类对象
        Animal a = new Animal() {
            @Override
            public void eat() {
                System.out.println("猫吃鱼");
            }
        };
        
        feed(a); 
    }

    //养动物
    public static void feed(Animal a){
        a.eat();
    }
} 

综合案例

1.写一个Usb接口,要求有通电、加载驱动程序、运行三个方法。
2.定义一个UseMouse鼠标类,实现Usb接口,复写三个方法
3.定义一个UsbKeyBoard键盘类,实现Usb接口,复写三个方法
4.写一个Computer电脑类,定义一个useUsb的方法,要求既能接收鼠标也能接收加键盘
    把Usb作为方法的参数即可
    
5.写一个测试类,创建电脑对象,调用useUsb方法

//定义一个USb的接口:

//相当于指定了一个规则
public interface Usb {
    public void power();
    public void loadDriver();
    public void run();
}

        

//定义鼠标的类

public class UsbMouse implements Usb {
    @Override
    public void power() {
        System.out.println("鼠标通电");
    }

    @Override
    public void loadDriver() {
        System.out.println("加载鼠标的驱动程序");
    }

    @Override
    public void run() {
        System.out.println("鼠标运行");
    }
}

public class UsbKeyBoard implements Usb {
    @Override
    public void power() {
        System.out.println("键盘通电");
    }

    @Override
    public void loadDriver() {
        System.out.println("加载键盘的驱动程序");
    }

    @Override
    public void run() {
        System.out.println("键盘运行");
    }
}

public class Computer {
    //使用Usb接口,
    //对于电脑来说,并不关心具体是哪一个外接的设备。
    // 只要符合Usb规范都可以的
    public void useUsb(Usb u){
        u.power();
        u.loadDriver();
        u.run();
    }
}

//测试类

public class Demo4 {
    public static void main(String[] args) {
        //创建电脑对象
        Computer com = new Computer();

        //创建鼠标对象
        UsbMouse mouse = new UsbMouse();
        //调用电脑的方法,把鼠标传进去
        com.useUsb(mouse);

        System.out.println("--------------------");

        UsbKeyBoard keyBoard = new UsbKeyBoard();
        com.useUsb(keyBoard);

        System.out.println("--------------------");
        //让电脑使用U盘
        com.useUsb(new Usb() {
            @Override
            public void power() {
                System.out.println("U盘通电");
            }

            @Override
            public void loadDriver() {
                System.out.println("U盘加载驱动程序");
            }

            @Override
            public void run() {
                System.out.println("U盘运行");
            }
        }); 
    }
}

Lambda表达式

在JDK8以前,使用匿名内部类时,受限于语法格式,必须创建父类\接口的子类对象,再复写抽象方法,这系列动作比较繁琐。从JDK8之后使用Lambda表达式可以对匿名内部类进行简化。

使用Lambda的步骤

Lambda表达式的使用是由条件的,必须要有一个【函数式接口】,在接口中只能有一个抽象方法。

@FunctionalInterface    //标记这个接口是函数式接口
public interface Inter{
    public void show();
}

再写一个方法,把方法的参数写成函数式接口,调用方法时就可以传递Lambda表达式

public class Demo5{
    public static void main(String[] args){
        //匿名内部类写法
        method(new Inter(){
            public void show(){
                System.out.println("Inter的show方法执行了");
            }
        });
        
        //Lambda表达式
        method(
            ()->{
                System.out.println("Inter的show方法执行了");
            }
        );
    } 
    
    //把方法的参数写成函数式接口
    public static void method(Inter in){
        in.show();
    }
}

Lam

bda表达式的格式

//1. Lambda标准格式
(参数类型1 参数名1,参数类型2 参数名2) -> {    方法体; return 返回值;    } 

//2. Lambda省略格式,省略参数数据类型
(参数名1,参数名2) -> {    方法体; return 返回值;    } 

//3. Lambda省略格式,{}中的代码只有一条语句,那么大括号可以省略、rerturn和分号都要省略
(参数名1,参数名2) ->   返回值    
    
//4. Lambda省略格式,参数只有一个时,()可以省略
参数名 ->   返回值 

-----------------------------------------------

Lamdba案例

定义一个函数式接口Inter

public interface Inter {
    public void printMsg(String s);
}

在测试类中定义一个使用函数式接口的方法method,并测试类中调用方法method,分别按照匿名内部类、Lambda表达式标准写法、Lambda省略写法传递参数。

public class Demo8 {
    //把Inter作为方法的参数
    public static void method(Inter in){
        in.printMsg("想你的夜");
    }
    
    public static void main(String[] args) {
        //调用方法,传递匿名内部类
        method(new Inter() {
            @Override
            public void printMsg(String s) {
                System.out.println(s);
            }
        });

        //调用方法,传递Lambda表达式,标准格式
        method((String s)-> {
                System.out.println(s);
            }
        );

        //调用方法,传递Lambda表达式,省略数据类型
        method((s)-> {
            System.out.println(s);
        });

        //调用方法,传递Lambda表达式,省略大括号
        method((s)-> System.out.println(s));

        //调用方法,传递Lambda表达式,省略参数的小括号
        method(s -> System.out.println(s));
        
        //扩展:当Lambda表达式所做的事情,正好可以用一个方法来代替时。
        //可以使用方法引用,可以认为是省略了Lamdab的参数
        //格式:【对象名::方法名】  或者  【类名::方法名】
        method(System.out::println); 
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值