C#概念C#的类

《叩开C#之门》连串之四

四、定义C#的类

既然类类型是C#中最关键、最普遍的门类,由此它是小编要介绍的要紧,实际上,C#中的许多风味都得以透过类类型来反映。

前方早已介绍,一个类对象中,首要不外乎字段、属性和措施。但是除了,在类项目中仍能定义嵌套类,也得以定义一个常量。

对此一个没有别的编程知识的初学者而言,或者还应介绍一下常量与变量。然而从它们的名字就可以相当清晰地分辨二者的差异,常量其值是不行更改的,而变量的值则能够修改,除非该变量是只读的(如设置为readonly)。

最好的常量的事例就是圆周率值,那么些值当然是不转移的,如若保留小数点后七位,其值为3.1415926。不过一旦大家要再三使用该值,则输入这么多数字自然不是好的选项,何况一旦用户需要圆周率尤其可信,必要保留越来越多的小数位,要修改起来就老大困难了。因而大家需求定义一个常量:
const PI = 3.1415926;

此刻pi就象征了3.1415926,要动用圆周率,直接取pi的值即可:
square = PI * radius;

留意上边的表明式,其中PI是常量,在概念它时,使用了const关键字;而square和radius则为变量,定义如下:
double square, radius;

一经定义了PI为常量,那么该类对象被确立将来,就无法改改了,而变量是足以修改的。如下的代码是谬误的:
PI = 3.1415926535897;
square = PI * radius;

而上边的两行代码则是不易的:
radius = 2.5;
square = PI * radius;

类的字段其实也是变量。如成千成万三中的类User,就包罗有字段m_name,m_password,m_tryCounter。它们的品种分别为string,string,int。字段如故能够应用public,internal,protected,private来修饰它。不过,小编提出如非优异意况,不要将字段修饰为public。因为,依照”对象封装”的尺度,应尽量防止将一个门类的字段以国有形式提需要外部。终究,对于字段而言,对象对它的操纵尤其弱,一旦公开在外,则调用者可以比较不难的对其进行操作,尤其是写操作,从而或然会招致错误。例如,大家为眼下定义的User类扩充一个age(年龄)字段,若是作者将其定义为public字段,如下所示:
public int Age;

这就是说调用者大概会将Age的值设为负数:
user.Age = -5;

对此字段的概念而言,并不可以判定那样一种不合常理的操作,因为咱们对字段的写操作的主宰无能为力。

我们可以看看,那里所谓的字段值,其实可以对应于前面所讲的目的的品质。例如姓名,年龄,就是一个用户的性质。假诺字段无法安装为public,那么调用者又怎样访问它们啊?答案就是使用C#类中的property(属性)。

所谓“属性”,很大程度可以视作是对“字段”的一种包装,它选用一种被叫作“get/set访问器”分别控制对字段的读写操作,并披露一个属性值,如Age属性:
private int m_age;
public int Age
{
 get {return m_age;}
 set
 {
  if (value < 0)
  {
   throw new ArgumentOutOfRangeException(“Age must be greater than or
equal to 0”);
  }
  m_age = value;
 }
}

下边的代码中,throw语句的功力是抛出一个卓殊,大家临时能够不去理会它,而是将注意力放到get和set访问器上。首先,大家定义了一个民用字段m_age,然后再定义一个公家属性Age。在该属性中,get重回私有字段的值m_age,而在set中,首先会咬定value的值,借使小于0,那么这些值是私行的,就将抛出一个至极,截止往下举办,并告知你对Age值的装置错误了。当然,大家也足以为value值设置更严酷的渴求,例如不允许value大于150。至少人的岁数以往从未有过超越150岁的啊。

唯恐会有人疑问value毕竟是怎样?它其实是C#中提供的首要字,代表的就是你赋给该属性的真正的值,例如:
user.Age = 30;

此时是对Age属性赋值,.Net会举办set访问器,而value值就是30。然后判断30是或不是小于0。分明不符合条件,不会抛出特别,继续执行,将value值30赋给字段m_age。为啥要赋给m_age呢?让大家再看看get访问器,它事实上就是一个读操作,再次回到的值是如何?对了,就是字段m_age,如下所示:
user.Age = 30;     //set操作,将字段m_age设置为30;
Console.WriteLine(“User’s Age is {0}.”, user.Age);  
//get操作,将m_age的值取出;

