c#:使用面向对象的编程思想和窗体实现计算器(二目运算)
最近一直在学面向对象的编程思想,什么封装呀、继承呀、枚举呀什么的,但是不会在实例中应用,那么接下来我们就用面向对象的编程思想结合窗体来给大家做一个小小的案例——计算器,希望你们能够从这个案例体会到面向对象的好处,并且会使用这个思想。
一、使用窗体设计界面
前端这个没啥说的,就是拖拉textBox、Buttom控件,并设置文本以及大小,
1、用Button按钮主要是实现数字区域以及运算符区域,并且按下控件的事件—在textBox中显示运算结果和式子
2、用textBox控件就是主要显示数字、运算符、以及运算结果,其中上边的是显示式子,下边的是显示结果
1、窗体的加载事件:
private void Form1_Load(object sender, EventArgs e)
{
this.Text = "计算器";
this.Opacity = 0.9;//设置窗体的不透明度
this.MaximizeBox = false;//窗体最大化按钮不可用
this.CenterToScreen();//设置窗体在显示器中居中显示
}
2、数字区域:
//数字嘛就是0-9,然后他们都是按钮,也就是说当按下某个数字就在textBox1和textBox2中显示,为了使数字不被替换使用‘+’链接
#region 数字0-9
#region 数字1
private void button1_Click(object sender, EventArgs e)
{
textBox1.Text += 1;
textBox2.Text += 1;
}
#endregion
#region 数字2
private void button2_Click(object sender, EventArgs e)
{
textBox1.Text += 2;
textBox2.Text += 2;
}
#endregion
#region 数字3
private void button3_Click(object sender, EventArgs e)
{
textBox1.Text += 3;
textBox2.Text += 3;
}
#endregion
#region 数字4
private void button4_Click(object sender, EventArgs e)
{
textBox1.Text += 4;
textBox2.Text += 4;
}
#endregion
#region 数字5
private void button5_Click(object sender, EventArgs e)
{
textBox1.Text += 5;
textBox2.Text += 5;
}
#endregion
#region 数字6
private void button6_Click(object sender, EventArgs e)
{
textBox1.Text += 6;
textBox2.Text += 6;
}
#endregion
#region 数字7
private void button7_Click(object sender, EventArgs e)
{
textBox1.Text += 7;
textBox2.Text += 7;
}
#endregion
#region 数字8
private void button8_Click(object sender, EventArgs e)
{
textBox1.Text += 8;
textBox2.Text += 8;
}
#endregion
#region 数字9
private void button9_Click(object sender, EventArgs e)
{
textBox1.Text += 9;
textBox2.Text += 9;
}
#endregion
#region 数字0
private void button10_Click(object sender, EventArgs e)
{
textBox1.Text += 0;
textBox2.Text += 0;
}
#endregion
#endregion
3、运算符区域:
(1)运算符就是+、-、×、÷、%嘛,但是我们先不急着链接运算符,
(2)存储第一个数字:当按下某个运算符的时候,先要将上次输入的数字(就是第一个数存储到Number中,这个Number是我实例化对象中封装的属性,具体的我写在了下边)
(3)链接运算符到第一个显示区域textBox1,然后就要将第二个显示区域textBox2中的文本清空
(4)**重点:**改变枚举属性中的值(这个枚举属性值我也放在下边说)
(5)因为属性Number是double类型的,所以要将textBox2中的文本转换为double类型
(6)如果说客户刚上去输入的就是运算符或等号,程序就会直接出错,所以就是使用try—cath处理异常,当出现异常我们要给可以弹出提示。
#region 运算符:+
private void button13_Click(object sender, EventArgs e)
{
try
{
num.Number1 = double.Parse(textBox2.Text);//先获取第一个数
textBox1.Text += "+";
textBox2.Text = "";
num.Ysf = Ysf.jia;//改变num对象下Ysf枚举属性的值
}
catch (Exception)
{
MessageBox.Show("请输入有效的数字");
}
}
#endregion
#region 运算符:-
private void button14_Click(object sender, EventArgs e)
{
try
{
num.Number1 = double.Parse(textBox2.Text);//先获取第一个数
textBox1.Text += "-";
textBox2.Text = "";
num.Ysf = Ysf.jian;//改变num对象下Ysf枚举属性的值
}
catch (Exception)
{
MessageBox.Show("请输入有效的数字");
}
}
#endregion
#region 运算符:×
private void button15_Click(object sender, EventArgs e)
{
try
{
num.Number1 = double.Parse(textBox2.Text);//先获取第一个数
textBox1.Text += "×";
textBox2.Text = "";
num.Ysf = Ysf.cheng;//改变num对象下Ysf枚举属性的值
}
catch (Exception)
{
MessageBox.Show("请输入有效的数字");
}
}
#endregion
#region 运算符:÷
private void button16_Click(object sender, EventArgs e)
{
try
{
num.Number1 = double.Parse(textBox2.Text);//先获取第一个数
textBox1.Text += "÷";
textBox2.Text = "";
num.Ysf = Ysf.chu;//改变num对象下Ysf枚举属性的值
}
catch (Exception)
{
MessageBox.Show("请输入有效的数字");
}
}
#endregion
#region 运算符“%
private void button17_Click(object sender, EventArgs e)
{
try
{
num.Number1 = double.Parse(textBox2.Text);
textBox1.Text += "%";
textBox2.Text = "";
num.Ysf = Ysf.yu;//改变num对象下Ysf枚举属性的值
}
catch (Exception)
{
MessageBox.Show("请输入有效的数字");
}
}
#endregion
#endregion
4、其他区域
(1)就是点、‘=’以及清除CE
(2)点肯定是和数字使用的,当客户上去直接输入点,那肯定是不符合逻辑的,所以就要判断(如果textBox1中的文本是空的,那么就直接给用户弹出提示,否则就是正确的)
(3)当输入“=”的时候当然就要给出结果了,按照以往的思路,我们会在等号事件中要有计算过程,但是今天我们用了面向对象的编程思想,那么就要将这个计算的过程封装到一个类中,因为在用户输入运算符的时候我们就已经改变了Ysf枚举属性的对应值,所以在这里我们就可以直接调用运算结果Jg方法(这个方法可以直接将运算后的数字带过,转换后赋值给textBox2的文本) 当然,要在方法调用之前存储用户输入的这个数字,存储到我们封装的这个属性Number2中,并且要在textBox1中链接“=”,以显示完整的公式。这里也涉及到属性赋值,所以也要使用处理异常try—catch
(4)“CE”清除,这个就是清除textbox1和textBox2中文本的值
#region 杂项:点、=、CE
#region 点
private void button12_Click(object sender, EventArgs e)
{
if (string.IsNullOrWhiteSpace(textBox1.Text))
{
MessageBox.Show("请输入有效的数字");
}
else
{
textBox1.Text += ".";
textBox2.Text += ".";
}
}
#endregion
#region 结果:=
private void button18_Click(object sender, EventArgs e)
{
try
{
num.Number2 = double.Parse(textBox2.Text);
textBox1.Text += "=";
textBox2.Text = num.Jg().ToString();
}
catch (Exception)
{
MessageBox.Show("请输入有效的数字");
}
}
#endregion
#region 清除
private void button11_Click(object sender, EventArgs e)
{
textBox1.Text = "";
textBox2.Text = "";
}
#endregion
#endregion
}
5、设计外观如下:
二、类的封装
(1)创建一个Count类,并在外部实例化,要在全局变量中
(2)定义两个double类型字段并封装属性来存储用户输入的两个数字
//字段
double number1;
double number2;
#region 封装的属性
public double Number1 { get => number1; set => number1 = value; }
public double Number2 { get => number2; set => number2 = value; }
#endregion
(3)定义枚举,来存储运算符
#region Ysf枚举,用来存储:运算符
public enum Ysf
{
jia,
jian,
cheng,
chu,
yu
}
#endregion
(4)在类中定义一个Ysf类型的属性,来让外界改变属性值,改变只能改变为 jia,、jian、cheng、chu、yu五种
/// <summary>
/// 声明一个枚举属性
/// </summary>
public Ysf Ysf { get; set; }
(5)声明方法并将五种运算过程封装与其中
public double Jia()
{
return Number1 + Number2;//返回结果,谁调用就返回给谁
}
public double Jian()
{
return Number1 - Number2;
}
public double Cheng()
{
return Number1 * Number2;
}
public double Chu()
{
return Number1 / Number2;
}
public double Yu()
{
return Number1 % Number2;
}
(6)判断枚举属性的值,是否是与对应的枚举值相等,如果相等就返回对应的运算方法(实则返回的是一个运算后的数字)
public double Jg()
{
switch (Ysf)
{
case Ysf.jia:
return Jia();
case Ysf.jian:
return Jian();
case Ysf.cheng:
return Cheng();
case Ysf.chu:
return Chu();
case Ysf.yu:
return Yu(); ;
}
return 0;
}
三、外部调用
1、在运算符和等号链接之前将用户输入的两次数字存储到Number1和Number2属性中
2、在+、-、×、÷、%运算符按钮链接运算符后改变枚举属性Ysf的值为对应的值(比如+对应jia)
3、在按钮事件中,就可以直接调用运算结果Jg方法,因为客户在输入运算符的时候就已经改变了枚举属性的值
调试结果如下:
正确:
异常:
四、另外一种计算器
设计外观如下:
还有一种计算器,就是没有运算符、以及数字按钮,就是通过手动的输入运算结果的那种,而这种计算器的运算符通常是下拉菜单,这里也是和上边一样,通过选择对应的下拉菜单文本来改变Ysf枚举属性的值,最后也是一样,调用方法即可。
代码如下:
private void button1_Click(object sender, EventArgs e)//等号按钮事件
{
#region 将文本框中的数字存储到属性中
count.Number1 = textBox1.Text;
count.Number2 = textBox2.Text;
//因为这种计算器不是在文本框中输入运算符的,而是两个文本框只是输入数字的,所以这就特别简单,在按下等号按钮的时候就可以直接将两个数字存储到属性中
#endregion
#region 通过下拉菜单的文本来改变索引属性的值
//这里是通过下拉文本框的索引(索引其实就对应文本值)来改变Ysf枚举属性的值,其实和上一种计算器的原理是一样的
switch (comboBox1.SelectedIndex)
{
case 0:
count.Ysf= Ysf.jia;break;
case 1:
count.Ysf= Ysf.jian; break;
case 2:
count.Ysf= Ysf.cheng; break;
case 3:
count.Ysf= Ysf.chu; break;
case 4:
count.Ysf= Ysf.yu; break;
}
#endregion
label1.Text = count.Jg().ToString();
}
}
总结:
其实两种计算器的重点都是:声明枚举,并定义枚举属性,最后通过外部运算符(+、-、×、÷、%)的选择来改变枚举属性的值,然后类里边是判断枚举属性的值来调用不同运算的方法,最终外部来调用这个最后结果的方法就可以实现二目运算计算机的主要功能了。
以上均为自己在学习中总结的一个案例思想,希望能够帮助到您,如果本篇文章有什么不足之处,或者对大家造成了误导,还希望您能够指点出来,纠正我的错误,谢谢!