一.主要功能:
1.实现租车功能。
选中一辆租车信息,输入租车者姓名,即可租车成功!在未租列表中点击刷新该车辆显示,在租车列表中会出现对应的租车信息将会消失。

2.实现还车功能。
选中一辆还车信息,输入使用天数,进行结算。点击租车列表中的刷新按钮该车辆信息会显示,在未租列表中该车辆会消失。

3.实现新车入库功能。
选择入库的汽车类型,填写对应车辆的信息,进行汽车入库,在未租列表中点击刷新按钮就会显示刚才添加的车辆信息。

2.思路:
根据日常生活中的租车案例,咋们都知道租车是分种类的,在这里呢,轿车和卡车属于一种交通工具的,所以要在我们的程序中就要抽象出一个交通工具类(Vechile)作为父类,
抽象出对应的子类就是轿车类(Car)和卡车类(Truck),到了这里,还别忘还有一个工厂类(VechileFactory),是用来示例化子类的对象,在这里需要注意的是,简单工厂类里的方法是静态的,
返回值是父类类型,也就是Vechile类,需要传入参数,在方法体中,通过switch选择结构进行选择,到底实例化哪个子类对象。
首先有这么几个类:

01.Vehicle类:
是一个交通工具类(抽象类,也是父类),在他的底层统领着两个子类,分别是Car类,和Truck类,在这个类中有一个计算价格的方法。
//父类:交通工具类
public abstract class Vehicle
{
public string Color { get; set; }//汽车颜色
public int DailyRent { get; set; }//每日租金
public string LicenseNo { get; set; }//车牌号
public string Name { get; set; }//车名
public int RentDate { get; set; }//还车日期
public string Rentuser { get; set; }//还车人
public int YearsOfService{ get; set; }//使用时间
//无参构造
public Vehicle() { }
//带参构造用于给属性赋值
public Vehicle(string color, int dailyrent, string licenseno, string name, int YearsOfService)
{
this.Color = color;
this.DailyRent = dailyrent;
this.LicenseNo = licenseno;
this.Name = name;
this.YearsOfService = YearsOfService;
}
//计算价格的方法
public abstract double CalculatePrice();
}
02.Car类(轿车):Vechile的子类。
//小汽车类继承自交通工具类
public class Car:Vehicle
{
//无参构造
public Car() { }
//带参构造
public Car(string color, int dailyrent, string licenseno, string name, int YearsOfService) :
base( color,dailyrent,licenseno,name,YearsOfService)
{
}
//重写计算价格的方法
public override double CalculatePrice()
{
//定义变量保存价格
double SumPrice = this.DailyRent * RentDate;
return SumPrice;
}
}
03.Truck类(卡车):Vechile的子类
//卡车类继承自交通工具类
public class Truck:Vehicle
{
public int weight { get; set; }//卡车的重量
public Truck() { }
public Truck(string color, int dailyrent, string licenseno, string name, int YearsOfService,int weight):
base( color,dailyrent,licenseno,name,YearsOfService)
{
this.weight = weight;
}
//计算价格的方法
public override double CalculatePrice()
{
//定义变量保存价格
double SumPrice = this.DailyRent * RentDate;
return SumPrice;
}
04.工厂类VechileFactory
//工厂
public class VehicleFactory
{
//第一一个静态方法,返回值类型是父类类型,传入参数
public static Vehicle CreateVehicle(string color, int dailyrent, string licenseno, string name, int YearsOfService, int weight,string type)
{
//给对象赋null值
Vehicle vehicle = null;
switch (type)
{
case"轿车":
vehicle = new Car( color, dailyrent, licenseno, name, YearsOfService);
break;
case"卡车":
vehicle = new Truck(color, dailyrent, licenseno, name, YearsOfService, weight);
break;
}
return vehicle;
}
}
FrmMain窗体:
//定义一个字典集合保存租车(还未租出的车辆)信息k:车牌号,V父类对象
public Dictionary<string, Vehicle> dic = new Dictionary<string, Vehicle>();
//第一一个集合保存已租车辆的信息
public Dictionary<string, Vehicle> outdic = new Dictionary<string, Vehicle>();
//点击退出触发的事件
private void btnrefurbish_Click(object sender, EventArgs e)
{
Application.Exit();
}
//load事件
private void FrmMain_Load(object sender, EventArgs e)
{
//01.初始化泛型集合(添加数据到集合中去)
Car car = new Car("红色", 500, "京P-34566", "奔驰", 3);
Car car1 = new Car("白色", 1000, "京Q-XH456", "保时捷", 2);
Truck truck = new Truck("蓝色", 200, "贵-B300挂", "变形金刚",5,100);
dic.Add(car.LicenseNo, car);
dic.Add(car1.LicenseNo, car1);
dic.Add(truck.LicenseNo, truck);
//02写一个方法显示到窗体的listview空间中
dictolvlist(dic,lvlist);
//03,给新车入库的颜色下拉框绑定值
comcolor.Items.Add("红色");
comcolor.Items.Add("蓝色");
comcolor.Items.Add("白色");
comcolor.Items.Add("黑色");
comcolor.Items.Add("灰色");
}
public void dictolvlist(Dictionary<string,Vehicle> dic,ListView lv)
{
//创建一个listviewitem对象,赋值为null
ListViewItem item = null;
//显示数据之前,清除数据
lv.Items.Clear();
foreach (Vehicle itemdic in dic.Values)
{
if (itemdic is Car)
{
//实例化对象
item = new ListViewItem();
item.Text = itemdic.LicenseNo;
item.SubItems.Add(itemdic.Name);
item.SubItems.Add(itemdic.Color);
item.SubItems.Add(itemdic.YearsOfService.ToString());
item.SubItems.Add(itemdic.DailyRent.ToString());
}
else
{
//实例化对象
item = new ListViewItem();
item.Text = itemdic.LicenseNo;
item.SubItems.Add(itemdic.Name);
item.SubItems.Add(itemdic.Color);
item.SubItems.Add(itemdic.YearsOfService.ToString());
item.SubItems.Add(itemdic.DailyRent.ToString());
//as等同于类型转换
item.SubItems.Add((itemdic as Truck).weight.ToString());
}
//让游离得Listviewitem对象和lvlsiit空间产生关系
lv.Items.Add(item);
}
}
//点击租车触发的事件
private void btnrentcar_Click(object sender, EventArgs e)
{
//01确保选中了一个车俩
if(lvlist.SelectedItems.Count==0)
{
MessageBox.Show("请选中你要租的车辆!");
return;
}
//02确保填写了租用值名字
if (txtrent.Text=="")
{
MessageBox.Show("请填写姓名!");
return;
}
//03验证信息完成!开始租车过程
//获取lvlist第一项的值车号
string carnum = lvlist.SelectedItems[0].Text;
//通过dic集合的key获取整个汽车对象
Vehicle vehicle= dic[carnum];
//在集合中删除该项记录
dic.Remove(carnum);
//重新绑定数据,调用方法dictolvlist即可
dictolvlist(dic,lvlist);
//将已租车辆放入到已租集合中
outdic.Add(carnum, vehicle);
MessageBox.Show("租车成功!");
//清空文本框中的值
txtrent.Text = "";
}
//在还车界面点击刷新触发的事件
private void btnrefurbish11_Click(object sender, EventArgs e)
{
dictolvlist(outdic,lvlisttwo);
}
//点击选择结算触发的事件
private void btnselectsettleaccounts_Click(object sender, EventArgs e)
{
if(lvlisttwo.SelectedItems.Count==0)
{
MessageBox.Show("请选择要退还的车辆!");
return;
}
//确保用户填写了租用天数
if (txtrentday.Text=="")
{
MessageBox.Show("请填写租用天数!");
return;
}
//执行还车步骤
//获取listviewtow中的选中项的车牌号
string carnum = lvlisttwo.SelectedItems[0].Text;
//从已租集合中通过key值找到汽车完整对象
Vehicle vehicle= outdic[carnum];
//给还车日期属性赋值
vehicle.RentDate = Convert.ToInt32(txtrentday.Text);
//计算价格
double summoney=vehicle.CalculatePrice();
//添加到未租车辆中
dic.Add(carnum, vehicle);
//删除已租车辆的该车辆信息
outdic.Remove(carnum);
//重新绑定数据
dictolvlist(outdic, lvlisttwo);
MessageBox.Show("需支付金额"+summoney.ToString());
//清空文本框中的值
txtrentday.Text = "";
}
//点击刷新触发的事件
private void btnrefurbish_Click_1(object sender, EventArgs e)
{
dictolvlist(dic, lvlist);
}
//点击入库触发的事件
private void btnok_Click(object sender, EventArgs e)
{
try
{
//01获取对应文本框中的值,
string carnum = txt.Text;//车号
string cartype = txtcartype.Text;//车型
string color = comcolor.Text;//颜色
int endtime = Convert.ToInt32(txttime.Text);//使用时间
int money = Convert.ToInt32(txtdaymoney.Text);//每日租金
int weight = 0;
if (rbcar.Checked == true)
{
//01写一个方法判断用户信息填写是否填写完整
if (isnulltwo() == true)
{
//执行到这证明信息已经验证完成
//调用工厂类,传入对应类型汽车,获取对应子类对象
//获取对应子类对象
Vehicle vehicle = VehicleFactory.CreateVehicle(color, money, carnum, cartype, endtime, weight, rbcar.Text);
//添加到集合中去
dic.Add(carnum, vehicle);
MessageBox.Show("添加成功!");
}
}
else if (rbtruck.Checked == true)
{
if (isnull() == true)
{
weight = Convert.ToInt32(txttruckweight.Text);//卡车载重
//获取对应子类对象
Vehicle vehicle = VehicleFactory.CreateVehicle(color, money, carnum, cartype, endtime, weight, rbtruck.Text);
//添加到集合中去
dic.Add(carnum, vehicle);
MessageBox.Show("添加成功!");
}
}
//调用清空文本框中的值的方法
infoclear();
}
catch (Exception)
{
MessageBox.Show("输入格式有误!");
}
}
//判断新车入库中填写信息是否完整
public bool isnull()
{
if (rbcar.Checked==false&&rbtruck.Checked==false)
{
MessageBox.Show("请选择添加的车辆类型!");
return false;
}
else if (txt.Text == "" || txtcartype.Text == "" || comcolor.Text == "" || txttime.Text == "" || txtdaymoney.Text == "" || txttruckweight.Text == "")
{
MessageBox.Show("请填写完整的信息!");
return false;
}
else
{
return true;
}
}
public bool isnulltwo()
{
if (rbcar.Checked == false && rbtruck.Checked == false)
{
MessageBox.Show("请选择添加的车辆类型!");
return false;
}
else if (txt.Text == "" || txtcartype.Text == "" || comcolor.Text == "" || txttime.Text == "" || txtdaymoney.Text == "")
{
MessageBox.Show("请填写完整的信息!");
return false;
}
else
{
return true;
}
}
//单机卡车触发的事件
private void rbtruck_Click(object sender, EventArgs e)
{
if (rbtruck.Checked == true)
{
txttruckweight.Enabled = true;
lbltruckweight.ForeColor = Color.Blue;
}
}
//单机轿车触发的事件
private void rbcar_Click(object sender, EventArgs e)
{
if (rbcar.Checked == true)
{
txttruckweight.Enabled = false;
lbltruckweight.ForeColor = Color.Red;
}
}
//清空文本框中的值的方法
public void infoclear()
{
txt.Text = "";
txtcartype.Text = "";
comcolor.Text = "" ;
txttime.Text = "";
txtdaymoney.Text = "";
txttruckweight.Text = "";
}
