Java核心卷一之接口、lambda 表达式与内部类

首先 介绍一下接口 interface ) 技术 这种技术主要用来描述类具有什么功能,而并不 给出每个功能的具体实现。 一个类可以实现 implement )—个或多个接口,并在需要接口的地方, 随时使用实现了相应接口的对象 了解接口以后
再继续介绍而表达式,这是 一种表示可以在将来某个时间点执行的代码块的简洁方法。 使用 lambda 表达式 可以用一 种精巧而简洁的方式表示使用回调或变量行为的代码。 接下来, 讨论内部类 inner class ) 机制 理论上讲 内部类有些复杂 内部类定义在另 外一个类的内部, 其中的方法可以访问包含它们的外部类的域 内部类技术主要用于设计具 有相互协作关系的类集合。
在本章的最后还将介绍代理 proxy ) , 这是一种实现任意接口的对象 代理是一种非常
专业的构造工具 它可以用来构建系统级的工具

接口

接口概念

Java 程序设计语言中 接口不是类 而是对类的一组需求描述 这些类要遵从接口描
述的统一格式进行定义
接口中的所有方法自动地属于 public 因此 在接口中声明方法时 不必提供关键字
public
为了让类实现一个接口 通常需要下面两个步骤
1 ) 将类声明为实现给定的接口
2 ) 对接口中的所有方法进行定义
要将类声明为实现某个接口 需要使用关键字 implements :
cl ass Employee implements Comparable
 

接口的特性

接口不是类 尤其不能使用 new 运算符实例化一个接口
x = new Comparable ( . . . ) ; / / ERROR
然而 尽管不能构造接口的对象 却能声明接口的变量
Comparable x ; // OK
接口变量必须弓 I 用实现了接口的类对象
x = new Employee ( . . . ) ; / / OK provided Employee implements Comparable
接下来 如同使用 instanceof 检查一个对象是否属于某个特定类一样 也可以使用
instance 检查一个对象是否实现了某个特定的接口
if ( anObject instanceof Comparable ) { . . . }
与接口中的方法都自动地被设置为 public
—样, 接口中的域将被自动设为 public static final
尽管每个类只能够拥有一个超类 但却可以实现多个接口 。这就为定义类的行为提供了
极大的灵活性 例如 Java 程序设计语言有一个非常重要的内置接口 称为 Cloneable ( 将在
6.2 . 3 节中给予详细的讨论 ) 如果某个类实现了这个 Cloneable 接口 Object 类中的 clone
法就可以创建类对象的一个拷贝 如果希望自己设计的类拥有克隆和比较的能力 只要实现
这两个接口就可以了
:
使用逗号将实现的各个接口分隔开
class Employee implements Cloneable , Comparable

接口与抽象类

为什么 Java 程序设计语言还要不辞辛苦地引入接口概念? 为什么不将 Comparable 直接设计成如下所示的抽象类。
然后 Employee 类再直接扩展这个抽象类 并提供 compareTo 方法的实现
非常遗憾 使用抽象类表示通用属性存在这样一个问题 每个类只能扩展于一个类
Employee 类已经扩展于一个类 例如 Person , 它就不能再像下面这样扩展第二个类了
class Employee extends Person , Comparable / / Error
但是可以实现多个接口
Java 的设计者选择了不支持多继承 其主要原因是多继承会让语言
本身变得非常复杂 如同 C + + ) 效率也会降低 如同 Eiffel )
实际上, 接口可以提供多重继承的大多数好处 同时还能避免多重继承的复杂性和低效性

静态方法

Java SE 8 允许在接口中增加静态方法 理论上讲 没有任何理由认为这是不合法
只是这有违于将接口作为抽象规范的初衷。目前为止 通常的做法都是将静态方法放在伴随类中

lambda 表达式

lambda 表达式 这是这些年来 Java 语言最让人激动的一个变化 你会了解如何使用 lambda 表达式采用一种简洁的语法定义代码块 以及如何编写处理 lambda 表达式的代码

为什么引入 lambda 表达式