那会儿就会在控制台下呈现:
User’s Age is 30.

别的,对于有些特种的渴求,大家在将字段封装为属性时,可以只设置它的get访问器恐怕set访问器,这样那性格子就是只读属性,只怕只写属性了。那样显著更便利对象的包裹。毕竟对于集体字段而言,我们最能得以操纵它为只读(设置为readonly),却无力回天设置为只写。

从上可以看来,实际上属性就是对字段进行三次封装。通过那个包裹,使大家对字段m_age的读写都拥有了控制效果,至少今后的Age属性可以决定赋值为负数的气象了。那就是性质的便宜。

在C#
2.0中,除了可以对所有属性设置public等做客修饰符外,对里面的get/set访问器同样可以设置访问修饰符,当然它要碰到肯定的限量。由于有些限制和接口、重写关于,笔者暂时不会介绍,在此间,作者仅介绍访问器和品质的造访修饰符争持难题。
1、即便整个属性被设置为public,则其访问器没有界定;
2、借使整个属性被安装为protected
internal,则访问器的拜会修饰仅能设置为internal,protected只怕private中的一种;
3、尽管全勤属性被安装为internal只怕protected,那么访问器的拜会修饰只好是private。
如下例:
public Class A
{
 private string m_text;
 private int m_count;
 public string Text
 {
  get {return m_text;}
  protected set { m_text = value;}
 }
 internal int Count
 {
  private get {return 5;}
  private set {m_count = value}
}
}

从程序的原形来看,其实属性就是一种特殊的办法,它一律上边的代码:
public int GetAge()
{
 return m_age;
}
public void SetAge(int age)
{
 m_age = age;
}

从这么些意义上来领会get/set访问器的拜访级别修饰,就更易于明白了。实质上,所谓的访问器的造访级别修饰,不外乎就是对章程举办访问级别修饰罢了。当然,C#C#,中提供的品质要比访问字段的get/set方法越发便利。一般而言,如要定义方法,应该是和一个目的的作为有关,例如种类三定义的User类中的SignIn()和SignOut()方法,它们代表的是目标User的表现:登录和剥离。

概念一个类的办法,必须概括多个元素:方法修饰符,方法名,重临类型,参数,以及方法体,例如Add方法:
public int Add(int x, int y)
{
 return x + y;
}

public即为大家的法子修饰符,它表示了该办法能被访问的级别。当然,修饰的点子的重点字还包涵static,virtual,abstract等,但是这几个情节会在未来介绍。方法名自然是Add了,自然属于方法的名字。重返类型为int,代表该方法会重回一个结果,该结果类型为int类型。参数有八个,分别为x和y,它们的项目都以int。调用者可以通过参数传递值到方法体中,并对它们进行操作。方法体则是花括号中的内容。

如若Add方法是概念在类Calculator中,那么该方式的调用为:
Calculator cal = new Calculator();
int result = cal.Add(3,5);

通过对Add的调用,并传播3和5的参数,最终得到结果8,并赶回。因而,此时变量result的值就为8。而首先行代码,则是运用new关键字对Calculator类进行实例化,拿到一个对象cal。通过对象cal,才得以调用Calculator类的集体艺术、属性或字段。

为何要开展实例化呢?我们定义一个类类型,是为调用者所利用的,否则就失去其含义了。但我们定义的那样一个类类型,仅仅是代表了某种格式而已,例如User类表达它是一个class,它装有了一些字段、属性和形式。通过那样的定义,大家在动用这么些项目标目的时,.Net可以辨识它。而只要实在要调用那几个品种对象,就不或许不开展”实例化”,那么些操作就会在运转时期,制造一个个对象,并被放在内存空间中供程序调用。就好比”人”就是一个类类型,而某一个现实的人,才是被实例化的、真正存在的靶子。要使得一个类类型被实例化,就须求为该类型提供”构造器”。构造器是一种很是的不二法门,它没有回来类型,且其方法名和档次名保持一致,如Calculator类的定义以及它的构造器:
public class Calculator
{
 public Calculator()
 {
 }
 public int Add(int x, int y)
 {
  return x + y;
 }
}

