关于throw的总结
1.父类异常预定义
在可能产生异常的动作后边,加上【可能出现的异常】,相较于子类,只能多不能少
示例:abstract void gets(double t) throws noMoney, exit;//取钱会出现错误
取钱的时候可能会遇到的两种错误,在动作void后方加上throws
2.子类异常预定义
也是后边加上throws,只能是父类定义中的部分异常处理,父类没定义的异常处理不能加
示例:
3.自定义异常
在ASRC同级,定义class,后面需要拓展Exception父类,书写示例
内侧可以定义无参构造,在定义出现异常捕获(catch)的时候,相当于实例化这个异常,会自动执行无参构造,我们这里使用void只是为了IDEA可以把代码块折叠起来,我们在
4.try-catch机制
A.这俩要紧贴在一起,中间不能有其他的语句
B.catch括号内相当于实例化一个异常,名称叫做e(类似于结构体实例化)
如果有定义无参构造,会自动执行;也可以重载带参数的构造
C.调用有参构造时,无参构造就不会被执行了;这里图省事之写了一个普通动作
5.异常的产生(抛出)
A.抛出异常的时候,会终止try块,执行catch
B.看块的位置知道中断后 try-catch 执行完成,会继续顺序执行下边的代码
C.以此可以知道密码输入错误后会返回menu而不是终止while
//【头文件】
import java.util.Scanner;
import java.lang.Math;
//【结构体模块】 其实本来还想搞个花呗卡的,下次一定
abstract class Card {//父类常规卡
String Name;//开户人姓名
String ID;//卡号
String pas;//密码
String qus;//密保
String ans;//密保回答
double mon;//余额
boolean sex;//性别
Card() {
}
Card(String Name, String ID, String pas, String qus, String ans, boolean sex) {
this.Name = Name;
this.ID = ID;
this.pas = pas;
this.qus = qus;
this.ans = ans;
this.sex = sex;
}
public final void save(double t) {
mon += t;
System.out.printf("成功存款:%.2f元,当前余额:%.2f元\n\n", t, mon);
}
abstract void show();
abstract void gets(double t) throws noMoney;//取钱会出现错误
}//父类:卡类型
class sCard extends Card {
String type;
public sCard() {
super();
type = "储蓄卡";
mon = -1;
}
public sCard(String Name, String ID, String pas, String qus, String ans, boolean sex) {
super(Name, ID, pas, qus, ans, sex);//开户
type = "储蓄卡";
}
public void gets(double t) throws noMoney {
if (t > mon)
throw new noMoney();
else
mon -= t;
yy();
}//取钱,需要异常处理
public void show() {
System.out.printf("\n\n早上好!%s" + (sex ? "先生" : "女士"), Name);
System.out.printf(" 您的%s(%s) 余额:%.2f\n", type, ID, mon);
//true男士,false女士
}//基本卡面信息
public void yy() {
System.out.printf("当前余额:%.2f\n\n", mon);
}//显示余额
}//子类:储蓄卡
//【异常处理模块】
class noMoney extends Exception {
void why() {
System.out.printf("你太穷了哈哈哈哈(余额不足)!\n\n");
}
}//余额不足异常
class exit extends Exception {
void why() {
System.out.printf("当前账户已存在,不可再申请\n\n");
}
}//账户已经存在异常
class selExt extends Exception {
void why() {
System.out.printf("您的选择有误,重新输入!\n\n");
}
}//sel选择溢出
class wID extends Exception {
void why() {
System.out.printf("查无此ID!\n\n");
}
}//登陆ID异常
class wPA extends Exception {
void why() {
System.out.printf("登陆密码错误!\n\n");
}
}//登录密码错误
class wQU extends Exception {
void why() {
System.out.printf("密保回答错误!\n\n");
}
}//密保答案错误
//其实可以搞无参构造的,但是这样会导致大括号不能折叠,看起来很恶心
//【Main调动区】
class ASRC {//极光-科研中心
public static void main(String[] ASRC) {
Scanner sc = new Scanner(System.in);
int sel = 0;
sCard SXH = new sCard();//苏晓辉储蓄卡
while (sel != 4) {
menu(); //【操作界面1号-基础区域】
sel = sc.nextInt();
try {
switch (sel) {
case 1: {
if (SXH.mon != -1)
throw new exit();//抛出账户存在的异常
String name, id, pas, qus, ans;
System.out.printf("开户人姓名:");
name = sc.next();
System.out.printf("登录卡号:");
id = sc.next();
System.out.printf("账户密码:");
pas = sc.next();
System.out.printf("密保问题:");
qus = sc.next();
System.out.printf("密保答案:");
ans = sc.next();
boolean sex = true;
String sexx;
do {
System.out.printf("性别:");
sexx = sc.next();
if (sexx.equals("男"))
sex = true;
else if (sexx.equals("女"))
sex = false;
else
System.out.printf("性别输入有误,请重新输入!\n");
} while (!sexx.equals("男") && !sexx.equals("女"));
SXH = new sCard(name, id, pas, qus, ans, sex);
break;
}//开户
case 2: {
{
System.out.printf("账户ID:");
String id = sc.next();
if (!id.equals(SXH.ID))//ID异常处理
throw new wID();
System.out.printf("登陆密码:");
String pa = sc.next();
if (!pa.equals(SXH.pas))//密码异常处理
throw new wPA();
SXH.show();
}//登录模块
int idx = 2745;
while (idx != 4) {//登录成功【操作界面2号-登录区】
menu2(SXH);
idx = sc.nextInt();
try {
switch (idx) {
case 1: {
System.out.printf("存款金额:");
double t = sc.nextDouble();
SXH.save(t);
break;
}//存钱
case 2: {
System.out.printf("取款数额:");
double t = sc.nextDouble();
SXH.gets(t);
break;
}//取钱
case 3: {
SXH.yy();
break;
}//查询余额
case 4: {
System.out.printf("安全退出中.....");
break;
//啥也不干,等退出
}//退出
default: {
throw new selExt();
}//异常
}
} catch (noMoney e) {
e.why();
}//这里部署noMoney异常,就不会因为太穷被赶出银行
}
break;
}//登录
case 3: {
{
System.out.printf("%s?\n您回答:", SXH.qus);
String t = sc.next();
if (!t.equals(SXH.ans))
throw new wQU();
}//密保验证模块
int idx = 2745;
String t;
while (idx != 0) {
menu3(SXH);
idx = sc.nextInt();
try {
switch (idx) {
case 1: {
System.out.printf("修改开户人姓名为:");
SXH.Name = sc.next();
break;
}//name
case 2: {
System.out.printf("修改开户人ID为:");
SXH.ID = sc.next();
break;
}//id
case 3: {
System.out.printf("修改开户人密码为:");
SXH.pas = sc.next();
break;
}//password
case 4: {
System.out.printf("性别修改~");
SXH.sex = !SXH.sex;
break;
}//sex
case 5: {
System.out.printf("修改开户人密保为:");
SXH.qus = sc.next();
break;
}//密保
case 6: {
System.out.printf("修改密保答案为:");
SXH.ans = sc.next();
break;
}//ans
case 0: {
break;
}//退出
default: {
throw new selExt();
}
}
} catch (selExt e) {
e.why();
}
}
break;
}//修改密保
case 4: {
break;
}//退出
default: {
throw new selExt();
}//异常
}
} catch (exit e) {
e.why();
//只要创建异常实例,就会自动执行无参构造,里面不用写东西
} catch (selExt e) {
e.why();
} catch (wID e) {
e.why();
} catch (wPA e) {
e.why();
} catch (wQU e) {
e.why();
}
System.out.printf("\n\n\n");
}
}
//【静态辅助函数区域】Switch支持
public static void menu() {
System.out.printf("欢迎访问【苏晓辉银行】ATM系统\n");
System.out.printf("1-开户申请 2-登录系统\n");
System.out.printf("3-信息修改 4-退出\n");
System.out.printf("您决议:");
}
public static void menu2(sCard t) {
System.out.printf("选择您要办理的业务 当前余额:%.2f\n", t.mon);
System.out.printf("1-存钱 2-取钱 3-查询余额\n");
System.out.printf("4-安全退出\n您选择:");
}
public static void menu3(sCard t) {
System.out.printf("\n\n您已取得账户最高权限!\n");
System.out.printf("开户人姓名:%s 当前余额:%.2f\n", t.Name, t.mon);
System.out.printf("账户ID:%s\n", t.ID);
System.out.printf("密码:%s\n", t.pas);
System.out.printf("密保问题:%s\n", t.qus);
System.out.printf("密保答案:%s\n", t.ans);
System.out.printf("性别:%s\n", t.sex ? "男" : "女");
System.out.printf("您要修改的信息:\n");
System.out.printf("1-开户人姓名 2-账户ID\n");
System.out.printf("3-账户密码 4-性别\n");
System.out.printf("5-密保问题 6-密保回答\n");
System.out.printf("0-退出\n");
System.out.printf("您决议:");
}
}