lambda 表达式是一个可传递的代码块 可以在以后执行一次或多次
到目前为止 Java 中传递一个代码段并不容易 不能直接传递代码段 _ Java 是一种面
向对象语言 所以必须构造一个对象 这个对象的类需要有一个方法能包含所需的代码
在其他语言中 可以直接处理代码块 Java 设计者很长时间以来一直拒绝增加这个特性
毕竟 Java 的强大之处就在于其简单性和一致性 如果只要一个特性能够让代码稍简洁一些
就把这个特性增加到语言中 这个语言很快就会变得一团糟 无法管理 。 不过 在另外那些
语言中 并不只是创建线程或注册按钮点击事件处理器更容易 它们的大部分 API 都更简单
更一致而且更强大 Java 也可以编写类似的 AP 丨利用类对象实现特定的功能 不过这
API 使用可能很不方便

lambda 表达式的语法

  • 一个 Lambda 表达式可以有零个或多个参数
  • 参数的类型既可以明确声明,也可以根据上下文来推断。例如:(int a)(a)效果相同
  • 所有参数需包含在圆括号内,参数之间用逗号相隔。例如:(a, b) 或 (int a, int b) 或 (String a, int b, float c)
  • 空圆括号代表参数集为空。例如:() -> 42
  • 当只有一个参数,且其类型可推导时,圆括号()可省略。例如:a -> return a*a
  • Lambda 表达式的主体可包含零条或多条语句
  • 如果 Lambda 表达式的主体只有一条语句,花括号{}可省略。匿名函数的返回类型与该主体表达式一致
  • 如果 Lambda 表达式的主体包含一条以上语句,则表达式必须包含在花括号{}中(形成代码块)。匿名函数的返回类型与代码块的返回类型一致,若没有返回则为空

函 数 式 接 口

对于只有一个抽象方法的接口 需要这种接口的对象时 就可以提供一个 lambda 表达
这种接口称为函数式接口 functional interface )
为了展示如何转换为函数式接口 下面考虑 Arrays . sort 方法 它的第二个参数需要一个
Comparator 实例 Comparator 就是只有一个方法的接口 所以可以提供一个 lambda 表达式
Arrays . sort ( words , (first , second ) - > first . lengthO - second . lengthO ) ;
最好把 lambda 表达式看作是一
个函数 而不是一个对象 另外要接受 lambda 表达式可以传递到函数式接口

内部类

内部类 inner class ) 是定义在另一个类中的类 为什么需要使用内部类呢 ? 
•内部类方法可以访问该类定义所在的作用域中的数据, 包括私有的数据
•内部类可以对同一个包中的其他类隐藏起来。
当想要定义一个回调函数且不想编写大量代码时 使用匿名 anonymous ) 内部类比较
便捷
在Java中,可以将一个类定义在另一个类里面或者一个方法里面,这样的类称为内部类。广泛意义上的内部类一般来说包括这四种:成员内部类、局部内部类、匿名内部类和静态内部类。

.匿名内部类

什么是匿名对象?如果一个对象只要使用一次,那么我们就是需要 new Object().method() 。 就可以了,而不需要给这个实例保存到该类型变量中去。这就是匿名对象。
public class Test {
public static void main(String[] args) {
//讲new出来的Apple实例赋给apple变量保存起来,但是我们只需要用一次,就可以这样写
Apple apple = new Apple();
apple.eat();
//这种就叫做匿名对象的使用,不把实例保存到变量中。
new Apple().eat();
}
}
class Apple{
public void eat(){
System.out.println("我要被吃了");
}
}

匿名内部类跟匿名对象是一个道理:
匿名对象:我只需要用一次,那么我就不用声明一个该类型变量来保存对象了,
匿名内部类:我也只需要用一次,那我就不需要在类中先定义一个内部类,而是等待需要用的时候,我
就在临时实现这个内部类,因为用次数少,可能就这一次,那么这样写内部类,更方便。不然先写出一
个内部类的全部实现来,然后就调用它一次,岂不是用完之后就一直将其放在那,那就没必要那样。
1. 匿名内部类需要依托于其他类或者接口来创建
如果依托的是类 , 那么创建出来的匿名内部类就默认是这个类的子类
如果依托的是接口 , 那么创建出来的匿名内部类就默认是这个接口的实现类。
2. 匿名内部类的声明必须是在使用 new 关键字的时候
匿名内部类的声明及创建对象必须一气呵成 , 并且之后能反复使用 , 因为没有名字。
 
public static void main(String[] args) {
//如果我们需要使用接口中的方法,我们只需要走一步,就是使用匿名内部类,直接将其
类的对象创建出来。
new Test1(){
public void method(){
System.out.println("实现了Test接口的方法");
}
}.method();
}
}
interface Test1{
public void method();
}



猜你喜欢

转载自blog.csdn.net/weixin_47277897/article/details/121545195