?
第5关:static静态对象
任务描述
大学校园内有各种各样的社团,一般每个社团都会不定期举办一些大型活动,活动的时间和地点可能会有所差异。例如某摄影社团2018 年上半年活动表:
次数统计 时间 地点 1 2018-03-22 北京大学 2 2018-05-01 中国人民大学 3 2018-06-01 清华大学
本关任务:根据编程要求编写一个大型活动类,要求能够统计举办活动的次数。
相关知识
static
使用static 修饰符声明一个静态成员。我们刚学习过类class ,类是以对象为基础,而静态变量是与类类型同一级别的类型,不属于任何对象。
staitc 修饰符可用于修饰类、方法、属性、操作符、事件或是构造函数,但不可用来修饰索引、Finalize() (即析构函数)等。
使用方法如下:
static <修饰对象>
例如,我们使用static 修饰类:
staitc class Person{ //类成员 }
静态变量的声明和使用
使用static 修饰类成员变量将不会被对象实例引用。相反,该成员变量可通过变量类型名称直接使用。 例如:
class Person { public static string name; //使用static修饰 public int age; } class myCaller { public static void Main() { Person p = new Person(); p.age = 20; //此处仅能使用age } }
以上这段代码,在类myCaller 中实例化类Person 对象p ,该对象无法调用成员变量name 。
使用类名称调用name : 具体如下代码:
class Person { public static string name; public int age; } class myCaller { public static void Main() { Person p = new Person(); p.age = 20; //此处仅能使用age Person.name = "Jackie"; //直接使用类型Person调用 } }
由于name 为静态变量,所以每一次赋值都会更改name 的值,而不是像类Person 实例化多个对象的属性值,类成员变量对应的对象属性值可互不相同,例如:
class Person { public static string name; public int age; } class myCaller { public static void Main() { Person p1 = new Person(); //创建三个实例 Person p2 = new Person(); Person p3 = new Person(); p1.age = 10; //三个实例互不相同 p2.age = 20; p3.age = 30; Person.name = "Jackie"; //共同拥有属性name } }
在调用类myCaller 中实例化三个对象p1 、p2 、p3 ,三个对象age 属性分别为10 、20 和30 ,而name 有且仅有一个值"Jackie" 。
实际中,对于静态成员可以这样理解:我们定义一个类employee 来表示公司员工,假定employee 包含一个方法用来计算员工数量,包含一个属性用来保存员工数量。当我们使用empliyee 实例化一个员工对象的时候,员工对象自身和计算、存储员工数量的方法、属性并无太大关联,相对的,该方法、属性更适用于创建一个新的公司company 类。因此,在employee 类中,该方法和属性被声明为静态类型最为合适。
我们需要注意:
- 使用
this 无法引用使用static 定义的成员变量。 - 如果使用
static 修饰类,那么这个类的所有成员皆是静态的。 - 类和静态类可以包含静态构造函数,静态的构造函数会在程序启动到实例化类之间调用。
一个实例
我们将员工类实现,如下:
namespace J5 { public class Emlployee { public string name; //员工属性:姓名 public Emlployee(string name) { this.name = name; } public static int employeeNum; //非员工属性:员工数量 public static void updateEmployeeNum() { employeeNum++; } } public class myCaller { public static void Main(string[] args) { Console.Write("Enter the new employee's name:"); string name = Console.ReadLine(); Emlployee e = new Emlployee(name); Console.Write("Enter the current number of employee:"); string num = Console.ReadLine(); Emlployee.employeeNum = Convert.ToInt32(num);//获取并更新员工数量 Emlployee.updateEmployeeNum(); Console.WriteLine("Name:"+e.name); Console.WriteLine("Number of Employee:"+Emlployee.employeeNum); } } }
该实例读取一个新员工对象姓名,然后通过函数updateEmployeeNum() 对员工数加一更新员工数量,之终显示员工数量的最新状态。此段代码使用键盘输入员工名字及员工数量初始值。
运行结果如下:
特别实例
此段代码显示了静态变量之间赋值过程:
namespace J5 { class Test { static int x = y; static int y = 4; public static void Main() { Console.WriteLine(x); Console.WriteLine(y); x = 100; Console.WriteLine(x); Console.WriteLine(y); } } }
其中静态变量x 声明的初始值为未定义变量y ,运行结果如下:
结果表明,当变量x 未被显示赋值之前,其值是未定义的。
编程要求
本关的编程任务是补全右侧代码片段中Begin 至End 中间的代码,具体要求如下:
- 补全大型活动类
BigEvent ,使用static 关键字定义一个int 类型静态变量counter ,使之随着BigEvent 类实例对象的创建而自增。 - 程序运行正常,实际输出与测试中的预期输出相符。
测试说明
测试过程:
- 平台将编译用户补全后的代码,并根据程序的输出判断程序是否正确。
以下是测试样例:
测试输入: 预期输出: 3
以中有足乐者,不知口体之奉不若人也。 --宋濂 开始你的任务吧,祝你成功!
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace J5
{
public class BigEvent
{
private string time;
private string location;
/********** Begin *********/
public static int counter=0;
public BigEvent()
{
counter++;
}
/********** End *********/
}
public class myCaller
{
public static void Main(string[] args)
{
BigEvent b1 = new BigEvent();
BigEvent b2 = new BigEvent();
BigEvent b3 = new BigEvent();
Console.WriteLine(BigEvent.counter);
}
}
}
|