类设计
银行卡共有储蓄卡(Account)与信用卡(Credit)两种
在银行类(bank)中添加Account类的成员,ATM类要实现银行的业务,BankDemo用于编写main方法测试功能。
源码
BankDemo类:
using System;
namespace BankDemo
{
public class BankDemo {
public static void Main(string[] args) {
Bank bank = new Bank();
// 插入初始数据
bank.OpenAccount("2222", "2222", 20);
bank.OpenAccount("3333", "3333", 50);
bank.OpenCredit("4444","4444",100,1000);
ATM atm = new ATM(bank);
bool login_ctr = false; // 用于控制登录逻辑
bool service_ctr = true; // 用于控制业务逻辑
while (!login_ctr)
{
Account account = atm.Login();
if (account == null) // 登录失败
{
Console.WriteLine("card invalid or password not corrent,please retry again");
service_ctr = false;
}
else // 登录成功
{
service_ctr = true; // 可以开始业务
}
while (service_ctr)
{
//login_ctr = true; // 登录成功
service_ctr = atm.Transaction(account);
}
Console.ReadKey(); // 停顿一下
Console.Clear(); // 清屏
}
}
}
}
Account类:
using System;
using System.Collections.Generic;
using System.Text;
namespace BankDemo
{
public class Account
{
protected double _money; //decimal money;
protected string _id;
protected string _pwd; //string name;
public Account(string id, string pwd, double money)
{ //if( money < 0 ) throw new Exception("....");
Id = id;
Pwd = pwd;
Money = money;
}
public Account() { }
public double Money
{
set { _money = value; }
get { return _money; }
}
public string Id
{
set { _id = value; }
get { return _id; }
}
public string Pwd
{
set { _pwd = value; }
get { return _pwd; }
}
public virtual bool SaveMoney(double money)
{
if (money < 0) return false; //卫语句
Money += money;
return true;
}
public virtual bool WithdrawMoney(double money)
{
if (Money >= money) {
Money -= money;
return true;
}
return false;
}
public bool IsMatch(string id, string pwd) {
return id == Id && pwd == Pwd;
}
}
}
ATM类:
using System;
using System.Collections.Generic;
using System.Text;
namespace BankDemo
{
public class ATM
{
Bank bank;
public ATM(Bank bank)
{
this.bank = bank;
}
// 优化用户登录逻辑
public Account Login()
{
Show("please insert your card");
string id = GetInput();
Show("please enter your password");
string pwd = GetInput();
Account account = bank.FindAccount(id, pwd);
return account;
}
public bool Transaction(Account account)
{
Show("1: display; 2: save; 3: withdraw; 4. exit");
string op = GetInput();
// 显示余额
if (op == "1")
{
Show("balance: " + account.Money);
if (account is Credit)
{
Credit c = (Credit)account;
if (c.Spend > 0)
{
Show("您已欠款:" + c.Spend + "元");
}
}
}
// 还款/存钱
else if (op == "2")
{
Show("save money");
string smoney = GetInput();
double money = double.Parse(smoney);
bool ok = account.SaveMoney(money);
if (ok) Show("ok");
else Show("eeer");
Show("balance: " + account.Money);
if (account is Credit)
{
Credit c = (Credit)account;
if(c.Spend > 0)
{
Show("您仍需要还款:"+c.Spend+"元");
}
}
}
// 体现
else if (op == "3")
{
Show("withdraw money");
string smoney = GetInput();
double money = double.Parse(smoney);
bool ok = account.WithdrawMoney(money);
if (ok)
{
Show("取款成功!");
if (account is Credit)
{
Credit c = (Credit)account;
if(c.Spend > 0)
{
Show("您已透支:" + c.Spend + "元,还可透支:" + (c.Quota - c.Spend) + "元");
}
else
{
Show("balance: " + account.Money);
}
}
}
else
{
if (account is Credit)
{
Show("您提取的金额超过您的可透支额度!无法为您提供取款服务");
}
else
{
Show("您提取的金额超过了您的总余额!无法为您提供取款服务");
}
}
}
// 退出登录
if (op == "4")
{
//account = null;
Show("退出成功!");
return false;
}
return true;
}
public void Show(string msg)
{
Console.WriteLine(msg);
}
public string GetInput()
{
return Console.ReadLine();// 输入字符
}
}
}
Bank类:
using System;
using System.Collections;
using System.Collections.Generic;
using System.Text;
namespace BankDemo
{
public class Bank
{
List<Account> accounts = new List<Account>(); // 生成Account对象序列
public Account OpenAccount(string id, string pwd, double money) // 初始化Account对象
{
Account account = new Account(id, pwd, money);
accounts.Add(account); // 将account添加到Account对象序列中
return account;
}
public bool CloseAccount(Account account)
{
int idx = accounts.IndexOf(account);
if (idx < 0) return false;
accounts.Remove(account);
return true;
}
// 寻找是否存在目标用户
public Account FindAccount(string id, string pwd)
{
foreach (Account account in accounts)
{
if (account.IsMatch(id, pwd))
{
return account;
}
}
return null;
}
// 信用卡业务
public Account OpenCredit(string id, string pwd, double money, double quota)
{
Account account = new Credit(id,pwd,money,quota); // 使用多态将父类account对象指向子类的Credit对象
accounts.Add(account);
return account;
}
}
}
Credit类:
using System;
using System.Collections.Generic;
using System.Text;
namespace BankDemo
{
class Credit:Account
{
// 构造函数
public Credit(string id, string pwd, double money,double quota):base( id, pwd, money) // 构造函数,将id,pwd,money交给Account类去生成
{
Quota = quota;
}
private double quota ; // 额度
private double spend; // 已用
// 属性
public double Quota {
set { quota = value; }
get { return quota; }
}
public double Spend
{
set { spend = value; }
get { return spend; }
}
// 覆盖父类的取钱
/*
信用与储蓄卡的不同之处主要是信用卡可以透支
怎样去实现透支功能呢?
首先,我们要有个透支的额度;当需要用的钱大于余额,余额为0,可透支额度减少。
*/
public override bool WithdrawMoney(double money)
{
double temp = Money - money;
if (temp > 0)
{
Money -= money;
return true;
}
else if(temp < 0)
{
if (temp > (Spend-Quota))
{
Spend += temp;
Spend = (-Spend);
//Quota += temp;
Money = 0;
return true; // 取钱成功
}
}
return false;
}
// 还款
/*
1.当输入的金额是负数,报错
2.当存在欠款时优先还欠款,多出来的存到余额
*/
public override bool SaveMoney(double money)
{
if (money < 0) return false; //卫语句
if (Spend > 0)
{
if ((Spend-money) <= 0)
{
Money += (-(Spend - money));
Spend = 0;
}
}
else
{
Money += money;
}
return true;
}
}
}
总结
除了完成作业的基本要求,我还优化了程序的执行逻辑,原本的程序,登录成功后完成一次业务操作则需要重新登录,十分麻烦!而且当5次操作后,程序将会关闭。经过我的优化后,用户可登录成功一次后,进行无数次的业务操作直到用户自己退出登录为止。为了数据的安全,我还修改了一些重要字段的修饰词。在ATM类中,由于新增了信用卡业务,所以在进行业务处理的时候添加了判断是否为信用卡的判断功能,当是信用卡时,需要显示欠费状况。用到本章学到的多态、继承、重载、重写等知识。在Bank类中,Credit类继承了Account类,用Account父类指向了Credit对象,从而实现将信用卡的对象添加到Account类的序列中,无需大规模改写代码。