接口&内部类&异常&Lambda

接口

接口

一般说class类之间的调用方式是 extends 继承,而class调用interface 接口 implements 关键字实现

接口是一种特殊的抽象类,是功能的集合(一般指抽象方法)。

优点:

1.接口可以多实现,类只能单继承

2.提高代码的复用性

3.解耦

4.定义开发规范

定义:

jdk1.7及之前版本:
1、静态常量: public static final 数据类型 = 值;

修饰符默认,可以选择性的省略

调用: 接口名|实现类类名|实现 类对象.静态常量名

2、抽象方法: public abstract 返回值类型|void 方法名();

修饰符默认,可以选择性的省略

调用: 实现类对象.方法名

jdk1.8及之前版本:
静态方法: 只能通过接口名调用
默认方法: 通过实现类对象使用
注意:

1.接口不能实例化

2.使用接口,需要通过子类实现,实现使用implements关键字

3.作用于继承很像,实现了接口,就有了接口中定义的规范,但是功能需要自己实现

类与接口: 只能是类实现接口,但是可以多实现

类与类: 只能单继承

接口与接口: 多继承

5.避免 一个类实现的多个接口中存在方法签名相同的方法

内部类与异常

1、异常

1.1. 异常的概念

异常(Exception) 即例外,程序没有按自己预想的结果运行出来,出现了非正常情况,即“程序得病了”。怎么让我们写的程序做出合理的处理,不至于崩溃是我们关注的核心。 异常机制就是当程序出现错误,程序如何安全退出的机制。
所谓错误是指在程序运行的过程中发生的一些例外事件(如:除0,数组下标越界,所要读取的文
件不存在)。
Java异常类是Java提供的用于处理程序中错误的一种机制。设计良好的程序应该在异常发生时提供
处理这些错误的方法,使得程序不会因为异常的发生而阻断或发生不可预见的结果。
Java程序的执行过程中如出现例外事件,可以生成一个异常类对象,该异常对象封装了例外事件的
信息并将被提交给Java运行时系统,这个过程称为抛出( throw )异常。 当Java运行时系统接收到异常对象时,会寻找能处理这一异常的代码并把当前异常对象交给其处理,这
一过程称为捕获(catch)异常。

1.2. 异常的分类

JDK中定义了很多异常类,这些类对应了各种各样可能出现的例外事件。我开着车走在路上,一头
猪冲在路中间,我刹车,这叫一个 异常。我开着车在路上,发动机坏了,我停车,这叫错误。系统处于
不可恢复的崩溃状态。发动机什么时候坏?我们普通司机能管吗?不能。发动机什么时候坏是汽车厂发
动机制造商的事。
Error:称为错误,由Java虚拟机生成并抛出,包括动态链接失败、虚拟机错误等,程序对其不做处
理。Error 类层次描述了 Java 运行时系统内部错误和资源耗尽错误。这类错误是我们无法控制的,同
时也是非常罕见的错误。所以在编程中,不去处理这类错误。Error 表明系统 JVM 已经处于不可恢复
的崩溃状态中。我们不需要管他。 如:写代码时突然断电,或者内存溢出。
Exception:所有异常的父类,其子类对应了各种各样可能出现的异常事件,一般需要用户显示地声
明或捕获。

1.2.1. Runtime Exception

Runtime Exception类是 Exception 类的子类,叫做运行时异常,Java 中的所有运行时异常都会直
接或者间接地继承自 RuntimeException 类。
这一类特殊的异常,如被0除、数组下标超范围等,其产生比较频繁,处理麻烦,如果显示的声明
或捕获将会对程序可读性可运行效率影响很大。因此由系统自动检测并将它们交给缺省的异常处理程序
(用户可不必对其处理);我们可以通过程序的健壮性来处理,不推荐使用异常处理机制来处理。
例如:
NullPointerException: 当程序访问只有引用没有对象的成员属性或成员方法。怎么处理?
ArithmeticException: 除数为 0ClassCastException:多态时类型转换错误
ArrayIndexOutOfBoundsException: 访问的元素下表超过数组长度
NumberFormatException: 数字格式异常!
1.2.2. CheckException(**需要处理的)
Java 中凡是继承自 Exception,而不继承自 RuntimeException 类的异常都是非运行时异常,也叫
检查时异常。 如:IOException。 必须要对其进行处理,否则无法通过编译。这类异常的产生不是程序
本身的问题,通常由外界因素造成的。 为了预防这些异常产生时,造成程序的中断或得到不正确的结
果,Java 要求编写可能产生这类异常的程序代码时,一定要去做异常的处理。

2.异常处理

2.1. 异常产生

之所以出现异常,是因为内部抛出了异常对象,这个异常对象的产生分为系统内部产生,或程序员
手动抛出异常。

2.2. 异常捕获 try catch finally