Calculator()方法就是一个”构造器”,那些构造器并没有参数,在C#中,也被叫做暗中认同的构造器,即便不定义该构造器,.Net也会为它暗中同意创制。例如在Calculator类中,大家完全可以删去Calculator()构造器的概念。然则,一旦我们定义了有参数的构造器时,则该暗中认同构造器将不设有,倘若大家再要求不带参数创立实例的话,就须求显式创造该构造器了。例如此前的User类。假设姓名和密码是此类一个极度关键的属性,一大半景况下,如果要创设User对象时,都亟需那八个属性的值时,大家就足以为User类专门创制一个构造器:
public class User
{
 public User(string name, string password)
 {
  m_name = name;
  m_password = password;
 } 
}

专注在那个构造器中,接收五个参数name和password,并将其值赋给User类的字段m_name,m_password。因而,当我们由此如下的方法创设User类的实例时,我们制造的靶子就早已拥有Name和Password的值了:
User specUser = new User(“bruce zhang”, “password”);

可是此时倘诺利用上面的章程创立User的实例,就会面世错误:
User user = new User();
因为那时候User类的暗许构造器(即无参的构造器)已经不存在,如要帮助地点的实例化形式,就必要在User类的定义中添加无参构造器。

是还是不是须要为一个类定义有参的构造器,应依据现实的急需而定。以User类而言,由于此类的Name和Password属性是一个目的必备的,那么建立那样一个构造器是有须要的。因为假若不具有那样的构造器,那么如前协会的specUser就必要用下边三行代码来完成:
User specUser = new User();
specUser.Name = “bruce zhang”;
specUser.Password = “password”;

留意,在一个类的概念中,大家可以利用this关键字来表示其类对象自笔者,通过this,可以访问到那么些类的拥有常量、字段、属性和方法,不管它们是public仍旧private,恐怕其余访问级别。固然那几个this指代的是类对象自我,相当于说它意味着的就是实例化所发生的目的,但this的意思也可是限于对象的中间,从目标封装的思索来看,它是被卷入了的,在目的外部是无法看出的。

比如说上边的概念:
public class Visitor
{
 public void Visit(Element e)
 {
  Console.WriteLine(“I was visited.”);
 }
}
public class Element
{
 public void Accept(Visitor v)
 {
  v.Visit(this);
 }
}

在Element类中,Accept方法则传出一个Visitor类型的参数值,在该方法中,调用参数v的法门Visit,而Visit方法传入的是Element类型的值,由于Accept方法本人就属于Element类,因而,大家可以把其本身传递到Visit方法中,相当于代码中的this。

浅析如下的代码段:
Visitor v = new Visitor();
Element e = new Element();
e.Accept(v);

Element的实例e,执行了Accept()方法,该形式传入的参数是Visitor类的实例v。那么执行Accept方法,实质就是在其艺术内部推行v.Visit()方法,并经过this关键字将对象e本人传入,所以最终的结果是,打印如下的字符串:
I was visited。

那那里顺便提一下命名的渴求。所谓命名规范,在作为集体开发的时候,是不行首要的。以本文为例,如何定义类名、字段名、属性名和方法名,都以有讲究的。经常来说,类名、属性名和办法名都须要具有单词的首字母大写。要是是字段,那么除非是公私字段,一般而言,应将率先个单词的首字母小写。可是这也是变量命名的渴求。由于在一个类中,或然会临时用到部分变量,而不是字段,为了不同一般变量和字段,C++的程序员喜欢在变量名前加上“_”符号,许多C#程序员也沿用了那一个习惯。然则小编更欣赏为那几个字段名前增进“m_”。命名一定要联合,特别是在一个集体中,但是类似于这个暂时变量,大概非公有变量,对名字的限定要少一些,终究这几个变量不会被类的调用者使用。其它,对于常量而言,最好定义为任何大写的名字,如前方的概念的常量PI。

C#特意有一套完整的命名规范,有趣味的可以友善去查看一下特别的素材。别的,区其余店堂或然还有一对一定的命名规范,在此处就不再赘言了。

相关文章