Java SE 入门到精通—5.内部类与匿名类【Java】

本文详细介绍了Java中的内部类、静态内部类、局部内部类、匿名内部类以及lambda表达式,探讨了它们的特点、访问权限、作用和使用场景,强调了封装性和简化接口实现的过程。
摘要由CSDN通过智能技术生成

内部类

内部类可以访问外部类所有成员,包括私有

外部类访问内部类必须创建内部类对象访问

特点:

内部类具有类的基本特征

内部类无法被其他类访问(即使在同一个包中),只能被其外部类访问

内部类的属性类似成员属性

内部类可以访问外部类的所有成员(私有,静态等等)

内部类同样可继承,重载,重写,this,super

内部类可以无限套娃

需要依赖外部类的内部类都不能有静态成员,局部内部类也不能有

(只有静态内部类才能创建静态成员)

作用:

提高了代码的封装性,内部类只能被外部类访问

成员内部类

具有成员变量同样属性(public,static,private,default)

定义在方法体外

通过外部类对象访问内部类,内部类的实例在外部类的基础上

调用方法

外部类.内部类 对象名=new 外部类().new 内部类();

静态内部类

静态内部类独立存在,不依赖外部类

静态内部类只能访问外部静态成员

可间接访问外部非静态成员

创建外部类对象调用属性方法

new 外部类().属性/方法

调用方法

外部类.内部类 对象名=new 外部类.内部类();

局部内部类

*局部类存在的方法中所有变量默认被final修饰,故赋值后不可变

*调用该类执行的操作必须写在该方法中

*不能创建静态成员

类没有访问修饰符

定义在方法体内

随方法执行完毕而消失

外部类调用时要通过特定方法间接调用局部内部类

调用方法

直接调用外部类方法(因为对该内部类的定义和操作方法封装在一个方法中)

匿名内部类

实质

接口的实现类匿名对象或者继承了该类的匿名对象

格式

new 类名/接口名(){
.....重写的方法.....
};

本身就是对象,可以直接调用方法
new 类名/接口名(){
.....重写的方法.....
}.方法();

既然是接口或类的实现/继承对象,也应该有对应的类型——>多态

接口名 interface=new interface(){
	@override
	方法......
};

interface.方法();
interface.方法();

作用场景

一般用来实现同一个功能下多次实现接口时避免繁琐为一个接口而创建不同类

通过匿名内部类来避免繁琐创建实现类

匿名内部类的用不仅仅用来实现函数式接口,它本质是一个匿名对象,因此也可以实现基本类,抽象类,接口的匿名对象(不限抽象方法数量)

lambda表达式

函数式接口:接口有且仅有一个方法,建议用@FunctionalInterfce注解标注函数式接口

@FunctionalInterface
public interface TsetInterface {
    void run();
}

lambda表达式简化了匿名对象的实现方法,通过上下文环境可以判断出对应哪个接口(对应的参数类型)

匿名方法,优化取代了了匿名内部类在实现函数式接口中的繁琐,使代码更简洁

作用

实现函数式接口(只有一个抽象方法,且该接口用@FunctionalInterface注解)

格式

参数->语句块

参数列表—>表达式/语句块{};当语句块中只有一条语句时“;”,“return”,“{}”都可以省略

可以无参,相当于void

()->{System.out.print("balabala...");}

当只有一个参数值,括号可以省略

str->{return str.length;}

参数的类型可以省略,但是不能只省略一个

案例

import java.util.function.Consumer;

public class demo {
    public static void main(String[] args) {
        //需求:消费给定的monkey,但是消费方式没有给定,需要具体消费的时候指定


        //消费100,洗澡
        consumerMonkey(100, m -> System.out.println("洗澡花费了"+m));
        //消费200,吃饭
        consumerMonkey(200, m-> System.out.println("吃饭花费了200元"));


        /**
         *  消费monkey,但是没有指定出使用什么方式消费
         * */
    }
    public static void consumerMonkey(double money, Consumer<Double> policy){//得到接口的匿名对象
        policy.accept(money);//接口对象.接口方法
    }
}

传递接口匿名对象(参consumer同时实现方法,通过对象调用方法(参money)

方法引用

方法引用适用于接口,用来从容器中提取已有方法

lambda表达式支持方法引用,方法引用和lambda是孪生兄弟

lamda表达式的简化,所引用的方法就是lamda表达式方法的实现

将别的方法引用进来

省略了可以从上下文环境可以判断的一切因素

类/实例/容器::方法

引用类方法
引用对象实例方法
引用构造方法

引用类方法

类::方法  (String::parseInt)

引用实例对象方法

类实例对象::方法  ("hello"::ParseInt)

引用类构造器

类::new (例:Student::new)


.....................
getObj(Student::new)
.....................


public static void getObj(TestInterface inter) {
	System.out.println(inter.getObj("小为").getName());
}
.....................
public class Demo {
    public static void main(String[] args) {
//        匿名内部类实现
        run(new TestInterface() {
            @Override
            public void run(String str) {
                System.out.println(str);
            }
        });

//      lambda表达式实现
        run(s-> System.out.println(s));

//        方法引用实现
        run(System.out::println);
    }
    public static void run(TestInterface inter){
        inter.run("小为");
    }
}
-

匿名内部类和lambda区别:

使用类型不同

匿名内部类基适用本类,抽象类,接口
lambda只能是函数式接口

实现原理不同

匿名内部类编译后产生单独.class字节码文件
lambda表达式对应的字节码动态生成

”可推导,可省略“

匿名内部类实质是匿名对象,而lambda表达式简化了其匿名对象的创建过程,方法引用在lambda表达式基础上更进一步简化了匿名对象创建过程,这一系列过程中省略了其本身可以通过上下文环境使进行推导出的参数,参数类型,以及不必要的关键字等等

接口的实现----简化--->匿名内部类----简化--->lambda----简化--->方法引用
  • 10
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

大数据小为

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值