0713第二天C#中的类
4.1 什么是类 现实生活中,人就是一个类,但是人只是一个抽象的概念,它
指的是所有人。如果我们想找人聊天,此时我们就需要具体的人,比 如张三。人是这个类别中的个体,具有一些公共的特征(姓名,性别, 年龄)和行为(吃饭,工作,思考和睡觉)。所以,类代笔具有公共 属性和行为的对象。
C#中如何定义一个类?
我们在C#中定义一个类很简单,只需要使用class关键字并且 按照格式定义即可。具体方法如下所示:
class Person
{
// }
上面的代码定义了一个类,定义之后,可在本项目或者其它项
目中通过实例化来访问该类,但是并非所有的都能这样访问。
默认情况下,如果class之前没有显式指定访问修饰符,则类的 访问修饰符为internal,表示仅在当前项目内可以被访问。
除了使用internal来修饰类外,还可以通过 private,protected,public ,abstract,sealed等修饰符,以及这几 个修饰符的组合。下表列出了可以使用的访问修饰符。


4.2 类的成员
定义类之后,还需要在类中定义成员。类的成员包括字段、属性、方法、 构造函数等。它们同类一样,也具有自己的访问权限。你可以为它们指定 public,private,internal和protected等修饰符。也可使用static修饰为静态 成员。下表列出了每个修饰符应用于类成员的访问权限。

4.3.1 字段
字段的定义由三部分组成-访问修饰符,字段的类型和字段名
称,下面的代码给出了字段的定义
public class Person{
private string name;
public int age;
protected bool sex;
}
用关键字readonly或const来定义字段。若使用readonly, 表示该字段是只读的,若使用const,表示该字段是不可变的。
public class Person{
private readonly string name;
public const int age=18;
protected bool sex;
}
若使用readonly,则不需要在定义的时候初始化,而是可以在构
造函数里面完成初始化,若使用const修饰,如果没有在定义字段时 初始化,就会产生编译错误。
也可以使用static关键字来声明静态字段。静态字段与实例字 段的区别是静态字段必须通过类来访问,而实例字段则需要通过类的 对象实例进行访问。
public class Person{
public static string name;
public int age;
}
以上定义的静态字段name只能通过类名,即Person.name的方式 进行访问;而对于实例字段age,应该通过类的实例对象,即new Person().age的方式进行访问。
4.3.2 属性
属性是对字段的扩展。根据面向对象的基本思想,字段最好设 置为private,因为这样可以防止客户端直接对字段进行修改,从而保 证内部成员的完整性。为了访问类的私有字段,C++提供了属性机 制。
public class Person{
private string name;
public string Name
{
//get
get
{
return name;
}
//set
set
{
3/2 2
//value
name = value;
}
}
}
通过属性来访问字段,避免了调用方法。
当属性仅含有get访问器,或者set访问器为private级别时,这 样的属性称之为只读属性;当属性仅包含set访问器,或者get访问器 为private级别时,称之为只写属性。只读属性和只写属性的定义如 下所示:
public class Person
{
//
private string name;
private int age;
private bool sex;
//set
public sting Name{
get{ return name;}
private set{ name = value;}
}
//set
public int Age{
//get
get{ return age;}
}
//
public bool Sex{
private get{ return sex;}
set{ sex = value;}
}
}
够直接访问私有字段之外,还可以加入自己的逻辑
代码。 和静态字段类似,属性也可以通过static关键字声明为静态属
性,不能在静态属性中使用非静态
public class Person{
private static string name;
public static string Name{
get{ return name;}
set{ name = value;}
}
}用二段式达到静态成员函数调用非静态成员函数
public class A
{
public static void create(){
A a = new A ();
a.print();
}
public void print(){
Console.WriteLine ("print");
}
}
4.3.3构造函数
如果类之定义了一个或者多个私有构造函数,而没有公共构造 函数,则该类不能在类外调用类的私有构造函数来创建类的实例。单例模式的典型应用:
class Person{
private string name;
public static Person person;
public string Name{
get { return this.name;}
}
private Person(){
Console.WriteLine("");
this.name = "Learn Hard";
}
public static Person getInstance(){
if (person == null) {
person = new Person ();
}
return person;
}
}
public static void Main (string[] args)
{
Person p = Person.getInstance ();
Console.WriteLine (p.Name);
}
2:静态构造函数 除了实例构造函数之外,静态构造函数用于初始化类中的静态
成员,在创建第一个实例或者引用任何静态成员之前,CLR都会自动 调用静态构造函数。
class Person{
private static string name;
static Person(){
Console.WriteLine("");
name = "Learnig Hard";
}
public static string Name{
get { return name;}
}
}
public static void Main (string[] args)
{
}
Console.WriteLine (Person.Name);
Console.WriteLine (Person.Name);
在上面的代码之中,两次调用了Person对象的静态Name属性, 但只输出了一次静态构造函数被调用,这说明静态构造函数只执行一 次。特点如下:
1:静态构造函数不能使用任何访问修饰符
2:静态构造函数不能带有任何参数
3:静态构造函数只会执行一次
4:不能直接调用静态构造函数
5:程序员无法直接控制静态构造函数调用时机
用C#翻译第一次大作业
using System;
namespace homework1
{
public class Date
{
private int year;
private int month;
private int day;
public Date (int _year,int _month,int _day)
{
year = _year;
month = _month;
day = _day;
}
public int Year{
set{ year = value;}
get{ return year;}
}
public int Month{
set{ month = value;}
get{ return month;}
}
public int Day{
set{ day = value;}
get{ return day;}
}
public void print(){
Console.WriteLine ("year : {0}",year);
Console.WriteLine ("month : {0}",month);
Console.WriteLine ("day : {0}",day);
}
}
public class Person
{
string name;
string email_address;
Date birthday;
public Person(string _name,string _email_address,int _day,int _month,int _year){
name = _name;
email_address = _email_address;
birthday = new Date (_year, _month, _day);
}
public Person(){
}
public string Name{
get{ return name;}
set{ name = value;}
}
public string Email_address{
get{ return email_address;}
set{ email_address = value;}
}
public Date Birthday{
get{ return birthday;}
set{ birthday = value;}
}
public void print(){
Console.WriteLine ("name : {0}",name);
Console.WriteLine ("emailaddress : {0}",email_address);
birthday.print ();
}
}
public class PersonSet
{
int capacity = 4;
int size = 0;
int index = 0;
Person []elements;
public PersonSet (int initial = 4)
{
elements = new Person[initial];
capacity = initial;
}
public void addPerson(Person p){
if (size == capacity) {
Person[] temp = elements;
elements = new Person [capacity *= 2];
for (int i = 0; i < size; i++) {
elements [i] = temp [i];
}
}
elements [size++] = p;
}
public void print(){
Console.WriteLine ("size : ",+size);
for (int i = 0; i < size; i++) {
elements [i].print ();
}
}
public Person removePerson(){
--size;
Person p = elements [size];
p.print ();
if (size<capacity/2) {
Console.WriteLine ("remove without parameter");
Person []temp=elements;
elements=new Person [capacity/=2];//size=5
for (int i = 0; i < size; ++i) {
elements[i]=temp[i];
}
}
return p;
}
public Person nextPerson(){
if (index == size) {
index = 0;
}
return elements[index++];
}
public int Size{
private set{ size = value;}
get{ return size;}
}
public void reset(){
index = 0;
}
}
class MainClass
{
public static void Main (string[] args)
{
Person p1 = new Person("Lou", "lou@chat.ca", 20, 6, 1960);
Person p2 = new Person("Frank","f123@chat.ca", 20, 3, 1967);
Person p3 = new Person("Ann", "ann@chat.ca", 20, 8, 1960);
PersonSet boys = new PersonSet();
PersonSet girls= new PersonSet();
boys.addPerson(p1);
//test to see if the same object is retrieved from the set.
if (p1 != boys.removePerson())
{
Console.WriteLine ("ERROR: the objects are different");
}
else
{
Console.WriteLine ("Good, the objects are the same ");
}
boys.addPerson(p1);
boys.addPerson(p2);
girls.addPerson(p3);
boys.addPerson(new Person("John", "f123@chat.ca", 20, 3, 1967));
girls.addPerson(new Person("Sue","f123@chat.ca", 20, 3, 1967));
boys.addPerson(new Person("Frank", "frank@chat.ca", 25, 4, 1958));
girls.addPerson(new Person("Mary", "mary@chat.ca", 25, 4, 1955));
boys.addPerson(new Person("John", "johnchat.ca", 12, 12, 1970));
//print all the boys using the removeSomeElement() method and delete //them
int numberOfBoys = boys.Size;
Console.WriteLine ("number of boys = "+numberOfBoys);
for(int i = 0; i<numberOfBoys; i++)
{
Person boy = boys.removePerson();
boy.print();
}
//print the girls using the << operator of the SetOfPersons class
Console.WriteLine ("number of girls = "+girls.Size);
girls.print();
//print of the girls birthdays and using the someElement() method
int numberOfGirls = girls.Size;
girls.reset();
for(int i = 0; i<numberOfGirls; i++)
girls.nextPerson().Birthday.print();
//delete all the girls from the heap
numberOfGirls = girls.Size;//int
for(int i = 0; i<numberOfGirls; i++)
{
Person her = girls.removePerson();
}
}
}
}