2022年CS高级编程[收 .pdf
8、C#高级编程目标单一继承抽象类和抽象方法使用委托和事件实现模拟闹铃。飞机和客机类的多态程序第一部分指导练习 1:单一继承问题现实生活中,哺乳动物是动物界中一个分支;可以动物普遍具有的特征都可以在哺乳动物身上找到;但哺乳动物也有自己独特的习性。因此可以将动物看成是哺乳动物的父亲。编程实现上可以通过哺乳动物类继承一般动物类,从而获得一般动物的特征。指导教师讲解问题说明用 C#编写一个程序, 使用 Animal 和 Mammal 两个类来说明一般动物和哺乳动物的继承关系。Animal 具有名称、所属门类等属性,需要提供方法实现以接收和显示这些属性的值。 Mammal类具有代表哺乳动物习性的属性,这些属性表明哺乳动物与其他类型动物的区别。同样地,需要提供方法实现以接收和显示这些属性的值。分析 Animal类是一个基类, 它包含 _name 、 _type 两个成员以及用于接收和显示信息的三个方法。名为 Mammal的派生类包含 _temperature 、_isViviparous两个成员和用于接收和显示信息的两个方法。为了检验创建的Animal 和 Mammal 类,应实例化一个Mammal 类对象, 并调用基类和派生类的方法来存储和检索值。推荐步骤:(1)新建一个名为“SingleInher”的基于控制台应用程序的项目。(2)将以下代码添加到“Program.cs ”中。using System; using System.Collections.Generic; using System.Text; namespace SingleInher /一般动物类 class Animal protected string _name; /动物名称 protected string _type; /动物所属门类 /接收名称和门类名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 1 页,共 12 页 - - - - - - - - - public void AcceptDetails() Console.WriteLine(请输入动物名称:); this._name = Console.ReadLine(); Console.WriteLine(请输入所属门类:); this._type = Console.ReadLine(); /显示动物的名称和所属门类 public void DisplayDetails() Console.WriteLine(); Console.WriteLine(0 动物的详细信息如下:, this._name); Console.WriteLine(姓名: 0, this._name); Console.WriteLine(门类: 0, this._type); /哺乳动物类,继承一般动物类 class Mammal : Animal private double _temperature; /恒定温度值 private string _isViviparous; /是否为胎生 /接收哺乳动物的特征信息 public void AcceptCharacter() Console.WriteLine(请输入哺乳动物的恒定温度:); try _temperature = Convert.ToDouble(Console.ReadLine(); catch /捕捉异常,例如:若输入字母,在转换成Decimal 时会引发异常 Console.WriteLine(请为温度输入数字!); Console.WriteLine(该哺乳动物是否胎生:); _isViviparous = Console.ReadLine(); /显示哺乳动物的特征信息 public void DisplayCharacter() Console.WriteLine(); Console.WriteLine(0 的特征包括: , this._name); Console.WriteLine(恒定温度: 0, _temperature.ToString(); Console.WriteLine(是否胎生: 0, _isViviparous); 名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 2 页,共 12 页 - - - - - - - - - class Program static void Main(string args) Mammal objM = new Mammal(); objM.AcceptDetails();/访问父类方法 objM.AcceptCharacter(); objM.DisplayDetails();/访问父类方法 objM.DisplayCharacter(); (3)生成项目。(4)选择“调试”“开始执行(不调试)”选项来执行此应用程序,输出结果如图1.1 所示。图 1.1 练习 1 的输出结果练习 2:使用抽象类和抽象方法计算不同形状的面积问题编写一个程序,使用抽象类和抽象方法来计算不同形状的面积。指导教师讲解问题说明先定义一个抽象类,该抽象类有一名为计算面积的方法为抽象方法。指导教师分析解题思路名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 3 页,共 12 页 - - - - - - - - - 定义好抽象类和抽象方法后,具体的类继承该抽象类,实现抽象方法。该问题中定义两个具体形状类:矩形和圆。解决方案:(1)创建一个基于控制台的项目“AbstractClass”。(2)建立一个抽象类,命名为“Figure ”, 定义变量和抽象方法Area() 。(3)定义两个具体类Square 和 Circle继承自 Figure 类,在各自类中分别实现Area() 方法。(4)创建一个测试类,分别调用Square 和 Circle类。(5)添加以下完整的代码using System; abstract class Figure/抽象类定义,表示一个抽象图形 protected double x = 0, y = 0; public Figure(double a, double b) x = a; y = b; public abstract void Area(); /抽象方法,无实现代码,抽象图形无法计算面积 class Square : Figure /类 Square 定义,矩形类 public Square(double a, double b) : base(a, b) public override void Area() /不能使用 new ,必须用override Console.WriteLine(矩形面积是: 0, x * y); /显示矩形面积 class Circle : Figure /类 Circle定义,圆类 public Circle(double a) : base(a, a) public override void Area() Console.WriteLine(圆面积是: 0, 3.14 * x * y); /显示圆的面积 class Class1 static void Main(string args) Square s = new Square(20, 30); Circle c = new Circle(10); s.Area(); c.Area(); 名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 4 页,共 12 页 - - - - - - - - - (6)选择“生成”“生成解决方案”选项,以生成此项目。(7)选择“调试”“开始执行(不调试)”选项来执行此应用程序。此程序的输出结果如图2.1 所示。图 2.1 程序输出结果指导教师检查学生进度练习 3:使用委托和事件实现模拟闹铃问题编写一个模拟闹铃的程序,具有闹铃,继续闹铃,打会盹儿,停止闹铃的功能。指导教师讲解问题说明编写一个程序用来模拟闹钟闹起床流程,有一个闹钟类AlarmClock ,催促起床类WakeMeUp ,使用类AlarmDriver。调用类引发开始闹铃事件,闹钟类调用委托方法进行处理,催促起床类和用户进行交互。指导教师分析解题思路在此问题中, 可以设计考试类来控制流程。闹钟类应该有一个可以引发开始闹铃的方法由使用类调用。这是一种常用的类设计方式,就是建立一些实体类,这些实体类由控制流程的类来进行关联。解决方案:(1)创建一个基于控制台的项目“EventSample”。(2)建立一个类,命名为“AlarmEventArgs ”, 定义事件参数类。(3)声明自定义代理类型,它的事件参数的类型为AlarmEventArgs 。(4)创建包含事件和触发事件方法的类:AlarmClock 。(5)创建包含事件处理方法的类:WakeMeUp。(6)创建包含程序入口方法的类:AlarmDriver 。(7)添加以下完整的代码using System; using System.Collections.Generic; using System.Text; namespace EventSample / / 定义事件参数类 / 名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 5 页,共 12 页 - - - - - - - - - public class AlarmEventArgs : EventArgs private readonly bool snoozePressed; private readonly int nrings; /构造函数 public AlarmEventArgs(bool snoozePressed, int nrings) this.snoozePressed = snoozePressed; this.nrings = nrings; / 定义属性,私有字段nrings public int NumRings get return nrings; / 定义属性,返回私有字段snoozePressed public bool SnoozePressed get return snoozePressed; / 下面的属性返回一个字符串 public string AlarmText get if (snoozePressed) return (别打打盹儿,快起床!); else return (起床! ); / 声明自定义代理类型,它的事件参数的类型为AlarmEventArgs public delegate void AlarmEventHandler(object sender, AlarmEventArgs e); / 包含事件和触发事件方法的类 public class AlarmClock private bool snoozePressed = false; private int nrings = 0; private bool stop = false; 名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 6 页,共 12 页 - - - - - - - - - / 定义两个属性 public bool Stop get return stop; set stop = value; public bool SnoozePressed get return snoozePressed; set snoozePressed = value; / 声明事件,它所使用的代理类型为AlarmEventHandler public event AlarmEventHandler Alarm; / 触发事件的方法 protected virtual void OnAlarm(AlarmEventArgs e) if (Alarm != null) / 通过代理调用事件处理方法 Alarm(this, e); / 在该方法中循环调用OnAlarm 方法来触发事件,直到 / stop字段的值为 true public void Start() for (; ; ) nrings+; if (stop) break; else if (snoozePressed) / 程序暂停 1 秒钟 System.Threading.Thread.Sleep(1000); / 创建事件参数对象实例 AlarmEventArgs e = new AlarmEventArgs(snoozePressed, nrings); OnAlarm(e); / 触发事件,在事件处理方法中会 / 相应地设置snoozePressed 和 stop / 字段的值(通过属性来设置) 名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 7 页,共 12 页 - - - - - - - - - else / 程序暂停 0.3 秒 System.Threading.Thread.Sleep(300); AlarmEventArgs e = new AlarmEventArgs(snoozePressed, nrings); OnAlarm(e); / 触发事件 / 包含事件处理方法的类 public class WakeMeUp / 事件处理方法 / 在该方法中根据用户的输入来通过事件参数sender / 设置事件发送者属性, public void AlarmRang(object sender, AlarmEventArgs e) Console.WriteLine(e.AlarmText + n); if (!(e.SnoozePressed) if (e.NumRings % 10 = 0) Console.WriteLine(继续闹铃?输入Y); Console.WriteLine(打会盹儿 ?输入 N); Console.WriteLine(停止闹铃?输入Q); String input = Console.ReadLine(); if (input.Equals(Y) | input.Equals(y) return; else if (input.Equals(N) | input.Equals(N) / 通过事件参数sender 来访问触发事件的对象 (AlarmClock)sender).SnoozePressed = true; return; else (AlarmClock)sender).Stop = true; return; else 名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 8 页,共 12 页 - - - - - - - - - Console.WriteLine( 继续闹铃?输入Y); Console.WriteLine( 停止闹铃?输入Q); String input = Console.ReadLine(); if (input.Equals(Y) | input.Equals(y) return; else (AlarmClock)sender).Stop = true; return; / 包含程序入口方法的类 public class AlarmDriver / 入口方法 public static void Main(string args) / 创建事件接收者对象实例 WakeMeUp w = new WakeMeUp(); / 创建事件发送者对象实例 AlarmClock clock = new AlarmClock(); / 把事件处理方法绑定到发送者的事件上 clock.Alarm += new AlarmEventHandler(w.AlarmRang); clock.Start(); (8)选择“生成”“生成解决方案”选项,以生成此项目。(9)选择“调试”“开始执行(不调试)”选项来执行此应用程序。此程序的输出结果如图3.1 所示。名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 9 页,共 12 页 - - - - - - - - - 图 3.1 EventSample的输出结果指导教师检查学生进度第二部分练习练习:多态( polymorphism ) C#可以通过使用关键字virtual在基类中定义虚方法,用 override在派生类重载虚方法实现多态。以飞机类和客机类的代码来说明如何实现多态。指导教师分析解题思路分别创建类 Plane 和 Airliner的实例 p 和 a,先调用类 Plane 的方法 Report ,然后把 p 指向 a,再调用 Report 方法,此时实际上调用了类Airliner被重载的方法Report 。具体代码如下所示:using System; using System.Collections.Generic; using System.Text; namespace Polymorphism 名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 10 页,共 12 页 - - - - - - - - - class Plane /定义飞机类 public int wheels; /飞机轮子数量 protected int weight; /飞机重量,是受保护的变量 public Plane() ; public Plane(int w1, int w2) wheels = w1; weight = w2; /定义虚方法 public virtual void Report() Console.WriteLine(The planes wheel number is 0,weight is 1,wheels,weight); class Airliner : Plane /定义客机类,从飞机类中继承 int passengers; /客机乘客数量 public Airliner(int w1,int w2,int p):base(w1,w2) passengers = p; /重载父类中的方法 public override void Report() Console.WriteLine(The Airliners wheel number is 0,weight is 1,passengers is 2, wheels, weight, passengers); class Program static void Main(string args) Plane p = new Plane(); Airliner a = new Airliner(2, 300, 100); p.Report(); p = a; p.Report(); 名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 11 页,共 12 页 - - - - - - - - - 指导教师检查学生进度指导教师检查学生代码规范性第三部分作业指导教师布置作业定义一个接口,用于描述动物的生活习性,包含食性、捕食、分布区域、睡觉方式、群居方式等;接口里面包括属性和方法。例如:interface IHabit void CatchFood(); string foodget;set; , 然后定义猫、老虎、狮子、大象等几个动物类来实现该接口;最后定义一个调用类,来运行程序,查看接口的使用情况。名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 12 页,共 12 页 - - - - - - - - -