面向对象

这篇篇文章我主要通过两个例子(计算器和猜拳游戏)来理解面向对象。

使用面向对象编程,关键的是要找出重复的东西,然后把它抽象出来,进行封装。所以,我们先来看下计算器计算的时候,哪些是重复的。重复的可作为属性。

先看计算器的例子。我们先模拟下计算的场景。当用户打开计算器的时候,先需要输入第一个要计算的数字,然后选择运算符,接下来输入第二个要计算的数字,最后得出计算结果。这里面,每次计算的时候,都涉及到要输入的数字,运算符,这三个是变量,所以我们把它们抽象出来,放到一个计算类Calc中。然后在点击计算的时候运算即可。代码如下:

Calc类:

 1 public class Calc
 2     {
 3         public double Number1 { get; set; }
 4         public double Number2 { get; set; }
 5 
 6         public double Calculate(string sign)
 7         {
 8             double r;
 9             switch (sign)
10             {
11                 case "+":
12                     r = this.Number1 + this.Number2;
13                     break;
14                 case "-":
15                     r = this.Number1 - this.Number2;
16                     break;
17                 case "*":
18                     r = this.Number1 * this.Number2;
19                     break;
20                 case "/":
21                     r = this.Number1 / this.Number2;
22                     break;
23                 default:
24                     throw new Exception("参数错误!");
25             }
26             return r;
27         }
28     }
View Code

计算方法:

 1 namespace 面线对象实现计算器
 2 {
 3     public partial class Form1 : Form
 4     {
 5         public Form1()
 6         {
 7             InitializeComponent();
 8         }
 9 
10         private void btnEquals_Click(object sender, EventArgs e)
11         {
12             Calc c = new Calc();
13             c.Number1 = Convert.ToDouble(txtNumber1.Text);
14             c.Number2 = Convert.ToDouble(txtNumber2.Text);
15 
16             string sign = cmbSign.Text;
17 
18             try
19             {
20                 txtResult.Text = c.Calculate(sign).ToString();
21             }
22             catch (Exception ex)
23             {
24                 MessageBox.Show(ex.Message);
25             }
26 
27         }
28     }
29 }
View Code

 接下来我们看下面向过程的编程。

 1 public partial class Form2 : Form
 2     {
 3         public Form2()
 4         {
 5             InitializeComponent();
 6         }
 7 
 8         private void btnEquals_Click(object sender, EventArgs e)
 9         {
10             double n1 = Convert.ToDouble(txtNumber1.Text); 
11             double n2 = Convert.ToDouble(txtNumber2.Text);
12             try
13             {
14                 string sign = cmbSign.Text;
15                 double r;
16                 switch (sign)
17                 {
18                     case "+":
19                         r = n1 + n2;
20                         break;
21                     case "-":
22                         r = n1 - n2;
23                         break;
24                     case "*":
25                         r = n1 * n2;
26                         break;
27                     case "/":
28                         r = n1 / n2;
29                         break;
30                     default:
31                         throw new Exception("参数错误!");
32                 }
33 
34                 txtResult.Text = r.ToString();
35             }
36             catch (Exception ex)
37             {
38                 MessageBox.Show(ex.Message);
39             }
40         }
41     }
View Code

这样看来面向对象和面向过程好像没什么区别,那为什么还要用面向对象呢?假如,我现在不想用WinForm窗口实现计算器,想改成控制台程序。如果用面向对象编程,只要把Calc类复制过去就实现了整个算法,而面向过程却要把calc中算法全部重写。二者的区别在这里就开始体现了。当然这个计算器还能进一步优化,这个后续再说。

接下来看猜拳游戏。

首先模拟下游戏的场景。当用户点击剪刀时,你出:显示剪刀,电脑随机出,然后比较输赢。这里涉及到的对象有你,电脑。涉及到的属性有,剪刀,石头,布,每个对象都出拳的方法。每个角色都要有个保存出拳结果的属性。既然电脑和你的属性和方法都相同,那能否把这两个对象合并成一个对象呢?最好不要。因为你出拳是用户在界面点击,然后把参数传进去,电脑是随机出拳,可以在方法中随机生成,不传参数,两个方法的参数不一致,分开更好维护。比较输赢的方法不能存在于你和电脑中,因为裁判必须是第三方。为方便判断输赢,我们把出拳结果用数字表示,石头=1,剪刀=2,布=3,用用户出拳减去电脑出拳的结果来表示输赢,很容易得出用户-电脑=-1或者2的时候,玩家赢,用户-电脑=0的时候,表示平局,其余是玩家输。所以,整个猜拳游戏的代码如下:

出拳的枚举:

1 namespace 猜拳游戏
2 {
3     public enum Fist
4     {
5         stone=1,
6         scissors=2,
7         cloth=3
8     }
9 }
View Code

