.NET程序员面试秘笈(txt+pdf+epub+mobi电子书下载)


发布时间:2020-09-06 11:02:19

点击下载

作者:张云翯(编著)

出版社:信息技术第一出版分社

格式: AZW3, DOCX, EPUB, MOBI, PDF, TXT

.NET程序员面试秘笈

.NET程序员面试秘笈试读:

前言

本书的思路

从目前软件开发的就业形势来看,.NET程序员的就业率相当不错,因为使用.NET开发项目的公司特别多,微软公司对.NET的支持也比较完善。下面的图给出了从2008年到2013年人们对ASP.NET招聘职位的关注度,从最初的30多万提高到了目前的100多万。本书的目的就是让更多学习.NET的开发者能轻松就业。本书的特色

本书的考题实例都具有较强的实践性,读者可以根据考题的具体情况,轻松完成实例的制作。本书的特点主要体现在以下几个方面。

本书的编排采用循序渐进的方式,适合初级、中级.NET 学习人员逐步掌握.NET Framework的基本原理。

本书精选大量典型的面试考题,在解题的过程中,不但分析题目所考查的知识点,还提供了解题思路及相关知识点的详细讲述。

本书在介绍.NET 技术时,采用了较简洁的例子,大多数考题的实例,读者可以快速完成编写并立即见到成效。

本书在介绍ASP.NET 技术时,以ASP.NET 的编译过程、无状态特性为起点,避免了.NET基础知识的重复学习,使读者能够快速掌握ASP.NET的程序编写。

本书有大量实际项目的开发方法提示,使读者可以轻松将知识应用到实际项目中。

本书的所有实例源代码都附在随书光盘中,方便读者使用。本书的内容安排

本书内容突出了在.NET面试中或者是.NET项目开发中,必须掌握的技能和容易忽略的内容,对.NET面试者来说,可以快速掌握面试过程中考察的知识点,减少面试准备时间,提高面试成功率。本书共分为11章180余道面试题。第1章 .NET 概念题

本章内容包含面向对象程序设计和.NET的基础概念题,由于这部分题目涉及的范围比较广,因此在很多公司的面试题中占了比较大的比重。第2章 .NET 编程语言基础题

本章内容包含C#语言各方面的题目,涉及部分容易忽略的C#基本语法,如值类型和引用类型、装箱和拆箱操作、枚举和结构等,还有.NET平台的内存管理和异常处理机制。第3章 基类、接口和泛型

本章包含基类应用(如System.DataTime、System.IO)、接口和集合、泛型方面的知识,相对前两章的内容,本章侧重实际应用,会用一些小示例来配合讲解每个面试题的解析。第4章 .NET 高级特性

本章的内容包含了.NET框架中的高级特性,主要有委托、事件、反射、线程、序列化、LINQ、匿名方法等。第5章 Windows 窗体编程

本章内容以窗体程序中控件及 GDI+相关的编程知识为主,.NET 提供了大量的控件以提升程序开发效率,读者可以通过这些面试题来重新认识控件。第6章 ADO.NET 编程

本章包括ADO.NET在数据库方面的应用题目,涉及ADO.NET连接式访问数据库和断开式访问数据库的知识,其中会涉及SQL Server 数据库。第7章 SQL查询及LINQ

本章讲述数据库的一些基本概念题,以及各种SQL查询语句相关的基础题目。本章还涉及.NET Framework 中的LINQ 技术,其相关的题目应用了LINQ 中比较基础同时也比较典型的几个知识点,其中包括LINQ to SQL 技术以及LINQ to XML 技术。第8章 ASP.NET 程序开发1

本章讲述 ASP.NET 程序开发的相关题目。ASP.NET 是.NET 重要的组成部分,所以ASP.NET的题目在面试题目中占的比例较大。本章包括一些Code-Behind技术、@Page指令等常见的ASP.NET题目。第9章 ASP.NET 程序开发2

本章的内容仍然和ASP.NET程序相关,主要分为Web.config配置文件相关题、ASP.NET数据相关题和建站技巧。本章的题目更贴近实际项目开发的知识需要和实践经验的考查,这要求面试者善于对开发经验的积累和归纳。第10章 Web Service 和远程处理

.NET 技术可以应用多种远程应用技术,其中,Web Service逐渐被企业应用大量采用。本章先以简单的实例说明Web Service 的基本概念,这些概念在面试中或多或少都有涉及,理解了基本概念后编写实际项目的难度并不大。第11章 算法和趣味题

本章讲述编程中的算法题目。算法是程序设计的核心,在笔试中出现的机会很多,面试者应做好充分的准备。对于同样一个问题可以用多种方法完成,面试应该选择最有效率的方法,这就是考官所要考查的内容,所以这种题目也充满了趣味性。本书读者群

