day13
抽象类
1. 半成品,是没有完成的类
2. 抽象方法的作用:
作为通用方法在父类中定义
要求子类必须实现
3. final
1. 常量, 值不可变
2. 方法, 不能重写
3. 类, 不能继承
4. static
1. 静态属于类的
2. 调用时,使用类名调用,也允许使用实例调用
3. 静态的初始化块
static{
类加载时执行,只执行一次
}
5. 访问控制符
1. public
2. protected
3. default
4. private
6. 对象创建的过程 10步
1.
7. 接口
1. 作用: 结构设计工具,解耦合,隔离实现
2. interface
3. implements
4. 可以多实现,接口与接口之间可以多继承
异常处理
封装错误信息的对象
错误信息 有3点
1. 类型
2. 提示信息
3. 行号
异常的继承结构
Throwable
| - Error 系统级错误, 无法处理,只能尽量让程序安全的退出.
| - Exception 异常, 可修复的错误
| - 其他 Exception
| - RuntimeException
|
| - NullPointerException
| - ArrayIndexOutOfBoundsException
| - ArithmeticException 数学异常
| - NumberFormatException
| - ClassNotFoundException
| - ClassCastException
| - ...
异常的捕获
try{
捕获
}catch(A异常类型){
处理
}catch(B异常类型){
处理
}catch(Exception e){
父类型处理
} finally{
不管处不出错,都必须执行
}
throws
在方法上添加异常的抛出管道
void f() throws A,B,C{
}
出现异常, 异常必须处理,处理的方式有两种
1. catch
2. throws
注: 在方法上, 存在默认的异常管道, 凡是RuntimeException下的异常都可以在不加管道的情况下,抛出
练习1, 异常
package day301;
import java.util.Scanner;
public class Test1 {
public static void main(String[] args) {
while(true){
try {
f();
break;
} catch (ArrayIndexOutOfBoundsException e) {
System.out.println("输入2个,不是一个");
}catch(ArithmeticException e){
System.out.println("不嗯呢该除零");
}catch (Exception e) {
System.out.println("出错,请重试");
e.printStackTrace();
}finally {
System.out.println("-----------------");
}
}
}
private static void f() {
/*
* 输入2个整数,用 ,号隔开
*/
System.out.println("请输入2个整数,用 , 号隔开");
String s = new Scanner(System.in).nextLine();
//拆分,返回一个数组
String[] a = s.split(",");
int m1 = Integer.parseInt(a[0]);
int m2 = Integer.parseInt(a[1]);
int r=m1/m2;
System.out.println(r);
}
}
测试 throws
package day301;
import java.io.File;
import java.io.IOException;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Scanner;
public class Test2 {
public static void main(String[] args) {
try {
f();
} catch (ParseException e) {
System.out.println("日期格式错误");
} catch (IOException e) {
System.out.println("不能创建文件");
}
}
private static void f() throws ParseException, IOException {
/*
* 输入日期(yyyy-MM-dd) "2919-4-1"
*
* SimpleDateFormat 日期格式工具,把字符串解析成Date
*
* Date 实例中,封装的是时间的毫秒值
* 取出毫秒值:3656456544
* 新建一个文件 d:\3656456544.txt 文件
*
*/
System.out.println("输入日期(yyyy-MM-dd): ");
String s = new Scanner(System.in).nextLine();
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
//强制处理异常
//必须事先考虑异常如何考虑,给出处理方案
Date d = sdf.parse(s);
String path="d:\\"+d.getTime()+".txt";
File file = new File(path);
file.createNewFile();
System.out.println("文件已经创建"+path);
}
}
RuntimeException和其他 Exception区别
RuntimeException: 称为"非检查异常"
编译期不会检查这种异常,不便携处理代码也可以
其他Exception 称为 "检查异常"
编译期会检查这种异常,有没有处理代码,没有代码,编译不会通过
两种处理异常的方式: catch , throws
RuntimeException 就算不写默认也会添加管道.
catch 和 throws 如何选择?
如果是在底层代码出现的错误,一般要向上层抛出,在调用路径中,选择一个合适的位置捕获处理.
如果经验不足,不知道如何选择 catch 还是 throws, 就要用 throws,不能随便 catch.
throw
手动抛出异常,执行异常的抛出动作
当程序出现逻辑错误 ,而且不自动创建异常,可以手动新建异常对象,并手动抛出
throw e,优点相当于 return e ;的感觉
#### 测试 throw
package day301;
import java.util.Scanner;
public class test3 {
public static void main(String[] args) {
f();
}
private static void f() {
/*
* 5345/0 出现异常 ArithmeticException
*
* 32.5632 /0 -->Infinity 无穷大值 ,特殊值
* 不出错, 没有提示异常
* Infinity 没有意义,我们需要处理这种数据异常
*/
System.out.println("输入两个浮点数:");
double a = new Scanner(System.in).nextDouble();
double b = new Scanner(System.in).nextDouble();
try {
double c=divide(a,b);
System.out.println(c);
} catch (ArithmeticException e) {
System.out.println("不能除零,是我们的错");
e.printStackTrace();
}
}
private static double divide(double a, double b) {
if(b==0){
ArithmeticException e =
new ArithmeticException(" / by zero ");
throw e;
}
return a/b ;
}
}
异常包装 捕获的异常,包装成另一种类型在抛出
为什么要包装后在抛出?
异常包装使用用场景:
1. 不能抛出的类型,包装成能抛出的类型
2. 异常的简化
为什么不能抛出? 不是加个管道就可以抛出了吗?
如: 方法重写时,异常管道,不能比父类方法的管道多.
异常包装的测试:
package day301;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
public class Test4 {
public static void main(String[] args) {
Student s = new Student("张三", "asda-06-12");
System.out.println(s);
}
}
class Student{
String name;
String birthday; //"1945-12-10"
public Student(String name, String birthday) {
super();
this.name = name;
this.birthday = birthday;
}
@Override
public String toString() {
// 张三 ,7854642131321(毫秒值)
// SimpleDateFormat 解析成Date 实例
// 从Date 中再取出毫秒值
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
try {
Date d = sdf.parse(birthday);
return name+","+d.getTime();
} catch (ParseException e) {
/*
* Parseexception 是抛不出去的, 因为他不是RuntimeException类型的
* 而且 也不能 throws 加管道,因为 toString()是重写父类object的,
* 父类中的toString() 没有声明管道,只有默认的RuntimeException管道.
* 所以需要把他 包装成 可以抛出的类型.
*/
throw new RuntimeException(e);
}
}
}
如果出现异常,他的异常信息:
Exception in thread "main" java.lang.RuntimeException: java.text.ParseException: Unparseable date: "asda-06-12"
at day301.Student.toString(Test4.java:42)
at java.lang.String.valueOf(String.java:2982)
at java.io.PrintStream.println(PrintStream.java:821)
at day301.Test4.main(Test4.java:10)
Caused by: java.text.ParseException: Unparseable date: "asda-06-12"
at java.text.DateFormat.parse(DateFormat.java:366)
at day301.Student.toString(Test4.java:32)
... 3 more
自定义异常类型
业务中的错误情况,用现有的异常类型是无法表示的,
如 转账失败, 就没有合适的异常来表示
我们的自定义异常 只不过是起一个符合这个异常描述的名字,我们也只是需要一个合适的名字.
转账异常:
ZhuanZhangShiBaiException
用户名错误
usernameNotFoundException
密码错误
WrongPassworldException
自定义异常:
1. 起一个合适的类名
2. 选择一个合适的异常父类, 可以继承runtimeException或者 Exception都可以,但注意的是 RuntimeException 是默认的管道,不用throws也可以抛出.
3. 添加合适的构造方法
自定义异常 测试
自定义 2个异常,
一个用户名异常,
一个密码异常.
如下:创建类:
package day301;
public class usernameNotFoundException extends Exception{
/*
* 在写自定义异常的构造时 ,参考父类的写法,
* Shift+Alt+ s ----->
*
*/
public usernameNotFoundException() {
super();
}
public usernameNotFoundException(String message, Throwable cause, boolean enableSuppression,
boolean writableStackTrace) {
super(message, cause, enableSuppression, writableStackTrace);
}
public usernameNotFoundException(String message, Throwable cause) {
super(message, cause);
}
public usernameNotFoundException(String message) {
super(message);
}
public usernameNotFoundException(Throwable cause) {
super(cause);
}
}
package day301;
public class WrongPassworldException extends Exception{
public WrongPassworldException() {
super();
}
public WrongPassworldException(String message, Throwable cause, boolean enableSuppression,
boolean writableStackTrace) {
super(message, cause, enableSuppression, writableStackTrace);
}
public WrongPassworldException(String message, Throwable cause) {
super(message, cause);
}
public WrongPassworldException(String message) {
super(message);
}
public WrongPassworldException(Throwable cause) {
super(cause);
}
}
package day301;
import java.util.Scanner;
public class Test5 {
public static void main(String[] args) {
System.out.println("用户名: ");
String n = new Scanner(System.in).nextLine();
System.out.println("密码: ");
String p = new Scanner(System.in).nextLine();
try {
login(n,p);
System.out.println("登陆成功");
} catch (usernameNotFoundException e) {
System.out.println("用户名不存在");
}catch (WrongPassworldException e) {
System.out.println("密码错误");
}
}
private static void login(String n, String p) throws usernameNotFoundException, WrongPassworldException {
// "abc" ,"123"
if (!n.equals("abc")) {
throw new usernameNotFoundException();
}
if (!p.equals("123")) {
throw new WrongPassworldException();
}
}
}
IO
Input/ Output
输入 / 输出
输入: 外部数据,读取到内存,有程序进行处理
输出: 内存中的数据,向外部输出
java.io 包
1. File
2. InputStream /OutputStream
3. FileInputStream/ fileOutputStream
4. ObjectInputStream /ObjectOutputStream
5. Reader /Writer
6. InputStreamReader /OutputSteramWriter
7. BufferedReader
8. PrintWriter
File 类
用来封装磁盘路径字符串
File 实例={ path: "d:\a.txt"}
可以封装:
1. 文件路径
2. 文件夹路径
3. 不存在的路径
内部提供了一些方法:
文件或文件夹属性方法:
1. getName() 获取文件名
2. getParent() 获取父文件夹 (路径)
3. getAbsolutePath() 完整路径 ,绝对路径
4. exists() 是否存在,判断这个路径是否存在, 返回值 boolean
5. isFile() 是否是文件
6. isDirectory() 是否是文件夹
7. length() 获取文件的字节量, 对文件夹无效
属性方法测试: