zoukankan      html  css  js  c++  java
  • C#通过完整的例子,Get常用的2个套路,理解抽象方法,虚方法,接口,事件

    一.理解:抽象方法,虚方法,接口,事件

    描述:

    1.定义一个抽象父类“People”:

    要求:

    1>3个属性:名字,性别,年龄;

    2>一个普通方法“说话”;

    3>2个抽象方法:“喜欢什么”,“会做什么”

    4>1个虚方法“母语”

    5>定义一个接口,用于唱歌

    2.分别创建3个子类:学生,老师,校长

    要求:都继承抽象类People,而且都实现唱歌接口,老师覆写虚方法“母语”

    3.每个子类都有自己独有的才艺,提供一个方法功能如下:

    打印“开始表演才艺”

    执行具体才艺

    打印“才艺表演结束,大家鼓掌!!”

    意义: 抽象类,虚方法

    4.定义事件

    要求

    抽象类中定义一个事件,模拟“发财了”。提供一个设置金钱的方法,默认1000作为触发条件,但老师需要1,0000触发,校长需要10,0000触发

    意义:  理解观察者模式,理解事件的发布/触发,事件的观察者(订户),事件的订阅

    5.新增一个“明星子类”

    要求:

    “明星”子类中,定义三个事件:表演开始/表演高潮/表演结束;

    然后新增一个Show方法: 依次调用->说话->触发表演开始事件->喜欢什么->会做什么->触发表演高潮事件->才艺->触发表演结束事件

    意义:理解事件的流程封装扩展的意义

    一.搭建程序

    自己新建一个工程,按照下图建好框架,拷贝下面的对应类即可

    People类:中有2个常用的套路

    常用套路1:

    封装Skill的时候,用到了套路1

    ★★★适用情形:子类大部分动作都相同,个别不同的情况:

    父类定义一个方法Skill(),大部分相同动作放Skill中;不同的动作在父类中做成一个抽象方法或者虚方法SelfSkill(),让各个子类去实现。

     常用套路2:

    模拟“发财了”。提供一个设置金钱的方法,做这个的时候又套路1,2,3中方式供选择

    1>小套路1:Poeplez中定义一个 虚方法SetMoney,然后子类Teacher和Schoolmaster需要重载这个虚方法,然后子类虚方法里面设置不同的金额来触发GetRich事件

    2>小套路2:把金钱在People中,定义为字段 protected int Money = 1000;,然后Teacher和Schoolmaster的构造函数中,重新对这个字段赋值即可

    3>小套路3:在People中,定义一个委托判断条件,protected Func<int, bool> FuncJudge = i => i > 1000;,然后Teacher和Schoolmaster的构造函数中,重写委托即可

     1 using System;
     2 using System.Collections.Generic;
     3 using System.Linq;
     4 using System.Security.Policy;
     5 using System.Text;
     6 using System.Threading.Tasks;
     7 
     8 namespace Self.Interface
     9 {
    10     public abstract class People
    11     {
    12         //4.定义事件
    13         //抽象类中定义一个事件,模拟“发财了”。提供一个设置金钱的方法,默认1000作为触发条件,但老师需要1,0000触发,校长需要10,0000触发
    14         //套路:提供3中类型的套路
    15         protected int Money = 1000;//套路2 把金钱做成字段,构造函数时候初始化
    16         protected Func<int, bool> FuncJudge = i => i > 1000;//套路3 委托判断条件
    17 
    18         public event Action GetRich;//发财了时间
    19         public virtual void SetMoney(int monry)
    20         {
    21             //if (monry >= 1000)//套路1 虚方法重载
    22             //if (monry >= Money)//套路2 把金钱做成字段,构造函数时候初始化
    23             if (FuncJudge.Invoke(monry))//套路3 委托判断条件
    24             {
    25                 FireGetRich();
    26             }
    27         }
    28         /// <summary>
    29         /// 触发发财了事件
    30         /// </summary>
    31         protected void FireGetRich()
    32         {
    33             GetRich?.Invoke();
    34         }
    35         public string Name { get; set; }
    36         public string Age { get; set; }
    37         public string Gender { get; set; }
    38         public void Speak()
    39         {
    40             Console.WriteLine("我是抽象父类方法:现在我开始说话!");
    41         }
    42         public abstract void Like();
    43         public abstract void ICanDo();
    44         public virtual void MotherTongue()
    45         {
    46             Console.WriteLine("我是抽象类:我的母语是汉语");
    47         }
    48         /// <summary>
    49         /// 3.每个子类都有自己独有的才艺,提供一个方法功能如下:
    50         /// 打印“开始表演才艺”
    51         /// 执行具体才艺
    52         /// 打印“才艺表演结束,大家鼓掌!!”
    53         /// 
    54         /// 常用的套路1:
    55         /// ★★★适用情形:子类大部分动作都相同,个别不同的情况:
    56         /// 父类定义一个方法Skill(),大部分相同动作放Skill中;不同的动作在父类中做成一个抽象方法或者虚方法SelfSkill(),让各个子类去实现。
    57         /// </summary>
    58         public void Skill()
    59         {
    60             Console.WriteLine("开始表演才艺");
    61             this.SelfSkill();
    62             Console.WriteLine("才艺表演结束,大家鼓掌!!");
    63         }
    64         protected abstract void SelfSkill();//这里注意 受保护的protected 和每个子类都必须实现的abstract
    65     }
    66 }
    View Code

    Sing类

     1 using System;
     2 using System.Collections.Generic;
     3 using System.Linq;
     4 using System.Text;
     5 using System.Threading.Tasks;
     6 
     7 namespace Self.Interface
     8 {
     9     public interface ISing
    10     {
    11         void Sing();
    12     }
    13 }
    View Code

    4个子类

     1 using System;
     2 using System.Collections.Generic;
     3 using System.Linq;
     4 using System.Text;
     5 using System.Threading.Tasks;
     6 using Self.Interface;
     7 
     8 namespace Self.Service
     9 {
    10     public class Schoolmaster : People, ISing
    11     {
    12         public Schoolmaster()
    13         {
    14             base.Money = 100000;//2 把金钱做成字段,构造函数时候初始化
    15             FuncJudge = i => i >= 100000;//套路3 委托判断条件
    16         }
    17         public override void Like()
    18         {
    19             Console.WriteLine("我喜欢看广场舞!");
    20         }
    21         public override void ICanDo()
    22         {
    23             Console.WriteLine("我会管理学校");
    24         }
    25         public void Sing()
    26         {
    27             Console.WriteLine("开始唱:我的中国心!");
    28         }
    29         protected override void SelfSkill()
    30         {
    31             Console.WriteLine("我会拉小提琴");
    32         }
    33     }
    34 }
    View Code
     1 using System;
     2 using System.Collections.Generic;
     3 using System.Linq;
     4 using System.Text;
     5 using System.Threading.Tasks;
     6 using Self.Interface;
     7 
     8 namespace Self.Service
     9 {
    10     public class Teacher : People, ISing
    11     {
    12         public Teacher()
    13         {
    14             base.Money = 10000;//2 把金钱做成字段,构造函数时候初始化
    15             FuncJudge = (i) => i >= 10000;//套路3 委托判断条件
    16         }
    17         public override void Like()
    18         {
    19             Console.WriteLine("我喜欢科研");
    20         }
    21         public override void ICanDo()
    22         {
    23             Console.WriteLine("我可以教学");
    24         }
    25         public void Sing()
    26         {
    27             Console.WriteLine("开始唱:新贵妃醉酒!");
    28         }
    29         public override void MotherTongue()
    30         {
    31             Console.WriteLine("我是老师,我的母语是英语!");
    32         }
    33         protected override void SelfSkill()
    34         {
    35             Console.WriteLine("我会跳拉丁舞");
    36         }
    37     }
    38 }
    View Code
     1 using System;
     2 using System.Collections.Generic;
     3 using System.Linq;
     4 using System.Text;
     5 using System.Threading.Tasks;
     6 using Self.Interface;
     7 
     8 namespace Self.Service
     9 {
    10     public class Student : People, ISing
    11     {
    12         public override void ICanDo()
    13         {
    14             Console.WriteLine("我会写作业!");
    15         }
    16 
    17         public override void Like()
    18         {
    19             Console.WriteLine("我喜欢打游戏");
    20         }
    21 
    22         public void Sing()
    23         {
    24             Console.WriteLine("开始唱:我的滑板鞋!");
    25         }
    26         protected override void SelfSkill()
    27         {
    28             Console.WriteLine("我会打王者荣耀!");
    29         }
    30     }
    31 }
    View Code
     1 using System;
     2 using System.Collections.Generic;
     3 using System.Linq;
     4 using System.Text;
     5 using System.Threading.Tasks;
     6 using Self.Interface;
     7 
     8 
     9 namespace Self.Service
    10 {
    11     public class Star : People, ISing
    12     {
    13         public event Action StartOn;
    14         public event Action HightOn;
    15         public event Action EndOn;
    16         /// <summary>
    17         /// ★★★目的:理解事件的流程封装扩展的意义
    18         ////封装框架的时候,固定的业务都封装好,开放出扩展点封装成事件;让用户自己定义逻辑。类似于事件的按钮情况
    19         ///也可以理解为:程序设计的时候,固定部分写死,不固定部分通过一个事件封装出去。
    20         /// </summary>
    21         public void Show()
    22         {
    23             base.Speak();//固定部分写死
    24 
    25             this.StartOn?.Invoke();//不固定部分,通过事件逻辑
    26 
    27             this.Like();
    28             this.ICanDo();
    29 
    30             this.HightOn?.Invoke();
    31 
    32             this.Sing();
    33 
    34             this.EndOn?.Invoke();
    35         }
    36         public override void ICanDo()
    37         {
    38             Console.WriteLine("我会演戏");
    39         }
    40 
    41         public override void Like()
    42         {
    43             Console.WriteLine("我喜欢表演");
    44         }
    45 
    46         public void Sing()
    47         {
    48             Console.WriteLine("开始唱:我爱我的祖国");
    49         }
    50 
    51         protected override void SelfSkill()
    52         {
    53             Console.WriteLine("我一秒钟能哭出来");
    54         }
    55     }
    56 }
    View Code

    主程序类

     1 using System;
     2 using System.Collections.Generic;
     3 using System.Linq;
     4 using System.Text;
     5 using System.Threading.Tasks;
     6 using Self.Service;
     7 using Self.Interface;
     8 
     9 namespace 自己模仿写的例子
    10 {
    11     class Program
    12     {
    13         static void Main(string[] args)
    14         {
    15             Console.WriteLine("********************teacher************************");
    16             People teacher = new Teacher()
    17             {
    18                 Name = "苍井空",
    19                 Age = "33",
    20                 Gender = "",
    21             };
    22             teacher.GetRich += () => { Console.WriteLine("我发财了!!"); };//当设置金钱>=10000的时候,执行这个lambda表达式
    23             teacher.Like();
    24             teacher.ICanDo();
    25             teacher.MotherTongue();
    26             teacher.Skill();
    27             teacher.SetMoney(10);
    28             teacher.SetMoney(10000);
    29             Console.WriteLine("**********************Student**********************");
    30             Student student = new Student()
    31             {
    32                 Name = "无名小辈",
    33                 Age = "22",
    34                 Gender = ""
    35             };
    36             student.Like();
    37             student.ICanDo();
    38             student.MotherTongue();
    39             student.Skill();
    40             Console.WriteLine("**********************star**********************");
    41             Star star = new Star()
    42             {
    43                 Name = "颖宝宝",
    44                 Age = "28",
    45                 Gender = "",
    46             };
    47             star.StartOn += () => { Console.WriteLine("主持人讲话了,大家安静了,明星即将开始表演了"); };
    48             star.HightOn += () => { Console.WriteLine("主持人讲话了,明星表演的精彩吧!"); };
    49             star.EndOn += () => { Console.WriteLine("主持人讲话了,明星表演结束了,大家鼓掌!!"); };
    50             star.Show();
    51             Console.ReadKey();
    52         }
    53     }
    54 }
    View Code

    二.抽象方法和虚方法的区别

    下图中,调用虚方法MotherTongue()的时候,学生类没有重写这个方法,就调用父类的MotherTongue();老师类重写了虚方法MotherTongue,调用的时候就调用重写的方法。

    目的:

    1>父类的虚方法,子类想重写就重写,不行重写就算了。调用的时候,子类有重写就调用子类重写的虚方法,没有重写就调用父类虚方法。

    2>父类的抽象方法,子类必须都得重写,不管子类愿不愿意,都必须重写的。

     三.理解程序封装的思想

    实例化一个明星类,然后调用Show(),固定部分写死了,不固定的部分通过事件封装出去了,让用户去实现业务逻辑。

    从图中可以看到,当Show()方法遇到事件的时候,就去执行用户定义的事件逻辑了,执行完用户定义的逻辑,再继续往下继续执行。

    目的:

    1>理解程序设计的时候,固定的部分写死,不固定部分,通过事件封装出去。

     

  • 相关阅读:
    关于二进制——lowbit运算
    代码风格
    焦作区域赛——反思及期望
    第一次参加acm区域赛
    0——1分数问题规划
    [FZYZOJ 1339] 修改密码
    [HDU 1856] More is better
    并查集小结
    [FZYZOJ 1031] 无线网络
    [FZYZOJ 1038] 隧道
  • 原文地址:https://www.cnblogs.com/dfcq/p/13205089.html
Copyright © 2011-2022 走看看