《C#.net》
实验报告
姓名:王璐
学号: 142871
日期: 2016/04/24
实验名称: 面向对象编程
成绩:
实验一类和对象编程
一、实验目的及要求
【实验目的】
1.如何创建类和对象。
2.如何为定义的类编写相应的方法。
3.如何通过属性访问对象中的数据
【实验要求】
1.写出程序,并调试程序,要给出测试数据和实验结果。
2.整理上机步骤,总结经验和体会。
3.完成实验日志和上交程序。
二、实验环境
Windows 7操作系统,Visual Studio 2005及以上版本
三、实验内容(题目、源代码、关键代码解释、运行结果、实验总结)
【实验1-1-1】
编写一个控制台应用程序,定义并使用一个时间类,该类包含时、分、秒字段与属性,具有将时间增加1秒、1分和1小时的方法,具有分别显示时、分、秒和同时显示时分秒的方法。
1、源代码:
using System;
public class Time
{
//字段
private int hour;
private int minite;
private int second;
//属性
public int Hour
{
get
{
return hour; }
set
{
hour=value;
}
}
public int Minite
{
get
{
return minite; }
set
{
minite=value; }
}
public int Second
{
get
{
return second; }
set
{
second=value; }
}
//方法
//加时方法
public void SAdd()
{
second++;
if(second>60)
{
minite++;
second=second%60;
}
if(minite>60)
{
hour++;
minite=minite%60;
}
if(hour>24)
{
hour=hour%24;
}
}
public void MAdd()
{
minite++;
if(minite>60)
{
hour++;
minite=minite%60;
}
if(hour>24)
{
hour=hour%24;
}
}
public void HAdd()
{
hour++;
if(hour>24)
{
hour=hour%24;
}
}
//输出方法
public void HPrint()
{
Console.WriteLine("现在时为:{0}",hour); }
public void MPrint()
{
Console.WriteLine("现在分为:{0}",minite);
}
public void SPrint()
{
Console.WriteLine("现在秒为:{0}",second);
}
public void TimePrint()
{
Console.WriteLine("得出准确时间为:{0}时{1}分{2}秒",hour,minite,second);
}
}
//主函数
public class Text
{
public static void Main()
{
Time time=new Time();
Console.WriteLine("获取系统时间中...");
time.Hour=DateTime.Now.Hour;
time.Minite=DateTime.Now.Minute;//刚刚发现前面的minute全写成minute了..英语不太..
time.Second=DateTime.Now.Second;
time.TimePrint();
Console.WriteLine("现在加一秒功能:");
time.SAdd();
time.TimePrint();
Console.WriteLine("现在加一分功能:");
time.MAdd();
time.TimePrint();
Console.WriteLine("现在加一时功能:");
time.HAdd();
time.TimePrint();
Console.WriteLine("现在依次调用三个方法输出时分秒:");
time.HPrint();
time.MPrint();
time.SPrint();
}
}
2、关键代码解释:
1)时钟循环需要取模运算,如第25时为25%24=1,即1时;另外还要注意秒的增加带给分、时的影响等。
2)加时功能直接使用time++,并注意判断对其他时间的影响
3)获取时间采用了DataTime里的函数,直接获取系统时间。
3、运行结果
4、实验总结
结合实践明白了属性的用法与含义,并且通过百度了解了怎么从系统中读取现在的时间。【实验1-1-2】
编写一个控制台应用程序,程序中有两个类定义,一个是创建程序时系统自动创建的类Class1,一个是用户自定义的Student类,要求该类包含私有字段:学号(字符串)、姓名(字符串)和性别(字符),具有三个属性:学号(读写)、姓名(只读)、性别(读写),具有有参构造方法、具有同时显示学生个人信息的方法。在Class1·中完成以下功能:
1)从键盘上输入一个学生的个人信息(学号、姓名、性别)。
2)修改该学生的学号和性别。
3)打印修改前后该学生的个人信息。
1、源代码
using System;
public class Student
{
//字段
private string num;
private string name;
private char sex;
private string oldnum;
private char oldsex;
//属性
public string Num
{
get
{
return num;
}
set
{
num=value;
}
}
public string Name
{
get
{
return name;
}
set
{
name=value;
}
}
public char Sex
{
get
{
return sex;
}
set
{
sex=value;
}
}
//方法
public Student(string c,string n,char s)
{
num=c;
name=n;
sex=s;
}
public void PrintIn()
{
Console.WriteLine("学号");
num=Console.ReadLine();
Console.WriteLine("姓名");
name=Console.ReadLine();
Console.WriteLine("性别");
sex=Convert.ToChar(Console.ReadLine());
}
public void Revise()
{
Console.WriteLine("请对输入的学号重新进行编辑:");
oldnum=num;
num = Console.ReadLine();
Console.WriteLine("请对输入的性别重新进行编辑:");
oldsex=sex;
sex =Convert.ToChar(Console.ReadLine());
}
public void PrintOut()
{
Console.WriteLine("修改前的信息为:学号:{0},姓名:{1},性别:{2}",oldnum,name,oldsex);
Console.WriteLine("修改后的信息为:学号:{0},姓名:{1},性别:{2}",num,name,sex);
}
}
public class class1
{
public static void Main()
{
Console.WriteLine("在本信息中男为Q女为N");
Student student1 = new Student("123", "王兰", 'N');
student1.PrintIn();
student1.Revise();
student1.PrintOut();
}
}
2、关键代码解释
1)为了能同时输出修改前修改后的名称,引入了字段oldnum,oldsex,将修改前的传给这两个值,并将新值覆盖原字段num和sex。
3、实验结果:
4、实验分析:
虽然设置了属性,但没用实际用到,感觉可能没有编好。。。另外为了满足第3个实验条件,同时输出,所以引入了新字段,不知道是否符合要求。
【实验1-1-3】
编写一个控制台应用程序,程序中有两个类定义,一个是创建程序时系统自动创建的类Class1,一个是用户自定义的Student类,要求该类包含私有实例字段:学号(字符串)、姓名(字符串)、成绩(double)以及私有静态字段:学生人数、学生总成绩、学生平均成绩,具有有参构造方法、显示学生个人信息的公有实例方法和显示学生人数、总成绩及平均成绩的公有静态方法。在Class1类的Main方法中完成以下功能:
1)从键盘上依次输入三个学生的个人信息(学号、姓名、成绩)。
2)统计全部学生的人数、总成绩和平均成绩。
3)打印学生们的个人信息及全部学生的人数、总成绩和平均成绩。
1、源代码
using System;
public class Student
{
//字段
private string num;
private string name;
private double score;
public static int count;
public static double addscore;
public static double average;
//方法
public Student()
{
count++;
}
public void PrintIn()
{
Console.WriteLine("请输入一位同学的信息:");
Console.WriteLine("学号:");
num = Console.ReadLine();
Console.WriteLine("姓名:");
name = Console.ReadLine();
Console.WriteLine("成绩:");
score =Convert.ToDouble(Console.ReadLine());
addscore += score;
}
public static void Average()
{
average = addscore / count;
}
public void Print1()
{
Console.WriteLine("学号:{0},姓名{1},成绩{2}",num, name, score); }
public static void Print2()
{
Console.WriteLine("输入的学生总人数为:{0}",count);
Console.WriteLine("同学们的总成绩为:{0}",addscore);
Console.WriteLine("同学们的平均成绩为:{0}",average);
}
}
public class class1
{
public static void Main()
{
Console.WriteLine("在本信息记录中,性别男为Q,女为N");
Student student1 = new Student();
student1.PrintIn();
Student student2 = new Student();
student2.PrintIn();
Student student3 = new Student();
student3.PrintIn();
Student.Average();
Console.WriteLine("同学们的信息为:");
student1.Print1();
student2.Print1();
student3.Print1();
Student.Print2();
//是否可以建立类数组?
}
}
2、关键代码解释
有关关键代码的解释后面的实验都直接写在代码的//备注里了。
3、实验结果
4、实验总结:
学会了在readline里面使用类型转换。认为也许可以使用类的数组来定义这三个学生,但没有实现。
实验二继承与多态编程
一、实验目的及要求
【实验目的】
1.理解继承的含义,掌握派生类的定义方法和实现;
2.理解虚函数在类的继承层次中的作用,虚函数的引入对程序运行时的影响,
能够对使用虚函数的简单程序写出程序结果。
3.编写体现类的继承性(成员变量,成员方法,成员变量隐藏)的程序;
4.编写体现类多态性(成员方法重载,构造方法重载)的程序。
【实验要求】
1.写出程序,并调试程序,要给出测试数据和实验结果。
2.整理上机步骤,总结经验和体会。
3.完成实验日志和上交程序。
二、实验环境
Windows 7操作系统,Visual Studio 2005及以上版本
三、实验内容(题目、源代码、关键代码解释、运行结果、实验总结)
【实验1-2-1】
创建一个描述图书信息的类并测试。类中应保存有图书的书号、标题、作者、出版社、价格等信息。
1)定义图书类Book,Book类中包含isbn(书号)、title(标题)、author(作者)、press(出版社)、price(价格)等私有字段。由于对一本书来说,书号是唯一的,因此,isbn字段应声明为只读的。
2)为Book类中的每个字段定义相应的属性,由于isbn字段只读的,其相应属性也应该是只读的。
3)为Book类定义两个构造函数,其中,一个构造函数将所有字段都初始化为用户指定的值,另一个构造函数只要求用户指定有关书号的信息,它将调用上一个构造函数初始化对象,初始化时,价格取0,除书号的其他信息取“未知”。
4)为Book类定义方法Show,Show方法用于显示图书的所有信息。
5)编写Main方法测试Book类,Main方法中分别使用上述两个构造函数创建Book对象。
1、源代码
using System;
public class Book
{
//定义私有字段
private readonly string isbn;
private string title;
private string author;
private string press;
private double price;
//定义属性
public string Isbn
{
get
{
return isbn;
}
}
public string Title
{
get
{
return title;
}
set
{
Title = value;
}
}
public string Author
{
get
{
return author;
}
set
{
Author = value;
}
}
public string Press
{
get
{
return press;
}
set
{
Press = value;
}
}
public double Price
{
get
{
return price;
}
set
{
Price = value;
}
}
//定义构造函数
public Book(string isbn, string title, string author, string press, double price) {
this.isbn = isbn;
this.title = title;
this.author = author;
this.press = press;
this.price = price;
}
//继承第一个构造函数
public Book(string isbn):this(isbn,"未知","未知","未知",0)
{}
public void Show()
{
Console.WriteLine("这本书的信息如下:");
Console.WriteLine("书号:{0}", isbn);
Console.WriteLine("标题:{0}", title);
Console.WriteLine("作者:{0}", author);
Console.WriteLine("出版社:{0}", press);
Console.WriteLine("价格:{0}", price);
}
}
class BookTest
{
public static void Main()
{
Console.WriteLine("请按<行>依次输入第一个书本信息,依次为书号,标题,作者,出版社,价格");
Book book1 = new
Book(Convert.ToString(Console.ReadLine()),Convert.ToString(Console.ReadLine()),Convert.ToString(Consol e.ReadLine()),Convert.ToString(Console.ReadLine()),Convert.ToDouble(Console.ReadLine()));
book1.Show();
Console.WriteLine("请输入第二个书本的书号");
Book book2 = new Book(Convert.ToString(Console.ReadLine()));
book2.Show();
}
}
2、实验结果
3、实验总结:
学会了用构造函数继承构造函数,另外经过查阅还明白了this指针可以代替对象来调用对象的字段。还实践了可以在构造函数调用时调用输入函数。
【实验1-2-2】
编写一个程序计算出球、圆柱和圆锥的表面积和体积。
1)定义一个基类圆,至少含有一个数据成员:半径;
2)定义基类的派生类:球、圆柱、圆锥,都含有求体积函数,可以都在构造函数中实现,也可以将求体积和输出写在一个函数中,或者写在两个函数中,请比较使用。
3)定义主函数,求球、圆柱、圆锥的和体积。
3、设计一个图书卡片类Card,用来保存图书馆卡片分类记录。
1)这个类的成员包括书名、作者、馆藏数量。
2)至少提供两个方法,store书的入库处理,show显示图书信息。
3)程序运行时,可以从控制台上输入需要入库图书的总量,根据这个总数创建Card对象数组,然后输入数据。
4)可以选择按书名、作者、入库量进行排序。
1、源代码
using System;
public class Circle //定义基类圆
{
protected double R;
public const double PI=3.14;
}
//定义继承类球,继承圆
public class Ball:Circle
{
//定义表面积、体积字段
protected double Vol;
protected double Area;
//构造函数
public Ball(double r)
{
R=r;
}
//求表面积和体积的方法。采用先求表面积和体积再输出
public double GetArea()
{
Area=4*PI*R*R;
return Area;
}
public double GetVol()
{
Vol=(4.0/3.0)*PI*R*R*R;
return Vol;
}
public void Print()
{
Console.WriteLine("球的表面积为:{0}",Area);
Console.WriteLine("球的体积为:{0}",Vol);
}
}
//定义继承类圆柱,继承圆,比较两种输出体积的方法(圆锥采用不继承圆,直接继承圆柱的做法) public class Cyl:Circle
{
//定义表面积、体积字段
protected double Vol;
protected double Area;
protected double h;
//构造函数
public Cyl() { }
public Cyl(double r,double h)
{
R=r;
this.h=h;
}
//采用直接输出体积和表面积
public virtual void GetArea()
{
Area=h*2*PI*R+2*PI*R*R;
Console.WriteLine("圆柱的表面积为:{0}",Area);
}
public virtual void GetVol()
{
Vol=h*PI*R*R;
Console.WriteLine("圆柱的体积为:{0}",Vol);
}
}
public class Cone:Cyl
{
//字段已经定义,构造函数不继承
public Cone(double r,double h)
{
R=r;
this.h=h;
}
//重写基类中的表面积、体积函数
public override void GetArea()
{
Area=PI*R*R+0.5*2*PI*R*System.Math.Sqrt(R*R+h*h);
Console.WriteLine("圆锥的表面积为:{0}",Area);
}
public override void GetVol()
{
Vol = (1.0 / 3.0) * h * PI * R * R;
Console.WriteLine("圆锥的体积为:{0}",Vol);
}
}
class Text
{
public static void Main()
{
Console.WriteLine("请输入球的半径:");
double count = Convert.ToDouble(Console.ReadLine());
Ball ball = new Ball(count);
double A=ball.GetArea();
double V=ball.GetVol();
ball.Print();
Console.WriteLine("请按'行'依次输入圆柱的半径、高");
Cyl cyl = new Cyl(Convert.ToDouble(Console.ReadLine()), Convert.ToDouble(Console.ReadLine()));
cyl.GetArea();
cyl.GetVol();
//相比较两种输出方法,直接输出法更简单。
Console.WriteLine("请按'行'依次输入圆锥的半径、高");
Cone cone = new Cone(Convert.ToDouble(Console.ReadLine()), Convert.ToDouble(Console.ReadLine()));
cone.GetArea();
cone.GetVol();
}
}
2、实验结果
3、实验总结
在计算圆锥表面积时学会了的使用
方法没有采用"0"个参数的重载:说明参数不能为空,错误出在把Convert.ToDouble (Console.ReadLine())括号里和括号外的内容写反了
另外很粗心在WriteLine里{}里面忘记加0,编译没出错但抛出了异常,又找了半天才修改好。。
【实验1-2-3】
设计一个图书卡片类Card,用来保存图书馆卡片分类记录。
1)这个类的成员包括书名、作者、馆藏数量。
2)至少提供两个方法,store书的入库处理,show显示图书信息。
3)程序运行时,可以从控制台上输入需要入库图书的总量,根据这个总数创建Card对象数组,然后输入数据。
4)可以选择按书名、作者、入库量进行排序。
1、源程序
using System;
public class Library
{
public static int Num=0;
public static void Show()
{
Console.WriteLine("图书馆共入库了{0}本书", Num);
}
}
public class Card
{
private string name;
public string Name
{
get
{
return name;
}
}
private string author;
public string Author
{
get
{
return author;
}
}
private int num=0;
public int Num
{
get
{
return num;
}
}
public void Store()
{
Console.WriteLine("输入要入库的书信息,包括书名、作者、入库量");
https://www.wendangku.net/doc/7b9280985.html, =Convert.ToString(Console.ReadLine());
this.author = Convert.ToString(Console.ReadLine());
this.num=Convert.ToInt32(Console.ReadLine());
Library.Num+=num;
}
public void Show()
{
Console.WriteLine("图书信息如下:");
Console.WriteLine("书名:{0},作者:{1},馆藏数量{2}",name,author,num);
}
}
public class Text
{
public static void Main()
{
int i;
Card temp;
Card[] card = new Card[3];
for (i = 0; i < 3; i++)
{
card[i] = new Card();//学会了定义对象的数组,应该先创建数组,再依次对里面的所有成员进行创建。 card[i].Store();
}
Library.Show();
Console.WriteLine("请选择按什么排序:、书名2、作者3、存库量");
int a = Convert.ToInt32(Console.ReadLine());
switch (a)
{
case 1:
{
Console.WriteLine("按书名从小到大排序");
for (i = 0; i < 2; i++)
{
for (int j = i; j < 3; j++)
{
if (https://www.wendangku.net/doc/7b9280985.html,pare(card[i].Name, card[j].Name) > 0)
{
temp = card[i];
card[i] = card[i + 1];
card[i + 1] = temp;
}
}
}
for (i = 0; i < 3; i++)
{
card[i].Show();
}
}
break;
case 2:
{
Console.WriteLine("按作者从小到大排序");
for (i = 0; i < 2; i++)
{
for (int j = i; j < 3; j++)
{
if (https://www.wendangku.net/doc/7b9280985.html,pare(card[i].Author, card[j].Author) > 0)//学会了比较函数的使用
{
temp = card[i];
card[i] = card[i + 1];
card[i + 1] = temp;
}
}
}
for (i = 0; i < 3; i++)
{
card[i].Show();
}
}
break;
case 3:
{
Console.WriteLine("按存库量从小到大排序");
for (i = 0; i < 2; i++)
{
for (int j = i; j < 3; j++)
{
if (card[i].Num-card[j].Num> 0)
{
temp = card[i];
card[i] = card[i + 1];
card[i + 1] = temp;
}
}
}
for (i = 0; i < 3; i++)
{
card[i].Show();
}
}
break;
default:
Console.WriteLine("输入错误。");
break;
}
}
}
2、实验结果(实验结果检测时选择了用2号--按作者从小到大排序)
3、实验总结
学会了定义对象的数组,应该先创建数组,再依次对里面的所有成员进行创建。
经过查阅学会了比较函数的使用。
类的多态性练习
【实验1-2-4】
设计雇员系统。
1)定义雇员基类,共同的属性,姓名、地址和出生日期;
2)派生类:程序员,秘书,高层管理,清洁工,他们有不同的工资算法,其中高级主管和程序员采用底薪加提成的方式,高级主管和程序员的底薪分别是5000元和2000元,秘书和清洁工采用工资的方式,工资分别是3000和1000,以多态的方式处理程序。
1、源代码
using System;
public class Employee
{
private string name;//定义雇员基类的姓名、地址、出生日期、底薪、提成以及其属性。
//属性为可读可写,实验结果中为了简练没有调用姓名地址出生日期等,不过调用了底薪、提成及其属性以体现多态。
public string Name
{
get
{
return name;
}
set
{
name=value;
}
}
string address;
public string Address
{
get
{
return address;
}
set
{
address=value;
}
}
string birth;
public string Birth
{
get
{
return birth;
}
set
{
birth=value;
}
}
double salary;//底薪
public virtual double Salary {
get
{
return salary;
}
set
{
salary = value;
}
}
double ticheng;//提成
public virtual double Ticheng {
get
{
return ticheng;
}
set
{
ticheng = value;
}
}
public virtual void SumSalary() { }//工资算法不同,所以定义虚函数工资计算方法public virtual void Show() { }//工资输出名称不同,所以定义了可重写的打印方法}
public class Programmer : Employee //程序员,继承雇员基类
{
public Programmer()
{
Salary=2000;
Console.WriteLine("请输入程序员提成");
Ticheng=Convert.ToDouble(Console.ReadLine());
}
public override void SumSalary()//重写工资计算方法,下面几个类同
{
Salary+=Ticheng;
}
public override void Show()//重写打印方法
{
Console.WriteLine("程序员的总工资是{0}",Salary);
}
}
public class Manager : Employee//主管高层,继承雇员基类
{
public Manager()
{
Salary=5000;
Console.WriteLine("请输入主管高层提成");
Ticheng=Convert.ToDouble(Console.ReadLine());
}
public override void SumSalary()
{
Salary+=Ticheng;
}
public override void Show()
{
Console.WriteLine("主管高层总工资是{0}",Salary);
}
}
public class Sec : Employee//秘书,继承雇员基类
{
public Sec()
{
Salary=3000;