Java SE 入门到精通—5.内部类与匿名类【Java】
内部类
内部类可以访问外部类所有成员,包括私有
外部类访问内部类必须创建内部类对象访问
特点:
内部类具有类的基本特征
内部类无法被其他类访问(即使在同一个包中),只能被其外部类访问
内部类的属性类似成员属性
内部类可以访问外部类的所有成员(私有,静态等等)
内部类同样可继承,重载,重写,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----简化--->方法引用
原文地址:https://blog.csdn.net/qq_63369191/article/details/136244564
免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!