希望进入程序开发行业的新手。

希望快速转向.NET 平台进行程序开发的开发人员。

希望从事.NET 开发岗位的开发人员。

希望进一步提高.NET 开发水平的中级开发人员。

对.NET 平台技术感兴趣的爱好者。

ASP.NET 和C#入门人员。编者第1章.NET概念题

本章内容包含面向对象程序设计和.NET的基础概念题,由于这部分题目涉及的范围比较广,因此在很多公司的面试题中占了比较大的比重。很多.NET程序员在编写代码时非常熟练,但往往缺乏对基础知识的深刻理解,从而导致面试失败。这类知识是程序设计的基础,如果不加以重视,程序编写就没有创造性,只能学一步,做一步。

面向对象编程是当前流行的编程方式,被大多数高级语言支持。.NET程序同样是基于面向对象的设计,只有深刻理解面向对象的编程理念,才可以开发出结构良好的、更易维护的.NET程序。

说明:本书采用C#语言编写.NET程序示例。面试题1 简述面向对象的程序设计思想【考点】面向对象程序设计思想概念的理解,面向对象设计的应用范围,用C#实现面向对象设计方法。【出现频率】★★★★☆【解答】

面向对象是程序开发的一种机制,其特征为封装、继承、多态及抽象。以面向对象的方式编写程序时,需要将复杂的项目抽象为多个对象互相协作的模型;然后编写类型的结构,声明或实现类型的成员,即描述对象的特征和行为。在项目中编写不同的类型完成不同的功能,最后在程序中通过类的实例处理实际的问题。

说明:此处类型不仅仅指类,还可能包括接口、结构等。【分析】

面向对象编程简称为OOP,其“对象”的含义类似于生活中的“物体”。相对于以前的编程方式,面向对象编程更注重于人的思维方式,可极大地提高程序的开发效率。面向对象编程将程序看作多个互相分离的功能模块,各个模块之间分工合作,并且有着极低的耦合度。面向对象编程中最重要的概念是类(即class),类是描述各个功能模块的模板,而程序中工作的模块实体被称为对象(即object)。

类和对象的概念好比动物学的分类,猫科动物就是一个类,老虎也是一个类,并且属于猫科动物类,动物园中某只老虎的实体则是一个对象。老虎类拥有猫科动物类的所有特征和行为,但有自己独特的特征和行为。而某只老虎符合老虎类特征描述和行为定义,可能还有部分独特的特征。所以类可以继承另一个类,如老虎类继承了猫科动物类。类是产生对象的一个模板,对象拥有类的一切特征和行为。关于类和对象的基本关系如图1.1所示。图1.1 类和对象示意图

面向对象编程的重点是类的设计,面试者应能熟练地编写简单的类并创建对象,展示基本的OOP语法。以图1.1为例,编写图中相应的类,并通过虎类创建一只体重为100kg、长度为 200cm 的老虎对象。新建一个.cs 文件,并命名为 OopTest.cs,编写代码如程序1.1所示。程序1.1 老虎对象的创建:OopTest.cs

01 using System;

02  class OopTest

03  {

04  static void Main(String[] args)

05  {

06   Console.WriteLine("请输入老虎对象的体重和长度(逗号分隔的整数):");

07   string input= Console.ReadLine();

08   int pos = input.IndexOf(",");

09   string w = input.Substring(0, pos);

10   string l = input.Substring(pos + 1);

11   Tiger chinatiger = new Tiger(w, l);

12   Console.WriteLine("老虎已经创建完成!");

13   Console.WriteLine("这只老虎的重量是:"+chinatiger.weight+"kg");

14   Console.WriteLine("这只老虎的长度是:" + chinatiger.length + "cm");

15   Console.WriteLine("老虎的特征是:" + Tiger.msg);

16   Console.WriteLine("老虎一般生存在:" + Tiger.habitat );

17   Console.WriteLine("老虎像猫吗?" + Tiger.cat());

18  }

19  }

20  class Mammal         //哺乳动物类名称

21  {

22  protected static bool viviparous = true; //有胎生的特征

23  protected static bool Feeding = true;  //有喂养的特征

24  }

25  class Felid : Mammal       //猫科动物类名称(继承于哺乳动物类)

26  {

27  protected static bool catlike = true;  //类似猫的特征

28  protected static bool sensitivity = true; //有敏感的特征

29  }

30  class Tiger : Felid       //虎类名称(继承于猫科动物类)