对于编译(非运行)时异常( checked exception ),必须要对其进行处理,否则无法通过编译。处理
方式有两种:异常捕获&异常处理
try代码段包含可能产生例外的代码
try代码段后跟有一个或多个catch代码段
每个catch代码段声明其能处理的一种特定类型的异常并提供处理的方法
当异常发生时,程序会中止当前的流程,根据获取异常的类型去执行相应的catch代码段
一个 try 后面可以跟多个 catch,但不管多少个, 最多只会有一个catch 块被执行。
finally段的代码无论是否发生异常都有执行
try语句
try{…}语句制定了一段代码,该段代码就是一次捕获并处理意外的范围。
在执行过程中,该段代码可能会产生并抛出一种或几种类型的异常对象,它后面的catch语句要分
别对这些异常做相应的处理。
如果没有意外产生,所有的catch代码段都被略过不执行。
catch语句
在catch语句块中是对异常进行处理的代码,每个try语句块可以伴随一个或多个catch语句,用于处
理可能产生的不同类型的异常对象。
在catch中声明的异常对象封装了异常事件发生的信息,在catch语句块中可以使用这个对象的一些
方法获取这些信息。
例如:
getMessage()方法,用来得到有关异常事件的信息
printStackTrace()方法,用来跟踪异常事件发生时执行堆栈的内容
finally语句
finally语句为异常处理提供一个统一的出口,使得在控制流程转到程序的其它部分以前,能够对程
序的状态作统一的管理。无论try所制定的程序块中是否抛出异常,finally所指定的代码都要被执行。
通常在finally语句中可以进行资源的清除工作,如:
关闭打开的文件
删除临时文件

2.3. 向外 声明( 抛出) 异常 throws

在产生异常的方法声明后面写上 throws 某一个 Exception 类型,如 throws Exception,将异常抛
出到外面一层去
异常与重写声明
子类声明的异常范围不能超出父类的异常范围

2.4. 使用自定义的异常
2.4.1. 概念

所谓自定义异常,通常就是定义一个类,去继承 Exception 类或者它的子类。因为异常必须直接或
者间接地继承自 Exception 类。通常情况下,会直接继承自 Exception 类,一般不会继承某个运行时的
异常类。

2.4.2. 步骤

使用自定义异常一般有如下步骤: 1、 通过继承java.lang.Exception类声明自己的异常类
2、 在方法适当的位置生成自定义异常的实例,并用throw语句抛出
3、 在方法声明部分用throws语句声明该方法可能抛出的异常

  1. 内部类

内部类,即类内部的类。类中类。形式如下:

3.1. 理解内部类的作用

内部类可以很好的实现隐藏
一般的非内部类,是不允许有 private 与protected权限的,但内部类可以
内部类拥有外围类的所有元素的访问权限
可是实现多重继承
匿名内部类优化接口

3.2. 隐藏细节

平时我们对类的访问权限,都是通过类前面的访问修饰符来限制的,一般的非内部类,是不允许
有 private 与protected权限的,但内部类可以,所以我们能通过内部类来隐藏我们的信息。这看起来没
什么作用,但是当内部类实现某个接口的时候,在进行向上转型,对外部来说,就完全隐藏了接口的实
现了。

3.3. 可以无条件地访问外围类的所有元素

内部类虽然和外部类写在同一个文件中, 但是编译完成后, 还是生成各自的class文件,内部类通
过this访问外部类的成员。
public class Outter{ 外部类 class Inner{ 内部类 } }

3.4. 可以实现多重继承

这个特点非常重要,它是内部类存在的最大理由之一。正是由于他的存在使得Java的继承机制更加
完善。大家都知道Java只能继承一个类,它的多重继承在我们没有学习内部类之前是用接口来实现的。
但使用接口有时候有很多不方便的地方。比如我们实现一个接口就必须实现它里面的所有方法。而有了
内部类就不一样了。它可以使我们的类继承多个具体类或抽象类。

3.5. 通过匿名内部类来优化简单的接口实现

有了匿名内部类,可以不需要定义一个新的类,而直接通过匿名内部类创建对象。对那些只是用一
次的类是非常方便的事情。

  1. 内部类的分类

在Java中,可以将一个类定义在另一个类里面或者一个方法里面,这样的类称为内部类。广泛意义
上的内部类一般来说包括这四种:成员内部类、局部内部类、匿名内部类和静态内部类。
内部类的共性:
内部类仍然是一个独立的类,在编译之后内部类会被编译成独立的.class文件,但是前面冠以外部
类的类名和$符号 。
内部类不能用普通的方式访问。内部类是外部类的一个成员,因此内部类可以自由地访问外部类的
成员变量,无论是否是private的 。
内部类声明成静态的,就不能随便的访问外部类的成员变量了,此时内部类只能访问外部类的静态
成员变量

4.1. 成员内部类

