一、实验目的
1.加深理解面向对象编程的概念,如类、对象、实例化等。
2.熟练掌握类的封装、继承和多态机制。
3.掌握编程常用的几种排序算法。
4.理解异常的产生过程和异常处理的概念,掌握C#异常处理的方法。
5.能够将面向对象思想应用与编程实践,开发出规模稍大的应用,如图书管理、银行卡存取款业务等。
二、实验内容
【实验3-2】银行卡存取款业务。
实验A:
假设某银行共发出M张储蓄卡,每张储蓄卡拥有唯一的卡号,每天每张储蓄卡至多支持持有者的N笔“存款”或“取款”业务。根据实际发生的业务,实时处理数据,以反映最新情况。
设储蓄卡包含的数据域有:卡号,当前余额,允许当日发生的业务次数(定义成静态变量,为所有Card类所共享),当日实际发生的业务数,以及一个数组记录发生的具体业务。它提供的主要方法有store(),处理判断是否超过当日允许发生的最大笔数,当前余额是否足以取款,以及实时修改当前数据等。
当持卡者输入正确的卡号、存款或取款金额后,程序进行相应的处理;若输入了不正确的数据,程序会提示持卡者重新输入;若输入的卡号为负数,银行终止当日业务。
实验B:
修改Card类,增加每日使用金额额度不超过5000的限制功能。
再次修改Card类,要求对银行卡进行操作前必须验证用户密码,并且在输入密码时屏幕上用“*”显示。为简单起见,初始密码设为123456。
三、实验步骤
实验A:
1.类:Card,属性:cardNo: long,balance: decimal,currentNum: int, number: static int,currentMoney: decimal[]
2.方法: Card(): 构造函数,初始化currentMoney数组;Card(long No, decimal Balance): 构造函数,初始化cardNo、balance和currentMoney数组;store(decimal Money, out int status): 存款或取款方法,更新balance和currentMoney数组,设置status状态;show(): 显示卡号、余额和存款/取款情况
3.静态属性:Number: 设置number值
4.属性: CardNo: 获取卡号
在EXP3步骤:
Main方法:
- 输入当日存款或取款总次数和储蓄卡总数
- 创建Card对象数组person
- 循环输入每张卡的卡号和余额
- 创建Card对象并添加到person数组中
5.进入业务处理循环
1)输入卡号
2)如果卡号小于0,结束循环
3)根据卡号定位到对应的Card对象
4)输入金额
5)调用Card对象的store方法进行存款或取款,并获取状态status
6)根据status打印相应的提示信息
7)调用Card对象的show方法显示卡号、余额和存款/取款情况
Locate(Card[] person, long cardNo)方法: 根据卡号定位到对应的Card对象,返回索引值或-1
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;namespace EXP3
{class Card{long cardNo;decimal balance;int currentNum;static int number;decimal[] currentMoney;public Card(){currentMoney = new decimal[number];}public Card(long No, decimal Balance){cardNo = No;balance = Balance;currentMoney = new decimal[number];}public void store(decimal Money, out int status){if (currentNum == number){status = 0;return;}if (balance + Money < 0){status = -1;return;}currentMoney[currentNum] = Money;balance += Money;currentNum++;status = 1;}public void show(){Console.WriteLine("卡号:{0},当前余额:{1},当日发生业务的次数:{2}", cardNo, balance, currentNum);for (int i = 0; i < currentNum; i++){Console.WriteLine("当前存款/取款的情况:{0}", currentMoney[i]);}}static public int Number{set{number = value;}}public long CardNo{get{return cardNo;}}}class EXP3{static void Main(string[] args){EXP3 E = new EXP3();Card[] person;int Num, status, k;long CardNo;decimal Balance, Money;Console.Write("请输入允许当日存款或取款的总次数:");string sline = Console.ReadLine();Card.Number = int.Parse(sline);Console.Write("请输入某银行发出的储蓄卡总数:");sline = Console.ReadLine();Num = int.Parse(sline);person = new Card[Num];for(int i = 0; i < Num; i++){Console.Write("请输入卡号:");sline = Console.ReadLine();CardNo = long.Parse(sline);Console.Write("请输入{0} 账户余额:", CardNo);sline = Console.ReadLine();Balance = decimal.Parse(sline);person[i] = new Card(CardNo, Balance);}while (true){Console.WriteLine("现在正在进行存款取款的业务处理,如果输入的卡号<0,则结束业务处理");Console.Write("请输入卡号:");sline = Console.ReadLine();CardNo = long.Parse(sline);if (CardNo < 0)break;k = E.Locate(person, CardNo);if (k == -1){Console.WriteLine("对不起,不存在{0}号的储蓄卡", CardNo);continue;}Console.WriteLine("请输入卡金额(正值代表存款,负值代表取款):");sline = Console.ReadLine();Money = decimal.Parse(sline);person[k].store(Money, out status);switch (status){case -1:Console.WriteLine("存款余额不足,不能完成本次的取款业务");break;case 0:Console.WriteLine("本卡已达到当日允许的业务次数");break;case 1:Console.WriteLine("成功处理完当前业务");person[k].show();break;}}}int Locate(Card[] person,long cardNo){for (int i = 0; i < person.Length; i++){if (person[i].CardNo == cardNo)return i;}return -1;}}
}
实验B:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;namespace EXP3
{class Card{long cardNo;decimal balance;int currentNum;static int number;decimal[] currentMoney;string password;public Card(){currentMoney = new decimal[number];password = "123456";}public Card(long No, decimal Balance){cardNo = No;balance = Balance;currentMoney = new decimal[number];password = "123456";}public void store(decimal Money, out int status){if (currentNum == number){status = 0;return;}if (balance + Money < 0){status = -1;return;}if (Money > 5000 || Money < -5000){status = -2;return;}currentMoney[currentNum] = Money;balance += Money;currentNum++;status = 1;}public void show(){Console.WriteLine("卡号:{0},当前余额:{1},当日发生业务的次数:{2}", cardNo, balance, currentNum);for (int i = 0; i < currentNum; i++){Console.WriteLine("当前存款/取款的情况:{0}", currentMoney[i]);}}static public int Number{set{number = value;}}public long CardNo{get{return cardNo;}}public bool VerifyPassword(string input){return password == input;}}class EXP3{static void Main(string[] args){EXP3 E = new EXP3();Card[] person;int Num, status, k;long CardNo;decimal Balance, Money;Console.Write("请输入允许当日存款或取款的总次数:");string sline = Console.ReadLine();Card.Number = int.Parse(sline);Console.Write("请输入某银行发出的储蓄卡总数:");sline = Console.ReadLine();Num = int.Parse(sline);person = new Card[Num];for (int i = 0; i < Num; i++){Console.Write("请输入卡号:");sline = Console.ReadLine();CardNo = long.Parse(sline);Console.Write("请输入{0} 账户余额:", CardNo);sline = Console.ReadLine();Balance = decimal.Parse(sline);person[i] = new Card(CardNo, Balance);}while (true){Console.WriteLine("现在正在进行存款取款的业务处理,如果输入的卡号<0,则结束业务处理");Console.Write("请输入卡号:");sline = Console.ReadLine();CardNo = long.Parse(sline);if (CardNo < 0)break;k = E.Locate(person, CardNo);if (k == -1){Console.WriteLine("对不起,不存在{0}号的储蓄卡", CardNo);continue;}Console.WriteLine("请输入密码:");string password = ReadPassword();if (!person[k].VerifyPassword(password)){Console.WriteLine("密码错误");continue;}Console.WriteLine("请输入卡金额(正值代表存款,负值代表取款):");sline = Console.ReadLine();Money = decimal.Parse(sline);person[k].store(Money, out status);switch (status){case -1:Console.WriteLine("存款余额不足,不能完成本次的取款业务");break;case -2:Console.WriteLine("每日使用金额超过限制(5000),不能完成本次的存款或取款业务");break;case 0:Console.WriteLine("本卡已达到当日允许的业务次数");break;case 1:Console.WriteLine("成功处理完当前业务");person[k].show();break;}}}int Locate(Card[] person, long cardNo){for (int i = 0; i < person.Length; i++){if (person[i].CardNo == cardNo)return i;}return -1;}private static string ReadPassword(){string password = "";ConsoleKeyInfo keyInfo;do{keyInfo = Console.ReadKey(true);if (keyInfo.Key != ConsoleKey.Backspace && keyInfo.Key != ConsoleKey.Enter){password += keyInfo.KeyChar;Console.Write("*");}else{if (keyInfo.Key == ConsoleKey.Backspace && password.Length > 0){password = password.Substring(0, (password.Length - 1));Console.Write("\b \b");}}} while (keyInfo.Key != ConsoleKey.Enter);Console.WriteLine();return password;}}
}
四、实验结果展示
实验A:
实验B:
五、实验小结
该实验在程序开始时,用户需要输入允许当日存款或取款的总次数和某银行发出的储蓄卡总数,然后,根据输入的卡号和账户余额创建相应的储蓄卡对象;用户可以进行存款或取款的业务处理。用户输入要操作的卡号,如果输入的卡号小于0,则结束业务处理。程序会检查输入的卡号是否存在,并要求输入密码进行验证。然后用户输入要存取的金额,程序会对金额进行合法性检查,如余额是否充足、每日使用金额是否超过限制等。根据检查结果,程序会输出相应的提示信息,并更新储蓄卡的余额和操作次数;程序中还包括一个Locate方法,用于根据卡号在储蓄卡数组中查找对应的储蓄卡对象。从时间复杂度的角度来看,该程序的主要操作是在存取款业务处理循环中进行的。在每次循环中,需要进行卡号的查找、密码验证和金额合法性检查等操作,操作的时间复杂度都是O(n),其中n为储蓄卡数组的长度。因此,整个程序的时间复杂度为O(N*M),其中N为储蓄卡总数,M为当日存款或取款的总次数。
通过实验,将面向对象的思想应用于银行卡存取款业务中。这种思想的应用可以使代码更加模块化、可扩展和易维护。在实际开发中,我可以学习将面向对象思想应用于开发规模稍大的应用,如图书管理系统、银行系统等。这样的实际开发中,根据需求设计不同的类和对象,并通过封装、继承和多态来实现复杂的业务逻辑,提高开发效率和代码质量。