31  {

32   //有各种特征

33  internal static string msg = "凶猛、会游泳、会爬树,有漂亮的花纹,被称为“兽中之王”。";

34  internal static string habitat = "森林"; //栖息地在森林

35  internal string weight;      //体重

36  internal string length;      //长度

37  internal Tiger(string w, string l)   //构造函数,直接给体重和长度赋值

38  {

39   this.weight = w;

40   this.length = l;

41  }

42  internal static bool cat()     //通过静态方法获取继承的属性

43  {

44   return Tiger.catlike;

45  }

46  }

在命令行下编译OopTest.cs后,执行OopTest程序,其效果如图1.2所示。图1.2 OopTest的执行结果

当用户首先输入了“50,100”,程序创建了一只老虎的对象,并访问了部分数据字段和方法。

说明:下文所有当前章的程序示例将在当前章编号的目录下创建并运行,最后进行归档,例如第1章每个示例文件归档到ch01目录下,而第2章每个示例文件归档到ch02目录下,依此类推。面试题2 用代码描述类和对象的区别【考点】理解类和对象的关系,在实际应用中类和对象的作用。【出现频率】★★★★★【解答】

类(即class)指一类事物,对象(即object)指属于这一类事物的实体。类定义了对象的相关数据和方法,类通过构造函数生成对象,对象实现了类的定义,且拥有具体的数据。在ch01目录下新建一个程序文件,并命名为ClassObj.cs,编写代码如程序1.2所示。程序1.2 类和对象:ClassObj.cs

01 using System;

02 class ClassObj

03  {

04  static void Main(String[] args)

05  {

06   Console.WriteLine("请输入动物对象的类别(pig,dog,cat):");

07   string animal= Console.ReadLine();   //读取用户输入到animal变量

08   Console.WriteLine("请输入动物对象的品种(如“波斯”):");

09   string tp = Console.ReadLine();    //读取用户输入到tp变量

10   Console.WriteLine("请输入动物对象的体重:");

11   string w = Console.ReadLine();    //读取用户输入到w变量

12   switch (animal.ToLowerInvariant())   //判断animal变量值

13   {

14    case "pig":

15     Pig pg = new Pig(tp, w);    //根据tp和w的值创建Pig类的对象

16     Console.Write("\n你创建了一只" + Pig.name + "!");

17     Console.WriteLine("它的品种是:" + pg.type + "!");

18     Console.WriteLine("这只" + Pig.name + "的重量是:" + pg.weight + "kg");

19     Console.WriteLine(Pig.name + "的特征是:" + Pig.msg );

20     break;

21    case "dog":

22     Dog dg = new Dog(tp, w);   根据tp和w的值创建//    Dog类的对象

23     Console.Write("\n你创建了一只" + Dog.name + "!");

24     Console.WriteLine("它的品种是:" + dg.type + "!");

25     Console.WriteLine("这只" + Dog.name + "的重量是:" + dg.weight + "kg");

26     Console.WriteLine(Dog.name + "的特征是:" + Dog.msg );

27     break;

28    default:

29     Cat ct = new Cat(tp, w);    //根据tp和w的值创建Cat类的对象

30     Console.Write("\n你创建了一只" + Cat.name + "!");

31     Console.WriteLine("它的品种是:" + ct.type + "!");

32     Console.WriteLine("这只" + Cat.name + "的重量是:" + ct.weight + "kg");

33     Console.WriteLine(Cat.name + "的特征是:" + Cat.msg );

34     break;

35   }

36

37  }

38  }

39  class Pig    //猪类名称

40  {

41  internal static string name = "小猪";

42  internal static string msg = 肥胖、迟钝";"    //有各种特征

43  internal string type;      //品种

44  internal string weight;      //体重

45  internal Pig(string tp, string w)   //构造函数, 接给品种和体重赋值直

46  {

47   this.type = tp;

48   this.weight = w;

49  }

50  }

51  class Dog  //狗类名称

52  {

53  internal static string name = "小狗";

54  internal static string msg = "属于犬科动物,是人类的好朋友"; //有各种特征

55  internal string type;      //品种

56  internal string weight;      //体重

57  internal Dog(string tp, string w)   //构造函数,直接给品种和体重赋值

58  {

59   this.type = tp;

60   this.weight = w;

61  }

62  }

63  class Cat  //猫类名称

64  {

65  internal static string name = "小猫";

66  internal static string msg = "安静、敏感"; //有各种特征

67  internal string type;           //品种

68  internal string weight;      //体重

69  internal Cat(string tp, string w)   //构造函数,直接给品种和体重赋值

70  {

71   this.type = tp;

72   this.weight = w;

73  }

74  }

例子比较简单,但可以充分说明类和对象的关系,3个动物类的描述如图1.3所示。图1.3 类和对象程序的执行结果

图1.3为3个类的定义,在主程序中用户输入动物的类别、品种和体重数据后,即根据以上类为模板创建了一只小动物对象,并输出其数据。在命令行下编译ClassObj.cs后,执行ClassObj程序,其效果如图1.4所示。【分析】

简单来说,类是用于描述对象的特征、状态和行为的模板,是抽象的概念。例如虎类可以用于描述所有老虎个体的共同特征及行为,但是虎类不能指定某一只老虎的个体。而对象指拥有具体特征、状态和行为的实体,例如某只老虎就是虎类的一个对象,它遵从类所描述的一切特征和行为。图1.4 类和对象程序的执行结果面试题3 描述private、protected、internal和public修饰符的作用【考点】理解访问权限存在的意义,各种访问权限的作用,在代码中灵活应用访问权限。【出现频率】★★★☆☆【解答】

1.private修饰符

private 修饰符用于设置类或类成员的访问权限仅为所属类的内部,private 也被称为私有修饰符。某些时候需要访问私有类成员时,可通过get和set访问器读取或修改。本例通过对类的私有成员及私有类的访问,展示private修饰符的保护作用。在ch01目录下新建一个程序文件,并命名为ModPrivate.cs,编写代码如程序1.3所示。程序1.3 private修饰符示例:ModPrivate.cs

01 using System;

02

03  class ModPrivate

04  {

05  static void Main(String[] args)

06  {

07   Dog dg = new Dog("可卡");

08   Console.WriteLine("一只小狗创建成功!");

09   Console.WriteLine("这只"+dg.name + "的品种是:" + dg.type);

10   //由于参数类型为字符串的构造函数是私有的,这里不能直接创建实例对象

11   //Tiger tg = new Tiger("华南虎");

12   //由于Tiger类所嵌套的ZooTiger类是私有类,所以无法直接访问

13   //Tiger.ZooTiger tz = new Tiger.ZooTiger();

14   Tiger tg = new Tiger(true); //参数类型为布尔型的构造函数可创建Tiger类的对象

15   Console.WriteLine("\n一只老虎创建成功!");

16   Console.WriteLine("这只" + tg.name + "的品种是华南虎吗?" + tg.ischinatiger);

17

18  }

19  }

20  class Dog  //狗类名称

21  {

22  internal string name = "小狗";

23  private string _type;    //品种

24  internal Dog(string tp)   //构造函数,直接给品种赋值

25  {

26   this._type = tp;

27  }

28  internal string type    //type变量,get访问器获取私有成员_type的值

29  {

30   get { return this._type; }

31  }

32  }

33  class Tiger  //虎类名称

34  {

35  internal string name = "老虎";

36  private string _type;    //品种

37  private bool _ischinatiger;  //是否为华南虎

38  private Tiger(string tp)   //构造函数,直接给品种赋值

39  {

40   this._type = tp;

41  }

42  internal Tiger(bool chinatiger) //构造函数,直接给_ischinatiger赋布尔型值

43  {

44   this._ischinatiger = chinatiger;

45  }

46   internal string ischinatiger  //ischinatiger变量,get访问器获取返回值  

47  {

48   get

49   {

50    //由于同属于Tiger类的内部,所以可创建ZooTiger私有类的对象

51    ZooTiger zt = new ZooTiger();

52    //返回字符串,内容为私有成员_ischinatiger的值和ZooTiger的对象的name值

53    return this._ischinatiger + "(" + zt.name + ")";

54   }

55  }

56  private class ZooTiger

57  {

58        internal string name;

59   internal ZooTiger()

60   {

61    this.name = "动物园的老虎";

62   }

63  }

64  }

2.protected修饰符

protected 修饰符用于设置类或类成员的访问权限仅为所属类及子类的内部。本例通过对类的私有成员及私有类的访问,展示private修饰符的保护作用。在ch01目录下新建一个程序文件,并命名为ModProtected.cs,编写代码如程序1.4所示。程序1.4 protected 修饰符示例:ModProtected.cs

01 using System;

02

03  class ModProtected

04  {

05  static void Main(String[] args)

06  {

07   Console.WriteLine("请输入所需创建老虎对象的品种(如东北虎、华南虎、孟加拉虎等):");

08   string input = Console.ReadLine(); //读取用户输入,并存储于input变量

09   string nm, tp;

10   if (input != "华南虎")    //如果input变量存储的不是"华南虎"字符串

11   {

12    Tiger tg = new Tiger(input); //创建Tiger类的对象,并传递input变量的值

13    nm = tg.name;     //将tg对象的name属性赋值给nm变量

14    tp = tg.type;     //将tg对象的type属性赋值给tp变量

15

16   }

17   else

18   {

19    ChinaTiger tg = new ChinaTiger(); //创建ChinaTiger类的对象

20    //将tg对象的name属性(继承于父类中声明为protected的属性)赋值给nm变量

21    nm = tg.name;

22

23    //将tg对象的type属性(继承于父类中声明为protected的属性)赋值给tp变量

24    tp = tg.type;

25   }

26   Console.WriteLine("\n一只{0}创建成功!",nm);

27   Console.WriteLine("这只{0}的品种是:{1}" ,nm,tp);

28  }

29  }

