(28.218.81608.81609.81613.83749.83751.83942)

实验二 继承、多态与委托 班级:16计科2班 学号:2015329620062 姓名:孙远昭 一、实验目的 1. 掌握C#中各种成员的写法; 2. 掌握C#继承和多态概念; 3. 掌握C#委托和事件的用法; 4. 掌握常用接口的使用方法。 二、实验内容 (实验过程中编写的程序复制到本文件中,下课整理后上交到yvsou.com,上交的附件以“学号-姓名.doc”命名。如对C#或.NET Framework相关内容不熟悉,可在VS中按F1打开MSDN文档。) 1. 定义以下结构与类: 1)Point结构,包含: 两个double类型实例变量x和y,代表点的二维坐标; 一个Point类型静态常量Orign,代表原点; 带两个double参数的构造方法; 重写ToString方法,输出格式Point(x: 1.0, y:1.0) 2)Shape抽象类,包含: 一个double类型属性Area,可读取面积; 一个double类型属性Perimeter,可读取周长; 一个方法Contains(double x, double y),判断参数所组成的点是否在图形内。 以上均为抽象成员。 2)Rect类,继承Shape抽象类并实现所有抽象成员,并包含: 一个Point2D类型的属性TopLeft,代表矩形的左上角点; 两个double类型属性Width和Height,代表矩形长和宽; 重写ToString方法,输出格式Rect[TopLeft: Point(x: 1.0, y:1.0), Width:1.0, Height: 1.0] 3)Circle类,继承Shape抽象类并实现所有抽象成员,并包含: 一个Point2D类型的属性Center,代表圆心坐标; 一个double类型属性Radius,可读写圆半径; 一个构造方法,接收指定坐标和半径; 一个无参构造方法,调用上个构造方法,创建一个默认圆,圆心在原点,半径为1。 重写ToString方法,输出格式Cirle[Center: Point(x: 1.0, y:1.0), Radius: 1.0, Area: 3.14259] 4)在Main方法中创建矩形与圆,声明为Shape变量,测试其成员。 using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace ConsoleApplication1 { struct Point { public double x, y; public readonly static Point Origin =new Point(); public Point(double x, double y) { this.x = x; this.y = y; } public override string ToString() { return string.Format("Point(x: {0}, y:{1})", x, y); ; } } abstract class Shape{ public abstract double Area{get ;} public abstract double Perimeter{get;} public abstract Boolean Contains(double x, double y); } class Rect : Shape { public Point TopLeft {get ;set ;} public double Width{get ;set ;} public double Length{get ;set ;} public override string ToString() { return string.Format("Rect[TopLeft:{0},Width:{1},Length:{2}",TopLeft,Width,Length); ; } public override double Area { get { return Length * Width; } } public override double Perimeter { get { return 2 * (Length + Width); } } public override Boolean Contains(double x,double y){ if(x>=TopLeft.x&&x<=(TopLeft.x+Width)&&y<TopLeft.y&&y>=(TopLeft.y-Length)) { return true; } else { return false; } } } class Circle : Shape { public Point center = new Point() ; public double Radius { get; set; } public Circle(double x,double y ,double Radius) { center.x=x; center.y=y; this.Radius = Radius; } public Circle():this(0,0,1){ } public override double Area { get { return Radius * Radius*3.14; } } public override double Perimeter { get { return 2*3.14*Radius; } } public override bool Contains(double x, double y) { if (Math.Pow(center.x-x,2)+Math.Pow(center.y-y,2)>=Radius*Radius){ return false;} else return true; } public override string ToString() { return string.Format("Cirle[Center:{0}, Radius:{1}, Area:{2}]",center,Radius,Area); } } class Program { static void Main(string[] args) { Point p1 = new Point(1, 1); Console.WriteLine(p1); Rect rect = new Rect() { TopLeft = p1, Length = 3, Width = 2 }; Console.WriteLine(rect); Console.WriteLine(rect.Area); Console.WriteLine(rect.Perimeter); Console.WriteLine(rect.Contains(5,5)); Circle circle = new Circle(); Console.WriteLine(circle); Circle circle1 = new Circle(0, 1, 2); Console.WriteLine(circle1); Console.WriteLine(circle1.Area); Console.WriteLine(circle1.Perimeter); Console.WriteLine(circle1.Contains(1,1)); } } } 2. 单例类的编写 设计模式(Design Pattern)是一套被反复使用、多数人知晓的、经过分类的、代码设计经验的总结。使用设计模式的目的:为了代码可重用性、让代码更容易被他人理解、保证代码可靠性。 前人总结的一种典型模式是单例模式(Singleton),其设计意图是保证一个类仅有一个实例,并提供一个访问它的全局访问点。 1)首先,该Singleton的构造函数必须是私有的,以保证客户程序不会通过new()操作产生一个实例,达到实现单例的目的; 2)因为静态变量的生命周期跟整个应用程序的生命周期是一样的,所以可以定义一个私有的静态全局变量instance来保存该类的唯一实例; 3)必须提供一个全局函数访问获得该实例,并且在该函数提供控制实例数量的功能,即通过if语句判断instance是否已被实例化,如果没有则可以同new()创建一个实例;否则,直接向客户返回一个实例。 4)在Main方法中得到两个单例类实例,检查它们是否相等。 using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace ConsoleApplication2 { class singleton { private singleton() { } private static singleton instance; public static singleton getinstance() { if (instance == null) { instance = new singleton(); } return instance; } } class Program { static void Main(string[] args) { singleton s1 = singleton.getinstance(); singleton s2 = singleton.getinstance(); Console.WriteLine(s1 == s2); } } } 3. 练习接口的使用 1)Array类的Sort方法需要数组中的元素实现IComparable接口。设计一个Person类,带有Name和Salary属性,还带有Birthday属性(DateTime类型),使之实现IComparable接口(其中定义了方法int CompareTo(object p)),按Name进行比较。 2)上题Person类只能按一种方式来比较。如果需要以其它方式对Person对象进行排序,就需要自己创建一个类PersonComparer,实现IComparer接口(其中定义了方法int Compare(object a, object b)),它独立于要比较的类,因此需要两个参数进行比较。 写个一PersonComparer类,继承IComparer,内部包含一个Type属性。当Type为0时按Salary进行比较,使得能够按Birthday进行排序。 3)测试类如下,生成如下Person数组,调用Sort方法进行两种方式的排序。 class Program { public static void Test() { Person[] persons = new Person[] { new Person { Name = "Damon", Salary = 10, Birthday = new DateTime(1990, 5, 1) }, new Person { Name = "Niki", Salary = 15 , Birthday = new DateTime(1995, 10, 4) }, new Person { Name = "Ayrton", Salary = 12 , Birthday = new DateTime(1992, 6, 23) }, new Person { Name = "Graham", Salary = 13 , Birthday = new DateTime(1994, 9, 15) } }; Console.WriteLine("Order by name:"); Array.Sort(persons); foreach (var p in persons) Console.WriteLine(p); Console.WriteLine(); Console.WriteLine("Order by salary:"); Array.Sort(persons, new PersonComparer(0)); foreach (var p in persons) Console.WriteLine(p); Console.WriteLine(); Console.WriteLine("Order by birthday:"); Array.Sort(persons, new PersonComparer(1)); foreach (var p in persons) Console.WriteLine(p); Console.WriteLine(); } } //代码 using System; using System.Collections; using System.Linq; using System.Text; namespace ConsoleApplication2 { class Person :IComparable { public string Name { get; set; } public int Salary { get; set; } public DateTime Birthday { get; set; } public string FirstName { get { return Name; } set { Name = value; } } public int CompareTo(object obj) { Person p=obj as Person; return Name.CompareTo(p.Name); } public override string ToString() { return Name + " " + Salary + " " + Birthday; } } class PersonComparer : IComparer { public int type; public PersonComparer(int t){ type=t; } public int Salary { get { return Salary; } set { Salary = value; } } public int Birthday { get { return Birthday; } set { Birthday = value; } } public virtual int Compare(object x, object y) { Person a= x as Person; Person b = y as Person; switch (type) { case 0: return a.Salary.CompareTo(b.Salary); case 1: return a.Birthday.CompareTo(b.Birthday); default: throw new ArgumentException(""); } } } class Program { static void Main(string[] args) { Person[] persons = new Person[] { new Person { Name = "Damon", Salary = 10, Birthday = new DateTime(1990, 5, 1) }, new Person { Name = "Niki", Salary = 15 , Birthday = new DateTime(1995, 10, 4) }, new Person { Name = "Ayrton", Salary = 12 , Birthday = new DateTime(1992, 6, 23) }, new Person { Name = "Graham", Salary = 13 , Birthday = new DateTime(1994, 9, 15) } }; Console.WriteLine("Order by name:"); Array.Sort(persons); foreach (var p in persons) Console.WriteLine(p); Console.WriteLine(); Console.WriteLine("Order by salary:"); Array.Sort(persons, new PersonComparer(0)); foreach (var p in persons) Console.WriteLine(p); Console.WriteLine(); Console.WriteLine("Order by birthday:"); Array.Sort(persons, new PersonComparer(1)); foreach (var p in persons) Console.WriteLine(p); Console.WriteLine(); } } } 4. 分析题 以下代码模拟一个服务类,Server类实现了服务器的创建逻辑,子类只要在生成实例对象时传递一个端口号即可创建一个监听该端口的服务,该代码意图如下: (1)通过SimpleServer的构造函数接收端口参数。 (2)子类的构造函数默认调用父类的构造函数。 (3)父类的构造函数调用子类的getPort方法获得端口号。 (4)父类构造函数建立端口监听机制(以Console.WriteLine替代)。 (5)对象创建完毕,服务监听启动,正常运行。 运行该程序,多运行几次,查看输出结果,写出你认为的code 1 – 5的执行顺序。 class Ex2_test { public int i = 0; static void Main(string[] args) { Server s = new SimpleServer(1000); } } abstract class Server { protected const int DEFAULT_PORT = 40000;//code1 public Server() { int port = getPort();//code2 Console.WriteLine("Port: " + port); } protected abstract int getPort(); } class SimpleServer : Server { private int port = 100;//code3 public SimpleServer(int _port) { port = _port;//code4 } protected override int getPort() { return (new Random()).NextDouble() > 0.5 ? port : DEFAULT_PORT;//code5 } } (可将该程序改造为Java程序,看看它的输出是什么,与C#程序输出是否相同。) 1,3,2,5,4 三、实验心得与体会

group status

👤 group joined: 0 ⏳ group pending: 0 🚫 group blocked: 0

ALL > Computer and Education > courses > university courses > undergraduate courses > > > > (28.218.81608.81609.81613.83749.83751.83942)

Sub Domains (0)