• 面向对象


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

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

    先看计算器的例子。我们先模拟下计算的场景。当用户打开计算器的时候,先需要输入第一个要计算的数字,然后选择运算符,接下来输入第二个要计算的数字,最后得出计算结果。这里面,每次计算的时候,都涉及到要输入的数字,运算符,这三个是变量,所以我们把它们抽象出来,放到一个计算类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

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

  • 相关阅读:
    单源最短路径-邻接表无向网络
    带权邻接表图的最小生成树
    邻接矩阵有向图的广度优先遍历
    邻接表无向图的深度优先遍历
    图基础-创造用于测试的简单图
    用EFCore从mssql数据库生成实体类
    使用EF Core访问SqlServer数据库
    哈夫曼树综合练习
    树形结构例--控制台显示文件夹结构
    Java之设计模式
  • 原文地址:https://www.cnblogs.com/wesley168/p/6226747.html
Copyright © 2020-2023  润新知