30  class Tiger       //虎类名称

31  {

32  protected string _name = "老虎";

33  protected string _type;   //品种

34  internal Tiger()     //无参数构造函数

35  {

36  }

37  internal Tiger(string t)   //构造函数,直接给品种赋值

38  {

39   this._type = t;

40  }

41  internal string name    //name变量,get访问器获取返回值

42  {

43   get

44   {

45    return this._name;   //返回字符串,内容为私有成员_name的值

46   }

47  }

48  internal string type    //type变量,get和set访问器获取返回值或写入值

49  {

50   get

51   {

52    return this._type;   //返回字符串,内容为私有成员_type的值

53   }

54   set

55   {

56    this._type = value;   //为私有成员_type赋值

57   }

58  }

59  }

60  class ChinaTiger : Tiger    //华南虎类名称

61  {

62  internal ChinaTiger()    //构造函数,直接给品种赋值

63  {

64   this._type = "华南虎";   //直接赋值"华南虎"字符串给父类中继承的_type属性

65  }

66  }

3.internal修饰符

internal修饰符修饰的类或类成员的访问权限为同一程序集内部,C#默认的类访问修饰符即为internal。前面两个示例中,需要供类外部代码访问的成员都使用了internal修饰符,因为这些类都处于同一程序集中。

4.public修饰符

public修饰符则为公共访问权限,对代码的访问没有任何限制。大多数情况下须谨慎使用public修饰符,因为滥用将影响类的封装性,并且带来安全隐患。

以下为代码的运行结果:(1)在命令行下编译ModPrivate.cs后,执行ModPrivate程序,其效果如图1.5所示。

从本例代码中可知,ZooTiger类无法在类的外部直接访问,所有的私有成员只能在类的内部访问,本例采用了get访问器访问了小狗和老虎的品种,并创建了ZooTiger私有类的对象。有的读者可能会迷惑,如果同时使用get和set访问器private,修饰符意义何在?其实很多程序中确实有这样的做法,这样做向类的外部屏蔽了私有成员的实现方法,同时也隐藏了私有成员的实际名称,有利于封装性。例如本例g, et访问器中有两步操作,而外界无法获知。图1.5 private修饰符示例(2)在命令行下编译 ModProtected.cs 后,执行 ModProtected 程序,其效果如图1.6所示。图1.6 protected修饰符示例

本例接收用户的输入,当输入值为“华南虎”时,创建 ChinaTiger 类的对象,并通过构造函数赋值“华南虎”字符串给_type字段。_type字段声明中使用了protected修饰符,所以在Tiger类的子类(ChinaTiger类)中可被直接访问。

注意:即使派生类和基类在不同程序集中,派生类仍可访问基类的 protected修饰符成员。读者必须清楚的一点是,派生类继承了所有基类的成员,只是无法直接访问基类的private修饰符成员,但可访问protected修饰符成员。【分析】

面向对象编程的特征之一就是封装性,而类就是封装性的典型体现。在生活中,人们不需要知道电器的内部构造,但是能很容易地使用电器,这就是封装性。在项目中需要编写很多功能类,在程序运行时只需要使用类所提供的功能,大部分类内部的代码实现需要封装,拒绝外部访问。这样大大增加了类的内部代码安全性和稳定性,同时多个功能类之间也减少了互相干扰的可能。访问权限修饰符即可将类及类的成员划分多种安全级别,根据不同需要设置访问权限。

internal和public访问修饰符是需要谨慎选择的,多数情况下应该尽量使用internal访问修饰符。

还有一种访问修饰符,即protected internal 修饰符,可在子类中或同一程序集内被访问。如果要声明成员只能被同一程序集内的派生类(子类)访问,则应首先设置所属类为internal,成员设置为protected。面试题4 举例说明属性、get和set访问器的使用【考点】对属性(Property)的理解,C#中get和set访问器的编写方法,理解自动实现的属性。【出现频率】★★☆☆☆【解答】

本例通过属性操作类中声明的私有字段_username,请注意在Name属性的get和set访问器中的逻辑操作。本例还有一个自动实现的属性,可读取用户输入的数据。在ch01目录下新建一个程序文件,并命名为GetSet.cs,编写代码如程序1.5所示。程序1.5 属性示例:GetSet.cs

