C#编程基础练习题与答案2.pdf
《C#编程基础练习题与答案2.pdf》由会员分享,可在线阅读,更多相关《C#编程基础练习题与答案2.pdf(63页珍藏版)》请在淘文阁 - 分享文档赚钱的网站上搜索。
1、1.面向对象的思想主要包括什么?答:个人认为一各程序语言要成为真正的面向对象的程序设计语言,它必须符合下列条件:1 抽象(a b s t r a c t io n)抽象能够有效地管理一个问题的复杂性,其作法是划分出与该问题相关的一组对象.2 封装(E n c a p s u l a t io n)一封装是指将一个抽象的内部实现隐藏在特定的对象之内.3 多态(p o l ym o r p his m)一多态会提供相同方法的多种操作方法的多种操作实作.例如,不同的对象都会拥有一个S a v e方法,但是每一个S a v e方法会执行不同的操作.4 继承(in her it a n c e)Vis
2、u a l C#2005最令人兴奋之处就是其继承特性.v c#2005则提供了真正的方法继承,因此您可以重复使用个类的实例.2.什么是A S P.n et 中的用户控件自己动手作自己的控件来取代.N E T提供的控件。这种控件就是用户控件。后缀为.ascx3.什么叫应用程序域?什么是受管制的代码?什么是强类型系统?什么是装箱和拆箱?什么是重载?什么是多态?C TS、C L S 和 C L R 分别作何解释?应用程序域:应用程序域(通常是A p p D o m a in)是用于隔离应用程序的虚拟进程。在同一个应用程序作用域中创建的所有对象(换句话说,从该应用程序的入口点开始沿着对象激活序列的任何
3、地方)都在同一个应用程序域中创建。多个应用程序域可以存在于一个操作系统进程中,使它们成为隔离应用程序的简便方式。操作系统进程通过使用各不相同的内存地址空间来提供隔离。尽管它是有效的,但也是代价昂贵的,并且不能达到大型W e b服务器所需要的数量。与其相比,公共语言运行时通过管理在应用程序域中运行的代码的内存使用来强制进行应用程序隔离。这样就确保它不会访问应用程序域以外的内存。需要注意的是,只有类型安全的代码才能以这种方式管理(当在应用程序域中加载不安全代码时,运行时不能保 证 隔 离。理解应用程序域:应用程序域是.N E T 运行库的逻辑进程表示,操作系统进程可以包含多个应用程序域。应用程序域
4、具有下列优点:1、隐藏了进程具体的操作系统信息。从而允许把.N E T 放在不同的操作系统下。2、提供了隔离。即使运行在同一个进程中的属于不同域的应用程序也不能直接共享全局数据、静态数据或其他资源。所以,一个应用程序域失败了,也不会影响到同一个进程中的其他应用程序域。3、对于不需要昂贵的I P C 机制的进程,应用程序域允许.N E T 运行库优化运行在这种进程中的应用程序间的通信。因为应用程序域是被隔离的,所有.N E T 对象都会被界定在创建它的应用程序域内。如果跨应用程序域的边界传递对象引用,该被引用对象就被称为远程对象。装箱和拆箱在C#中的有两种类型的变量:值类型和引用类型。当值类型和
5、引用类型相互转化时,会发生装箱和拆箱的过程。这里有一点耍声明:经过拆箱或装箱的对象会多出它自己一份拷贝。它和它的拷贝不在一个存储区域。这也是值类型和引用类型的区别所在。值类型总是在栈中,而引用类型总是在托管堆中。(目前J 2 S E 5.0 也支持了装箱和拆箱,但是我目前不知道是否和C#一样)。为了进一步理解看下面例子:s t r uc t P oi n t p ub l i c i n t x;p ub l i c i n t y;)s t a t i c voi d M a i n O P oi n t p;p.x=1 0;p.y=2 0;O b j e c t o=p;/b ox.将值类
6、型从栈中拷贝到堆中。*从托管堆中将对象拷贝到栈中。P oi n t p 2=(P oi n t)p;C on s ol e.W r i t e L i n e (4 tp 2.x:=+p 2.x+“p 2.y:=+p 2.x);p.x=1 6;p.y=3 4;C on s ol e.W r i t e L i n e (up 2.x:=,+p 2.x+“p 2.y:=+p 2.x);C on s ol e.W r i t e L i n e (up.x:=+p.x+“p.y:=4+p.x);输出结果为:p 2.x:=1 0;p 2.y=2 0;p 2.x:=1 0;p 2.y=2 0;p.x:
7、=1 6;p.y=3 4;可知,变量经过拆箱/装箱后,得到是自己的另一份拷贝。装箱和取消装箱的概念是 C#的类型系统的核心。它在“值类型”和“引用类型”之间的架起了一座桥梁,使得任何“值类型”的值都可以转换为 ob j ect 类型的值,反过来转换也可以。装箱和取消装箱使我们能够统一地来考察类型系统,其中任何类型的值最终都可以按对象处理多态形象理解两条理解的原则:(1)一个派生类对象可以被声明成一个基类,或者是一个基类指针可以指向一个派生类对象:/c+codeB as eC l as s *p;D er i v edC l as s ob j;P=&ob j;C#codeB as eC l a
8、s s ob j =n ew D er i v edC l as s();(2)把一个对象看做是一个独立的个体,调用对象的p u b l i c成员函数实际上是给这个对象发送一个消息,采取什么样的动作完全由对象自己决定。Sh ap e是基类,C i r cl e和L i n e是从Sh ap e继承出来的,Sh ap e有dr aw。方法,C i r cl e与L i n e分别自己定义了自己的dr aw。方法,在下面的代码里:/J av a C odes t at i c v oi d fu n c(Sh ap e s)(s.D r aw ();如果发生了这样的调用:L i n e 1 =n
9、 ew L i n e();C i r cl e c=n ew C i r cl eO ;fu n c ;fu n c(c);一个C i r cl e和一个L i n e被当做Sh ap e传到函数里去了,然后调用D r aw。,会发生什么情况?因为对象是独立的个体,在fu n c()里,这两个对象被分别传递了D r aw。消息,叫它们绘制自己吧,于是他们分别调用了自己类里定义的D r aw。动作。通过这两条原则我们可以理解上面的多态。正是由于多态,使得我们不必要这样去做:I F 你是一个C i r cl e TH E N 调用C i r cl e的D r aw。E L SE I F 你是一个
10、L i n e TH E N 调用L i n e的D r aw。E L SE 我们只要给这个被声明成为Sh ap e的对象发送D r aw 消息,怎么样去D r aw 就由对象自己去决定了。二.一 切皆因虚函数先看看实现多态的基本条件:(1)基类含有虚函数(2)继承类把这个虚函数重新实现了(3)继承类也可能没有重新实现基类的所有虚函数,因此对于这些没有被重新实现的虚函数不能发生多态。再看一下几种语言里一些特别的规定:1.C+:(1)虚函数用v i r t u al 关键字声明。(2)v i r t u al v oi d F u n c(p ar ai s t)=0;这样的虚函数叫做纯虚函数,
11、表示这个函数没有具体实现。包含纯虚函数的类叫做抽象类,如果他的继承类没有对这个纯虚函数具体用代码实现,则这个继承类也是抽象类。抽象类不能被实例话(就是说不能创建出对象)。(3)继承类重新实现基类的虚函数时,不需要做任何特别的声明。(4)如果不用v i r t u al 关键字修饰,并且在派生类里重新实现了这个方法,这仅仅是一个简单的覆盖,不会发生多态,我们暂称它非多态吧。2.J av a:(1)J av a没有v i r t u al 关键字,J av a把一切类的方法都认为是虚函数。(2)继承类重新实现基类的虚函数时,不需要做任何特别的声明。因此在Ja v a 里只要重新实现了基类的方法,并
12、且把继承类对象声明为基类,多态就要发生。因此Ja v a 对多态的条件相对是比较低的。/Ja v a Codec l a s s Ba s e Cl a s s(pu b l i c v oi d h e l l o();c l a s s De r i v e dCl a s s e x t e n ds Ba s e Cl a s s(pu b l i c v oi d h e l l o()(Sy s t e m,ou t.pr i n t l n(*He l l o w or l d!);pu b l i c s t a t i c v oi d m a i n(St r i n g
13、a r g s)(Ba s e Cl a s s ob j =n e w De r i v e dCl a s s();ob j.h e l l oO;)输入是He l l o w or l d!。这样就实现了多态。(3)虚函数用a b s t r a c t 声明,含有虚函数的类是抽象类,也要用a b s t r a c t 关键字修饰。/Ja v a Codepu b l i c a b s t r a c t Ab s t r a c t c l a s spu b l i c a b s t r a c t v oi d h e l l o();/-3.C#:C#对于多态的编写是最为严
14、格和严谨的。(1)虚函数用v i r t u a l 声明。(2)纯虚函数用a b s t r a c t 声明,含纯虚函数的类是抽象类,必须用a b s t r a c t 关键字修饰。(3)如果仅仅是覆盖基类的非虚方法,则需要用n e w 关键字声明:/C#Codepu b l i c c l a s s Ba s e Cl a s s(pu b l i c v oi d h e l l o()(Sy s t e m.Con s ol e.Wr i t e Li n e (He l l o,t h i s c om e f r om Ba s e Cl a s s);)pu b l i c
15、 c l a s s De r i v e dCl a s s :Ba s e Cl a s s(pu b l i c n e w v oi d h e l l o()(Sy s t e m.Con s ol e.Wr i t e Li n e(*He l l o,t h i s i s c om e f r om De r i v e dCl a s s);)pu b l i c s t a t i c v oi d Ma i n()(Ba s e Cl a s s ob j =n e w De r i v e dCl a s s();ob j.h e l l oO;)输出为He l l o
16、,t h i s c om e f r om Ba s e Cl a s s,也就是说这并没有实现多态(非多态)。(4)通过v i r t u a l -ov e r r i de、a b s t r a c t -ov e r r i de 组合实现多态。当派生类重新实现基类的虚函数(或纯虚函数)时,必须用ov e r r i de 关键字进行修饰。/C#Codepu b l i c a b s t r a c t c l a s s Ab s Ba s e Cl a s s(pu b l i c a b s t r a c t v oi d h e l l oO;)pu b l i c c
17、 l a s s De r i v e dCl a s s :Ab s Ba s e Cl a s spu b l i c v oi d h e l l oOSy s t e m.Con s ol e.Wr i t e Li n e(He l l o w or l d!);pu b l i c s t a t i c v oi d Sa y He l l o(Ab s Ba s e Cl a s s ob j)(ob j.h e l i oO;)pu b l i c s t a t i c v oi d Ma i n()(De r i v e dCl a s s _ob j =n e w De
18、 r i v e dCl a s s();De r i v e dCl a s s.Sa y He l l o(_ob j);)输出为He l l o w or l d!三.多态的反溯继承类对象在发生多态时,并是不完全抛开基类不管的,它会去查看基类的虚函数列表,在这个列表的范围内才会发生多态。让我们来看一个比较复杂的例子:/Ja v a Codec l a s s Apr ot e c t e d v oi d h e l l o(Ob j e c t o)(Sy s t e m,ou t.pr i n t i n (,ZA-Ob j e c t);)c l a s s B e x t e n
19、 ds A(pr ot e c t e d v oi d h e l l o(St r i n g s)(Sy s t e m,ou t.pr i n t i n (Z/B-St r i n g);pr ot e c t e d v oi d h e l l o(Ob j e c t o)Sy s t e m,ou t.pr i n t i n(B-Ob j e c t););c l a s s Cpu b l i c s t a t i c v oi d m a i n(St r i n g a r g s)Ob j e c t ob j =n e w Ob j e c t ();St r
20、i n g s t r =ABC;A a =n e w B();a.h e l l o(ob j);a.h e l l o(s t r);;输出结果为:B-Ob j e c tB-Ob j e c t正如上面所说的,由于基类里没有参数类型为St r i n g的虚函数,因此B的h e l l o(St r i n g)方法不参与多态。调用a.h e l l o(s t r)时,由于St r i n g是Ob j e c t的继承类,因此这个s t r被作为一个Ob j e c t传入了B的h e l l o(Ob j e c t),这一点正如我们的原则一所述。四.接口仅仅是更抽象的抽象类接口是
21、类的协定,但由于接口又参与多态性,从这一点说,我们认为它是更为抽象的抽象类:CTS、CLS和CLR.NET结合Ja v a和COM解决方案两者优点来解决互操作性问题。类似于COM定义的标准二进制格式,.NET定义了一个称为通用类型系统Com m on Ty pe Sy s t e m(CTS)的类型标准。这个类型系统不但实现了COM的变量兼容类型,而且还定义了通过用户自定义类型的方式来进行类型扩展。任何以.NET平台作为目标的语言必须建立它的数据类型与C T S的类型间的映射。所有.N E T语言共享这一类型系统,实现它们之间无缝的互操作。该方案还提供了语言之间的继承性。例如,用户能够在V B
22、.N E T中派生一个由C#编写的类。很显然,编程语言的区别不仅仅在于类型。例如,一些语言支持多继承性,一些语言支持无符号数据类型,一些语言支持运算符重载。用户应认识到这一点,因此.N E T通过定义公共语言规范(C L S:C ommon L a ngu a ge S pe cifica t ion),限制了由这些不同引发的互操作性问题。C L S制定了-种以.N E T平台为目标的语言所必须支持的最小特征,以及该语言与其他.N E T语言之间实现互操作性所需要的完备特征。认识到这点很重要,这里讨论的特征问题已不仅仅是语言间的简单语法区别。例如,C L S并不去关心一种语言用什么关键字实现继
23、承,只是关心该语言如何支持继承。C L S 是C T S 的一个子集。这就意味着一种语言特征可能符合C T S 标准,但又超出C L S 的范畴。例如:C#支持无符号数字类型,该特征能通过C T S 的测试,但C L S 却仅仅识别符号数字类型。因此,如果用户在一个组件中使用C#的无符号类型,就可能不能与不使用无符号类型的语言(如V B.N E T)设计的.N E T 组件实现互操作。这里用的是“可能不”,而不是“不可能”,因为这一问题实际依赖于对non-C L S-complia nt 项的可见性。事实上,C L S 规则只适用于或部分适用于那些与其他组件存在联系的组件中的类型。实际上,用户
24、能够安全实现含私有组件的项目,而该组件使用了用户所选择使用的.N E T 语言的全部功能,且无需遵守C L S 的规范。另 方面,如果用户需要.N E T 语言的互操作性,那么用户的组件中的公共项必须完全符合C L S 规范。让我们来看下面的C#代码:pu b lic cla ss F oo(/T he u int(u nsigne d int e ge r)t y pe is non-C L S complia nt./B u t since t his it e m is priv a t e,t he C L S ru le s do not a pply,priv a t e u in
25、t A =4;/S ince shis u int me mb e r is pu b lic,w e ha v e a C L S/complia nce issu e.pu b lic u int B =5;/T he long t y pe is C L S complia nt.pu b lic long G e t A ()(re t u rn A;)最后一个C 是公共语言运行库C ommon L a ngu a ge R u nt ime (C L R)(,简单地说,C L R 是C T S 的实现,也就是说,C L R 是应用程序的执行引擎和功能齐全的类库,该类库严格按照C T
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- C# 编程 基础 练习题 答案
限制150内