成员内部类可以无条件访问外部类的所有成员属性和成员方法(包括private成员和静态成员)。
虽然成员内部类可以无条件地访问外部类的成员,而外部类想访问成员内部类的成员却不是这么随
心所欲了。在外部类中如果要访问成员内部类的成员,必须先创建一个成员内部类的对象,再通过指向
这个对象的引用来访问:

4.1.1. 内部类的基本结构

内部类其实严重破坏了良好的代码结构,但为什么还要使用内部类呢?
因为内部类可以随意使用外部类的成员变量(包括private)而不用生成外部类的对象,这也是内部类的
唯一优点

4.1.2. 内部类中的变量访问形式

内部类在没有同名成员变量和局部变量的情况下,内部类会直接访问外部类的成员变量;若有同名
情况时,直接访问会导致内部类中的局部变量将外部类的成员变量覆盖,访问内部类本身的成员变量可
用this.属性名,访问外部类的成员变量需要使用Out.this.属性名

4.1.3. 私有内部类

如果一个内部类只希望被外部类中的方法操作,那么可以使用private声明内部类,此时我们必须
在Out类里面生成In类的对象进行操作,而无法再使用Out.In in = new Out().new In() 生成内部类的对

也就是说,此时的内部类只有外部类可控制
如同是,我的心脏只能由我的身体控制,其他人无法直接访问它

4.2. 静态内部类

如果用static 将内部类静态化,那么内部类就只能访问外部类的静态成员变量,不能直接访问外部
类的实例变量、实例方法,只有通过对象引用才能访问。
其次,因为内部类被静态化,因此Out.In可以当做一个整体看,可以直接new 出内部类的对象(静
态内部类不通过外部类实例进行创建对象)

4.3. 局部内部类

将内部类移到了外部类的方法中,然后在外部类的方法中再生成一个内部类对象去调用内部类方
法。局部内部类和成员内部类的区别在于局部内部类的访问仅限于方法内
如果此时我们需要往外部类的方法中传入参数,那么外部类的方法形参必须使用final定义类
至于final在这里并没有特殊含义,只是一种表示形式而已
局部内部类:像局部变量一样,不能被public, protected, private和static修饰。jdk1.8 +可以不加
final

4.4. 匿名内部类***(重点)
4.1匿名类的定义:

定义类的最终目的是创建一个类的实例,但是如果某个类的实例只是用一次,则可以
将类的定义与类的创建,放到与一起完成,或者说在定义类的同时就创建一个类 , 以这种方法定义的没
有名字的类成为匿名内部类。

4.2 格式:

​ 4.2.1Out.Inner inner=new Out().new Inner(); 或 Out out=new Out() Out.Inner inner=out.new Inner()
声明和构造匿名内部类的一般格式如下:
new ClassOrInterfaceName(){ 类体 }
①匿名内部类可以继承一个类或实现一个接口,这里的ClassOrInterfaceName是匿名内部类所继承的类名或实现的接口名。但匿名内部类不能同时实现一个接口和继承一个类,也不能实现多个接口。如果实现了一个接口,该类是Object类的直接子类,匿名类继承一个类或实现一个接口,不需要extends和implements关键字。
②由于匿名内部类没有名称,所以类体中不能定义构造方法,由于不知道类名也不能使用关键字来创建该类的实例。实际上匿名内部类的定义、构造、和第一次使用都发生在同样一个地方。此外,上式是一个表达式,返回的是一个对象的引用,所以可以直接使用或将其复制给一个对象变量,如:
TypeName obj=new Name(){ 此处为类体 }
同样,也可以将构造的对象作为调用的参数。例:
someMethod(new Name(){ 此处为类体 });
局部内部类:像局部变量一样,不能被public, protected, private和static修饰。Jdk1.7中只能访问方法
中定义的final类型的局部变量。

5.Lambda

Lambda是1.8的新特性:

1、Lambda表达式为了简化匿名内部类的
2、使用前提:

函数式接口: 必须要重写的抽象方法只有一个的接口

检测一个 接口是否为函数式接口: @FunctionalInterface

3、语法: ()->{};

() 方法的参数列表

{} 重写抽象方法的方法体

-> 箭头符号 lmabda符号

4、Lambda写法
Lambda写法 1

Smoke s1 = ()->{ System.out.println(“边吸烟边吐烟圈 …”); };

Lambda写法 2

如果方法体只有一句,前后的{}可以省略
Smoke s2 = ()->System.out.println(“边吸烟边吐烟圈 2…”);

Lambda写法3

如果抽象方法有参数,参数的数据类型可以省略
Smoke s3 = (a)->System.out.println(“边吸烟边吐烟圈 3…”+a);

Lambda写法4

如果参数只有一个,前后的()可以省略
Smoke s4 = a->System.out.println(“边吸烟边吐烟圈 4…”+a);

Lambda写法5

如果方法体语句只有一句,并且是return返回值语句,前后的{}与return关键字可以一起省略

​ Smoke s5 = i-> “最后”+i; System.out.println(s5.Smoking(3));

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值