01 using System;

02

03 class GetSet

04  {

05  static void Main(String[] args)

06  {

07   Console.Write("请输入用户名:");

08   Detail dt = new Detail();   //创建Detail的对象

09   dt.Name = Console.ReadLine();

10   Console.WriteLine("Name属性写入完成!");

11   Console.WriteLine("\n您的用户名为{0}(读取Name属性)", dt.Name);

12   Console.Write("\n请输入密码:");

13   dt.Password = Console.ReadLine();

14   Console.WriteLine("Password属性写入完成!");

15   Console.WriteLine("\n您的密码为{0}(读取Password属性)", dt.Password);

16  }

17  }

18  class Detail

19  {

20  private string _username;

21  internal string Name

22  {

23   get

24   {

25    //从_username值的第6位开始截取并返回(字符串索引值从0开始)

26    return _username.Substring(5);

27   }

28   set

29   {

30     _username = "user-" + value; //在传入值前面加上"user-"

31   }

32  }

33  internal string Password   //Password属性内部为自动属性实现

34  {

35   get;

36   set;

37  }

38  }

在命令行下编译GetSet.cs后,执行GetSet程序,其效果如图1.7所示。图1.7 属性示例

本例中,首先创建Detail类的对象dt,将用户第1次输入数据赋值给dt对象的Name属性。在Name属性的set访问器中,用户输入的字符串前面拼接了“user-”字符串,然后赋值给_username 字段。当读取 Name 属性时, get 访问器将_username 字段的值执行Substring(5)方法,将“user-”字符串去掉后返回。从整个过程来看,用户无法知道属性中数据经过了什么处理及数据最终存储在何处。而用户输入第2次数据,其值被写入Password属性,自动属性实现可将值写入匿名后备字段,读取时亦可直接返回其值。

说明:本例仅展示了get和set访问器在属性中的使用,在索引器中使用方法是一样的。【分析】

在前面的例子中使用了get和set访问器,通过访问器可以很方便地访问私有成员。其对外部暴露的部分可以为属性或索引器,属性比较常用。类体中的属性(Property)在使用时和一般的类成员没有区别,只是在内部实现的方法通过get和set访问器完成,这样更灵活、更隐蔽、更安全。其编写格式如以下代码所示:

访问修饰符 数据类型 属性名称

{

get

{

[访问修饰符2] 相关数据操作;

}

[访问修饰符3] set

{

和value关键字有关的数据操作;

}

}

当直接读取属性名称时,将会使用 get 访问器,执行“相关数据操作”的内容,相当于执行一个返回值为“数据类型”的方法。当直接赋值给属性名称时,被赋予的新值将替换隐式参数value,执行相关的数据操作。从代码中可知,get或set可添加访问修饰符,不过必须在get和set同时存在的情况下,且不能同时添加。当没有set访问器时,代表该属性为只读。

最常用的数据操作是读取和写入类中的私有字段(被称为后备字段),如果 get 和 set访问器中不需要逻辑,仅仅通过属性完成赋值和写入值的功能,可以使用自动实现的属性。自动实现的属性可以提供比较简洁的格式,并且编译器将自动创建一个匿名后备字段(在类体中没有声明),其编写方法如以下代码所示:

访问修饰符 数据类型 属性名称{get;set}

访问修饰符 数据类型 属性名称{get;private set}

第1种自动实现的属性可直接读取和写入,使用者并不知道数据读取或写入了哪个字段(匿名后备字段)。第2种自动实现的属性为只读,无法写入。

注意:属性提供了比较灵活的数据访问方法,读者编写代码时注意显式声明的set访问修饰符必须比属性修饰符更严格。get 或 set 没有显式访问修饰符时,其默认访问限制和属性一致。面试题5 描述sealed修饰符的使用【考点】sealed修饰符的意义,密封类和抽象类的关系,sealed修饰符的用法。【出现频率】★★★☆☆【解答】

在ch01目录下新建一个程序文件,并命名为Sealed.cs,编写代码如程序1.6所示。程序1.6 sealed修饰符示例:Sealed.cs

01 using System;

02

03  class Sealed

04  {

05  static void Main(String[] args)

06  {

07   Console.WriteLine("请输入电脑CPU的名称:");

08   string c = Console.ReadLine();

09   Computer lenovo = new Computer(c); //创建电脑对象

10   Console.WriteLine("\n{0}所采用的CPU为{1}", lenovo.name, lenovo.cpu);

11   Phone nokia = new Phone();   //创建手机对象

12   nokia.display();      //调用重写后的密封方法display()

13  }

14  }

