实验2 C#程序设计基础
一、实验目的:
1. 学习和掌握面向对象的基本概念及应用 (类、对象、方法、字段、构造函数和析构函数)
2. 学习和掌握C#中方法的重载、静态成员、类的继承(派生)来编写程序、初步体会多态性的使用
3. 掌握对象实例化的使用。
二、实验要求:
1.独立完成
2.实验内容完成后,认真写出一份规范的实验报告,内容包括:实验名称、目的要求、实验结果分析、总结与讨论等,包括教师在实验指导书中提出的问题。鼓励在报告中写出自己创新性,有独到之处的见解,设计方案等。
三、实验内容
1.验证:
在界面中有一个Button按钮,单击该按钮,执行以下代码,观察
Button btn;
btn.Left = this.ClientSize.Width-100;
btn.Width =100;
btn.Top = 0;
btn.Height = 50;
btn.Text = "Button对象";
(1) 该代码能否正确运行,如果不行,是什么问题?如何解决?
答:不能正确运行,变量btn未赋值,将“Button btn;”改为“Button btn=button1;”
(2)对象实例化后,能不能在界面上显示新创建的按钮?为什么?
答:不能,缺少btn.Parent = this;
(3)最后加上代码:btn.Parent = this;或 this.Controls.Add(this.btn);效果如何? 为该按钮添加Click事件,试添加并运行。
答:新建了一个按钮
2.对象的创建和使用
(1)编写应用程序,初步实现员工信息管理的功能
①定义一个员工类Employee,员工类中包括私有成员:workNum(工号)、name(姓名)、basicSalary(基本工资)、rewards(奖金)、totalSalary(应发工资)、totalNum(静态成员:总员工人数);
②在类中添加公有方法:CalTotalSalary(计算应发工资,基本工资+奖金)、DisplayEmployeeInfo(显示员工当前信息)、DisplayTotalNumber(显示总员工人数)
③在类Employee中添加相应的公有属性,WorkNum(工号)、Name(姓名)、BasicSalary(基本工资)、Rewards(奖金)、Salary(应发工资,只读);
④类中同时包含函数:Employee(构造函数)、~Employee(析构函数)。其中,构造函数为Employee类的对象赋值并将员工人数加1,以实现对象的初始化,析构函数计算员工人数减1,显示当前人数信息。
⑤创建一个类Employee的对象并调用四个公有方法。
⑥创建一组类Employee的对象并调用相应的方法设置和显示各对象信息。(提示:可以通过创建ArrayList类对象,每创建一个Employee对象,通过ArrayList的add方法将对象加到列表中)
internal class Employee
{
private String workNum, name; //工号,姓名
private int basicSalary, rewards, totalSalary; //基本工资,奖金,应发工资
public static int totalNum; //总员工人数
public int BasicSalary { get => basicSalary; set => basicSalary = value; }
public int Rewards { get => rewards; set => rewards = value; }
public int TotalSalary { get => totalSalary; }
public string WorkNum { get => workNum; set => workNum = value; }
public string Name { get => name; set => name = value; }
public Employee(String workNum,String name,int basicSalary,int rewards) //构造函数
{
this.workNum = workNum;
this.name = name;
this.basicSalary = basicSalary;
this.rewards = rewards;
totalNum++;
}
~Employee() //析构函数
{
Console.WriteLine("员工"+name+"离职");
totalNum--;
}
public int CalTotalSalary() //计算应发工资,基本工资+奖金
{
return this.BasicSalary + this.Rewards;
}
public virtual void DisplayEmployeeInfo() //显示员工基本信息
{
Console.WriteLine("工号:" + WorkNum);
Console.WriteLine("姓名:" + Name);
Console.WriteLine("基本工资:" + BasicSalary);
Console.WriteLine("奖金:" + Rewards);
Console.WriteLine("应发工资:" + CalTotalSalary());
}
public void DisplayTotalNumber() //显示总员工人数
{
Console.WriteLine("总员工人数:" + totalNum);
}
(2)基于(1)题中的员工类派生定义部门经理类DepartManager:
①定义私有成员:nameDepart(部门名称)、performanceSalary(经理绩效工资)
②定义构造函数和析构函数,构造函数DepartManager()初始化经理类成员,析构函数~ DepartManager()显示当前经理离职信息
③在类DepartManager中添加相应的公有属性,NameDepart(部门名称,只读)、PerformanceSalary(经理绩效工资)
④重写方法CalTotalSalary(计算经理应发工资,基本工资+奖金+经理绩效工资)
⑤重写方法DisplayEmployeeInfo(显示经理当前信息)
⑥创建DepartManager的对象dm并调用新定义的两个公有方法
⑦试着把dm也加到数组列表中,并将Employee类中的DisplayEmployeeInfo前面加virtual,将DepartManager类中的DisplayEmployeeInfo前加override,看看运行结果如何,思考一下,它反映了面向对象编程中的什么特征?(将思考结果作为注释写在该方法的定义之前)
internal class DepartManager:Employee
{
private string nameDepart; //部门名称
private int performanceSalary; //经理绩效工资
public DepartManager(String workNum, String name, int basicSalary, int rewards, string nameDepart, int performanceSalary) : base(workNum,name,basicSalary,rewards) //调用父类的构造方法
{
this.nameDepart = nameDepart;
this.performanceSalary = performanceSalary;
}
~DepartManager() //析构函数
{
Console.WriteLine(Name+"经理离职");
}
public string NameDepart { get => nameDepart; set => nameDepart = value; }
public int PerformanceSalary { get => performanceSalary; set => performanceSalary = value; }
public new int CalTotalSalary() //重写父类函数 计算应发工资,基本工资+奖金
{
return this.BasicSalary + this.Rewards + this.performanceSalary;
}
public override void DisplayEmployeeInfo() //重写父类函数 显示所有信息
{
Console.WriteLine("工号:" + WorkNum);
Console.WriteLine("姓名:" + Name);
Console.WriteLine("基本工资:" + BasicSalary);
Console.WriteLine("奖金:" + Rewards);
Console.WriteLine("经理绩效工资:" + performanceSalary);
Console.WriteLine("应发工资:" + CalTotalSalary());
Console.WriteLine("部门名称:" + nameDepart);
}
}
(3)编程完成下面功能:
1) 定义一个抽象类或接口Shape,包含抽象方法GetArea和GetPerim(用来计算面积和周长),方法OutData(输出相关形状信息)
internal abstract class Shape
{
public abstract double GetArea();
public abstract double GetPerim();
public abstract void OutData();
}
2) 由Shape派生出三角形类Triangle类、矩形Rectangle类、圆形Circle类,定义相关形状信息数据成员(三角形包括三边长,矩形包括长宽值,圆形包括半径长),分别实现其构造函数初始化数据成员,并实现抽象方法GetArea、GetPerim 和OutData
只举一个三角形的
internal class MyTriangle : Shape
{
public string type="三角形";
public double edge1, edge2, edge3;
public MyTriangle(double edge1,double edge2,double edge3)
{
this.edge1 = edge1;
this.edge2 = edge2;
this.edge3 = edge3;
}
public override double GetArea() //计算面积,用海伦公式
{
double p = GetPerim()/2;
return System.Math.Sqrt(p*(p-edge1)*(p-edge2)*(p-edge3));
}
public override double GetPerim()
{
return edge1 + edge2 + edge3;
}
public override void OutData()
{
System.Console.WriteLine("形装名称:"+ type);
System.Console.WriteLine("边长分别为:" + edge1+" "+edge2+" "+edge3);
}
3) 创建具体类的对象,对功能进行验证
或实现以下功能:
创建一个点Point类,属性包括横坐标、纵坐标。要求能够完成点的移动操作、求两点距离操作,并利用运算符重载,对两个点进行比较(两点相等指橫坐标和竖坐标分别相等)。测试
3.委托和事件
(1)创建一个计算类,可以实现两个数的加减乘除(4个方法),也可以对数组进行累加操作(使用参数数组)。创建委托(仅对加减乘除进行委托)
delegate double mydelegate(double x, double y); //申明一个委托类型
class MydeClass
{
public double add(double x,double y) { return x + y; }
public double sub(double x, double y) { return x - y; }
public double mul(double x, double y) { return x * y; }
public double div(double x, double y) { return x / y; }
}
class Program
{
static void Main(string[] args)
{
MydeClass mydeClass = new MydeClass(); //定义mydeClass并实例化
mydelegate mydelegate = new mydelegate(mydeClass.add); //定义委托对象mydelegate并与mydeClass.add()绑定
Console.WriteLine("3+4={0}", mydelegate(3, 4));
mydelegate = new mydelegate(mydeClass.sub);
Console.WriteLine("3+4={0}", mydelegate(3, 4));
mydelegate = new mydelegate(mydeClass.mul);
Console.WriteLine("3+4={0}", mydelegate(3, 4));
mydelegate = new mydelegate(mydeClass.div);
Console.WriteLine("3+4={0}", mydelegate(3, 4));
Console.ReadLine();
}
}
(2)完成P140 课后题4(2),可尝试使用界面实现。
创建老师类和老师类,老师有一个方法“宣布考试开始”,学生类有一个方法“开始考试”
当老师类执行方法时“宣布考试开始”,学生类执行方法“开始考试”
public class Teacher
{
ListView listView;
String name;
public delegate void delegateType(); //申明事件委托类型
public event delegateType ClassEvent; //声明一个上课类型
public Teacher(String name,ListView listView)
{
this.name = name;
this.listView = listView;
}
public void Start() //定义引发事件函数
{
listView.BeginUpdate();
for(int i = 0; i < 1; i++) {
ListViewItem lvi = new ListViewItem();
lvi.Text = name + " " + "教师宣布考试";
this.listView.Items.Add(lvi);
}
listView.EndUpdate();
if (ClassEvent != null) ClassEvent();
}
public void End(String name)
{
listView.BeginUpdate();
ListViewItem lvi = new ListViewItem();
lvi.Text = name + "提交考卷,老师收卷";
this.listView.Items.Add(lvi);
listView.EndUpdate();
}
}
public class Student
{
ListView listView;
String name;
public delegate void delegateType(String name);
public event delegateType ClassEvent;
public Student(String name, ListView listView)
{
this.name = name;
this.listView = listView;
}
public void exam()
{
for (int i = 0; i < 1; i++)
{
ListViewItem lvi = new ListViewItem();
lvi.Text = "学生" + name + DateTime.Now + "开始答题";
this.listView.Items.Add(lvi);
}
}
public void endExam()
{
if (ClassEvent != null) ClassEvent(name);
}
}
private void button1_Click(object sender, EventArgs e)
{
Teacher t = new Teacher("李明",this.listView1);
Student s1 = new Student("小明", this.listView1);
Student s2 = new Student("小白", this.listView1);
Student s3 = new Student("小张", this.listView1);
Student s4 = new Student("小杭", this.listView1);
Student s5 = new Student("小红", this.listView1);
t.ClassEvent += new Teacher.delegateType(s1.exam); //订阅事件
t.ClassEvent += new Teacher.delegateType(s2.exam);
t.ClassEvent += new Teacher.delegateType(s3.exam);
t.ClassEvent += new Teacher.delegateType(s4.exam);
t.ClassEvent += new Teacher.delegateType(s5.exam);
t.Start();
s1.ClassEvent += new Student.delegateType(t.End);
s2.ClassEvent += new Student.delegateType(t.End);
s3.ClassEvent += new Student.delegateType(t.End);
s4.ClassEvent += new Student.delegateType(t.End);
s5.ClassEvent += new Student.delegateType(t.End);
s1.endExam();
s2.endExam();
s3.endExam();
s4.endExam();
s5.endExam();
}
四、实验结果分析、总结
不得少于200字