玩家类:

 1 namespace 猜拳游戏
 2 {
 3     public class Person
 4     {
 5         public int PFist { get; set; }
 6 
 7         public void ShowFist(int index)
 8         {
 9             this.PFist = index;
10         }
11     }
12 }
View Code

电脑类:

 1 namespace 猜拳游戏
 2 {
 3     public class Computer
 4     {
 5         public int CFist { get; set; }
 6 
 7         public void ShowFist()
 8         {
 9             Random rd = new Random();
10             int r =rd.Next(1,4);
11             this.CFist = r;
12         }
13     }
14 }
View Code

裁判类:

 1 namespace 猜拳游戏
 2 {
 3     public class Judgement
 4     {
 5         /// <summary>
 6         /// 猜拳判断输赢 玩家赢=1;平局=0;玩家输=-1
 7         /// </summary>
 8         /// <param name="p">玩家</param>
 9         /// <param name="c">电脑</param>
10         /// <returns></returns>
11         public int Judge(int p,int c)
12         {
13             int r;
14             if (p - c == -1 || p - c == 2)
15             {
16                 r = 1;
17             }
18             else if (p - c == 0)
19             {
20                 r = 0;
21             }
22             else
23             {
24                 r = -1;
25             }
26             return r;
27         }
28     }
29 }
View Code

这里要特别提示下:

裁判判断的结果是输赢,这里最好不要直接返回类似“你赢了”之类的信息,返回数字即可,因为用户可能会把“你赢了”改成“You Win !”等任何其他提示信息。

 窗体类中的代码:

 1 private void btnGuessStone_Click(object sender, EventArgs e)
 2         {
 3             Computer c = new Computer();
 4             c.ShowFist();
 5             lblComputerResult.Text = c.CFist == (int)Fist.stone ? "石头" : (c.CFist == (int)Fist.scissors ? "剪刀" : "");
 6             
 7 
 8             Person p = new Person();
 9             p.ShowFist((int)Fist.stone);
10             lblYouResult.Text = p.PFist == (int)Fist.stone ? "石头" : "";
11 
12             Judgement j = new Judgement();
13             int r= j.Judge(p.PFist,c.CFist);
14 
15             string result = string.Empty;
16             //猜拳判断输赢,返回值=0:平局;返回值的绝对值=1:玩家赢;返回值的绝对值=2:玩家输。
17             if (r == 0)
18             {
19                 result = "平局,再来一局!";
20             }
21             if (r==1)
22             {
23                 result = "你赢了!!!";
24             }
25             if (r == -1)
26             {
27                 result = "你输了!!!";
28             }
29 
30             lblResult.Text = result;
31         }
32 
33         private void btnGuessScissors_Click(object sender, EventArgs e)
34         {
35             Computer c = new Computer();
36             c.ShowFist();
37             lblComputerResult.Text = c.CFist == (int)Fist.stone ? "石头" : (c.CFist == (int)Fist.scissors ? "剪刀" : "");
38             
39 
40             Person p = new Person();
41             p.ShowFist((int)Fist.scissors);
42             lblYouResult.Text = p.PFist == (int)Fist.scissors ? "剪刀" : "";
43 
44             Judgement j = new Judgement();
45             int r = j.Judge(p.PFist, c.CFist);
46 
47             string result = string.Empty;
48             //猜拳判断输赢,返回值=0:平局;=1:玩家赢;-1:玩家输。
49             if (r == 0)
50             {
51                 result = "平局,再来一局!";
52             }
53             if (r == 1)
54             {
55                 result = "你赢了!!!";
56             }
57             if (r == -1)
58             {
59                 result = "你输了!!!";
60             }
61 
62             lblResult.Text = result;
63         }
64 
65         private void btnGuessCloth_Click(object sender, EventArgs e)
66         {
67             Computer c = new Computer();
68             c.ShowFist();
69             lblComputerResult.Text = c.CFist == (int)Fist.stone ? "石头" : (c.CFist == (int)Fist.scissors ? "剪刀" : "");
70             
71 
72             Person p = new Person();
73             p.ShowFist((int)Fist.cloth);
74             lblYouResult.Text = p.PFist == (int)Fist.cloth ? "" : "";
75 
76             Judgement j = new Judgement();
77             int r = j.Judge(p.PFist, c.CFist);
78 
79             string result = string.Empty;
80             //猜拳判断输赢,返回值=0:平局;1:玩家输;2:玩家赢。
81             if (r == 0)
82             {
83                 result = "平局,再来一局!";
84             }
85             if (r == 1)
86             {
87                 result = "你赢了!!!";
88             }
89             if (r == -1)
90             {
91                 result = "你输了!!!";
92             }
93 
94             lblResult.Text = result;
95         }
View Code

以上就是面向对象的两个例子,可能表述的不是很完整,后期会反复雕琢,欢迎指正!

原文地址:https://www.cnblogs.com/wesley168/p/6226747.html