15  class Product

16  {

17  internal string name;

18  internal virtual void display()

19  {

20   Console.WriteLine("这是产品类的方法!");

21  }

22  }

23  sealed class Computer:Product    //声明电脑类,继承于Product类

24  {

25  internal string cpu ;

26  internal Computer(string c)

27  {

28   this.cpu = c;

29   this.name = "电脑";

30  }

31  }

32  /*

33  class NoteBook : Computer

34  {

35  }

36  *声明本类将导致错误,因为Computer类为密封类,无法被继承

37  */

38 class Phone : Product      //声明手机类,继承于Product类

39 {

40  internal sealed override void display()

41  {

42   Console.WriteLine("\n这是手机类的方法!");

43  }

44 }

45 class Phone3G : Phone      //声明手机类,继承于Product类

46 {

47  /*internal override void display()

48  {

49   Console.WriteLine("\n这是3G手机类的方法!");

50  }

51  *声明此方法将导致错误,由于 display方法在其父类Phone中为密封方法,所以无法再重写

52  */

53 }

在命令行下编译Sealed.cs后,执行Sealed程序,其效果如图1.8所示。图1.8 sealed修饰符示例

从本例代码中可知,密封类一般情况下的使用方法和其他类一样,只是无法被继承。代码中Product类的虚方法display方法被Phone类重写,而被重写的display方法前面也加了sealed修饰符。在这种情况下,密封的display方法无法被所属类的子类继续重写,如本例代码中的Phone3G类,无法重写display方法。

说明:密封类可用于单一功能的实现,并且防止被意外地继承,产生非预期的效果,这也是封装性的体现。【分析】

sealed修饰符用于修饰类、实例方法和属性。sealed用于修饰类时,该类无法被继承,所以该类也被称为密封类。而abstract类(抽象类)必须被继承才有意义,所以,sealed修饰符和abstract修饰符是互相排斥的,无法共存。密封方法会重写基类的方法,sealed用于修饰实例被重写的虚方法或虚属性时,表示该方法或属性无法再被重写。

注意:sealed修饰实例方法或属性时,必须和override一起使用。面试题6 请简述静态类和静态类成员【考点】静态类和静态类成员的理解,static在应用中的特殊性。【出现频率】★★☆☆☆【解答】

在ch01目录下新建一个程序文件,并命名为Static.cs,编写代码如程序1.7所示。程序1.7 静态类及静态类成员示例:Static.cs

01 using System;

02

03 class Static

04 {

05  static void Main()

06  {

07  Console.Write("请输入电脑的CPU和内存规格,用英文逗号分隔:");

08  string input = Console.ReadLine();   //获取用户输入值并赋值给input变量

09  int pos = input.IndexOf(",");    //获取input字符串中英文逗号的索引

10  //根据索引获取逗号前面部分的字符串并赋值给PC类的静态字段cpu

11  PC.cpu = input.Substring(0, pos);

12  //根据索引获取逗号后面部分的字符串并赋值给PC类的静态字段memory

13  PC.memory = input.Substring(pos + 1);

14  Console.Write("请输入电脑的单价和数量,用英文逗号分隔:");

15  string input2 = Console.ReadLine();

16  int pos2 = input2.IndexOf(",");

17  int p = Int32.Parse(input2.Substring(0, pos2));

18  int n = Int32.Parse(input2.Substring(pos2 + 1));

19  PC ibm = new PC(p, n);    //将p和n值转换为int类型后传递给构造函数

20  Console.WriteLine("\n(1)你选择电脑的CPU是{0},内存是{1},总价是{2}元", PC.cpu,PC.memory, ibm.count());

21  CpuMsg.getmsg();      //调用静态类的静态方法

22  }

23 }

24 class PC

25 {

26  internal static string cpu="";

27  internal static string memory="";

28  private static int price;

29  private static int num;

30  internal PC(int p, int n)     //构造函数接收2个参数并为2私有字段赋值

31  {

32  price = p;

33  num = n;

34  }

35  internal int count()      //用于计算总价格的方法,返回值为int类型

36  {

37  return price * num;

38  }

39 }

40 static class CpuMsg

41 {

42  private static string _name="CPU";

43  private static string _comp = "Intel";

44  internal static void getmsg()

45 {

46  Console.WriteLine("(2)静态类包含的CPU名称为:{0};生产厂家为:{1}",_name,_comp);

47 }

48 }

在命令行下编译Static.cs后,执行Static程序,其效果如图1.9所示。图1.9 静态类及静态类成员示例

本例的Main方法中,首先将用户第1次输入的值通过逗号分隔为2个字符串,再分别给PC类的赋值静态字段,即cpu和memory;然后将用户的第2次输入也分隔为2个字符串,并转换为整数类型赋值给p和n。通过传递参数p和n给PC的构造函数创建了PC类的对象ibm,并进行了初始化。在用户输入值后的第1行访问了PC类的2个静态字段,并通过实例方法计算了总价。在第2行直接调用了静态类CpuMsg的静态方法getmsg(),静态类CpuMsg完全不需要实例化,可以很方便地直接在程序中使用。在.NET的类库中有很多类似的静态类,可以在程序中直接使用其方法,例如Math类。【分析】

static是比较特殊的修饰符,它所修饰的类或类成员被称为静态类或静态类成员。

当类中某些成员不需要创建实例实现,则可将其声明为静态类成员。静态成员在访问类名而非对象名,同样,“this”关键字也无法访问静态成员时直接引用。这些成员可用作该类的多个对象共享的数据,因为静态类成员不依赖某个对象。声明静态类成员如以下代码所示:

访问修饰符 static 数据类型 类成员;

当类中没有和对象实例相关的成员时,即类体中只有静态成员,可声明该类为静态类。静态类无法用new 创建对象,所以并不能编写构造函数,并且该类是密封类(即无法被继承)。静态类的声明方法如以下代码所示:

访问修饰符 static class 类名称

{

静态类成员1;

静态类成员2;

静态类成员3;

...

}

必须注意的是,类中的常数声明和类型声明默认为静态,如类体中声明 1 个类,这个类默认为static,即无法被所属类的对象访问。

注意:声明静态类时,必须保证其内含成员全部为静态成员。面试题7 构造函数有什么作用【考点】各种形态构造函数的理解,派生类的构造函数,构造函数的重载。【出现频率】★★★★☆【解答】

构造函数用于创建类的实例,并对实例进行初始化操作,通过不同的参数传递,可进行不同的实例初始化操作。本例通过多种不同形式的构造函数创建实例,并输出初始化的结果。在 ch01 目录下新建一个程序文件,并命名为 Constructor.cs,编写代码如程序1.8所示。程序1.8 构造函数示例:Constructor.cs

01 using System;

02

03 class Constructor

04 {

05  static void Main()

06  {

07  Console.Write("请输入篮球比赛的选手人数:");

08  int inputA = Int32.Parse(Console.ReadLine()); //将用户输入值转换为int类型(这里没有作异常处理)

09  Console.Write("请输入篮球比赛的MVP:");

10  string inputB = Console.ReadLine();

11  Basketball bb = new Basketball();  //用Basketball类的默认构造函数创建实例bb

12  bb.getmsg();       //实例bb调用getmsg方法

13  Basketball bbb = new Basketball(inputA, inputB); //用Basketball类带2个参数的构造函数创建bbb

14  bbb.getmsg();      //实例bbb调用getmsg方法

15  Football fb = new Football();  //用Football类的默认构造函数创建实例fb

16  fb.getmsg();       //实例fb调用getmsg方法

17  Console.WriteLine("\n本次游泳比赛的冠军是{0}队", Swim.champ); //直接访问Swim类的静态字段

18  //Shoot sh = new Shoot();此处代码将会被编译器报错,因为其默认构造函数为私有的

19  }

20 }

21 class Basketball

22 {

23  private int _playernum;

24  private string _mvp;

25  internal Basketball()

26  {

27  }

28  internal Basketball(int n, string m)

29  {

30   _playernum = n;

31   _mvp = m;

32  }

33  internal void getmsg()

34  {

35  Console.WriteLine("\n这场篮球比赛的选手有{0}个,最有价值球员是{1}!", _playernum,_mvp);

36  }

37 }

38 class Football

39 {

40  private string _star = "Henry";

41  internal void getmsg()

42  {

43  Console.WriteLine("\n这场足球比赛的明星是{0}!", _star);

44  }

45 }

46 class Swim

47 {

48  internal static string champ;

49  static Swim()      //静态构造函数,用于初始化静态成员

50  {

51  champ = "中国";

52  }

53 }

54 class Shoot

55 {

56  internal static string champ=null;

57  private Shoot()      //私有构造函数,无法在类外部创建实例

58  {

59  }

60 }

在命令行下编译Constructor.cs后,执行Constructor程序,其效果如图1.10所示。图1.10 构造函数示例【分析】

前面的所有示例中都使用了构造函数,因为构造函数用于创建类的实例(对象)。在类中声明构造函数可对新实例(对象)进行初始化的操作,其编写方法如以下代码所示:

class 类名称

{

访问修饰符 类名称()

{

试读结束[说明:试读内容隐藏了图片]

下载完整电子书


相关推荐

最新文章


© 2020 txtepub下载