实验二
实验目的
1. 加深理解面向对象编程的概念,如类、对象、实例化等。
2. 熟练掌握类的封装、继承和多态机制。
3. 掌握编程常用的几种排序算法。
4. 理解异常的产生过程和异常处理的概念,掌握C#异常处理的方法。
5. 能够将面向对象思想应用于编程实践,开发出规模稍大的应用,如图书管理、 银行卡存取款业务等。
实验内容
①实验3-1:图书管理应用
设计一个图书卡片类Card,用来保存图书馆卡片分类记录。这个类的成员包括书名、作者、馆藏数量。至少提供两个方法:
store——书的入库处理;
show——显示图书信息。
程序运行时,可以从控制台上输入需入库图书的总数,根据这个总数创建Card对象数组,然后输入数据,最后可以选择按书名、作者或入库量排序。
跟着学习
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace shiyan3_1
{
class Card
{
private string title, author;
private int total;
public Card()
{
title = "";author = "";
total = 0;
}
public Card (string title,string author,int total)
{
this.total = total;
this.author = author;
this.title = title;
}
public void store(ref Card card)
{
title = card.title;author = card.author;total = card.total;
}
public void show()
{
Console.WriteLine("Title:{0},Autho:{1},Tatal:{2}", title, author, total);
}
public string Title
{
get { return title; }
set { title = value; }
}
public string Author
{
get { return author; }
set { author = value; }
}
public int Total
{
get { return total; }
set { total = value; }
}
}
class shiyan3_1
{
static void Main(string[] args)
{
shiyan3_1 T = new shiyan3_1();
Card[] books;
int[] index;
int i, k;
Card card = new Card();
Console.Write("请输入需要入库的图书总数:");
string sline = Console.ReadLine();
int num = int.Parse(sline);
books = new Card[num];
for (i = 0; i < num; i++)
books[i] = new Card();
index = new int[num];
for(i=0;i< num;i++)
{
Console.Write("请输入书名:");
card.Title = Console.ReadLine();
Console.Write("请输入作者:");
card.Author = Console.ReadLine();
Console.Write("请输入入库量:");
sline = Console.ReadLine();
card.Total = int.Parse(sline);
books[i].store(ref card);
index[i] = i;
}
Console.Write("请选择按什么关键字排序(1.按书名,2.按作者,3.按入库量)");
sline = Console.ReadLine();
int choice = int.Parse(sline);
switch (choice)
{
case 1:
T.sortTitle(books, index);
break;
case 2:
T.sortAuthor(books, index);
break;
case 3:
T.sortAuthor(books, index);
break;
}
for (i = 0; i < num; i++)
{
k = index[i];
(books[k]).show();
}
Console.Read();
}
void sortTitle(Card[] book, int[] index)
{
int i, j, m, n, temp;
for (m = 0; m < index.Length - 1; m++)
for (n = 0; n < index.Length - m - 1; n++)
{
i = index[n]; j = index[n + 1];
if (String.Compare(book[i].Title, book[j].Title) > 0)
{
temp = index[n]; index[n] = index[n + 1]; index[n + 1] = temp;
}
}
}
void sortAuthor(Card[] book, int[] index)
{
int i, j, n, m, temp;
for (m = 0; m < index.Length - 1; m++)
for (n = 0; n < index.Length - m - 1; n++)
{
i = index[n]; j = index[n + 1];
if (String.Compare(book[i].Title, book[j].Title) > 0)
{
temp = index[n]; index[n] = index[n + 1]; index[n + 1] = temp;
}
}
}
void sortTolal(Card[] book, int[] index)
{
int i, j, m, n, temp;
for (m = 0; m < index.Length - 1; m++)
for (n = 0; n < index.Length - m - 1; n++)
{
i = index[n]; j = index[n + 1];
if (book[i].Total > book[j].Total)
{
temp = index[n]; index[n] = index[n + 1]; index[n + 1] = temp;
}
}
}
}
}
实验结果
自己思考
将上述程序中class Test3_1中的三个方法:
void sortTitle(Card[] book, int[] index)
void sortAuthor(Card[] book, int[] index)
void sortTotal(Card[] book, int[] index)
改写成一个方法sort(Card[] book,int[] index,int method),其中增加的参数method指示按什么字段排序。
重新修改、编译和运行程序,观察运行结果。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace shiyan3_1
{
class Card
{
private string title, author;
private int total;
public Card()
{
title = "";author = "";
total = 0;
}
public Card (string title,string author,int total)
{
this.total = total;
this.author = author;
this.title = title;
}
public void store(ref Card card)
{
title = card.title;author = card.author;total = card.total;
}
public void show()
{
Console.WriteLine("Title:{0},Autho:{1},Tatal:{2}", title, author, total);
}
public string Title
{
get { return title; }
set { title = value; }
}
public string Author
{
get { return author; }
set { author = value; }
}
public int Total
{
get { return total; }
set { total = value; }
}
}
class shiyan3_1
{
static void Main(string[] args)
{
shiyan3_1 T = new shiyan3_1();
Card[] books;
int[] index;
int i, k;
Card card = new Card();
Console.Write("请输入需要入库的图书总数:");
string sline = Console.ReadLine();
int num = int.Parse(sline);
books = new Card[num];
for (i = 0; i < num; i++)
books[i] = new Card();
index = new int[num];
for(i=0;i< num;i++)
{
Console.Write("请输入书名:");
card.Title = Console.ReadLine();
Console.Write("请输入作者:");
card.Author = Console.ReadLine();
Console.Write("请输入入库量:");
sline = Console.ReadLine();
card.Total = int.Parse(sline);
books[i].store(ref card);
index[i] = i;
}
Console.Write("请选择按什么关键字排序(1.按书名,2.按作者,3.按入库量)");
sline = Console.ReadLine();
int choice = int.Parse(sline);
T.sort(books, index, choice);
for (i = 0; i < num; i++)
{
k = index[i];
(books[k]).show();
}
Console.Read();
}
void sort(Card[] book,int[] index,int method)
{
int i, j, m, n, temp;
switch(method)
{
case 1:
for(m=0;m<index.Length-1;m++)
for(n=0;n<index.Length-m-1;n++)
{
i = index[n];j = index[n + 1];
if(string.Compare(book[i].Title,book[j].Title)>0)
{
temp = index[n];index[n] = index[n + 1];index[n + 1] = temp;
}
}
break;
case 2:
for (m = 0; m < index.Length - 1; m++)
for (n = 0; n < index.Length - m - 1; n++)
{
i = index[n]; j = index[n + 1];
if (string.Compare(book[i].Title, book[j].Title) > 0)
{
temp = index[n]; index[n] = index[n + 1]; index[n + 1] = temp;
}
}
break;
case 3:
for (m = 0; m < index.Length - 1; m++)
for (n = 0; n < index.Length - m - 1; n++)
{
i = index[n]; j = index[n + 1];
if (book[i].Total>book[j].Total)
{
temp = index[n]; index[n] = index[n + 1]; index[n + 1] = temp;
}
}
break;
}
}
}
}
实验结果
②实验2-4 银行卡存取款业务
假设某银行共发出M张储蓄卡,每张储蓄卡拥有唯一的卡号,每天每张储蓄卡至多支持持有者的N笔“存款”或“取款”业务。根据实际发生的业务,实时处理数据,以反映最新情况。
设储蓄卡包含的数据域有:卡号,当前余额,允许当日发生的业务次数(定义成静态变量,为所有Card类所共享),当日实际发生的业务数,以及一个数组记录发生的具体业务。它提供的主要方法有store(),处理判断是否超过当日允许发生的最大笔数,当前余额是否足以取款,以及实时修改当前数据等。
当持卡者输入正确的卡号、存款或取款金额后,程序进行相应的处理;若输入了不正确的数据,程序会提示持卡者重新输入;若输入的卡号为负数,银行终止当日业务。
跟着学习:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace shiyan3_2
{
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 shiyan3_2
{
static void Main(string[] args)
{
shiyan3_2 T = new shiyan3_2();
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 = T.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)
{
//此处补充完整
int index = -1;
for(int i=0;i<person.Length;i++)
{
if(person[i].CardNo==cardNo)
{
index = i;
}
}
return index;
}
}
}
实验结果
自己思考
修改Card类,增加每日使用金额额度不超过5000的限制功能。
2. 再次修改Card 类,要求对银行卡进行操作前必须验证用户密码,并且在输入密码时屏幕上用“*”显示。为简单起见,初始密码均设为123456。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace shiyan3_2
{
class Card
{
long cardNo;
decimal balance;
int currentNum;
static int number;
decimal[] currentMoney;
decimal m = 0;
string passward;
public Card()
{
currentMoney = new decimal[number];
}
public Card(long No, decimal Balance,string Passward)
{
cardNo = No;
balance = Balance;
passward = Passward;
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;
}
m = 0;
for(int i=0;i<currentNum;i++)
{
m = System.Math.Abs(currentMoney[i]) + m;
}
m=m+System.Math.Abs(Money);
if(m>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 string PASSWORD
{
get
{
return passward;
}
}
}
class shiyan3_2
{
static void Main(string[] args)
{
shiyan3_2 T = new shiyan3_2();
Card[] person;
int Num, status, k = 0;
string Password = null;
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);
Console.Write("请输入{0}账户密码: ", CardNo);
Password = Console.ReadLine();
person[i] = new Card(CardNo, Balance, Password);
}
while (true)
{
Console.WriteLine("现在正进行存款取款的业务办理,如果输入卡号<0,则结束业务处理");
Console.Write("请输入卡号: ");
sline = Console.ReadLine();
CardNo = long.Parse(sline);
if (CardNo < 0)
{
break;
}
k = T.Locate(person, CardNo);
if (k == -1)
{
Console.WriteLine("对不起,不存在{0}号的储蓄卡", CardNo);
continue;
}
string input = null;
Console.WriteLine("请输入储蓄卡的密码");
LL:
while (true)
{
ConsoleKeyInfo ck = Console.ReadKey(true);
if (ck.Key != ConsoleKey.Enter)
{
if (ck.Key != ConsoleKey.Backspace)
{
input += ck.KeyChar.ToString();
Console.Write(".");
}
else
{
Console.Write("\b\b");
}
}
else
{
Console.WriteLine();
break;
}
}
if (person[k].PASSWORD != input)
{
Console.WriteLine("请重新输入密码:");
input = null;
goto LL;
}
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;
case 2:
Console.WriteLine("当日提取金额超过5000,不能办理此业务");
break;
}
}
}
int Locate(Card[] person, long cardNo)
{
int index = -1;
for (int i = 0; i < person.Length; i++)
{
if (person[i].CardNo == cardNo)
{
index = i;
}
}
return index;
}
}
}
实验结果: