软件设计模式 试 卷(作业考核 线上) B 卷
学习中心: 院校学号: 姓名
(共 页)
总分 | 题号 | 一 | 二 | 三 | 四 | 五 | 六 | 七 | 八 | 九 | 十 |
| 得分 |
|
|
|
|
|
|
|
|
|
|
一:单选题(共40分,20小题,每小题2分。请将答案填入下表)
题号 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 |
答案 | A | A | B | B | A | D | D | C | B | D |
题号 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 |
答案 | A | A | D | D | D | A | B | C | D | D |
1. C#语言的核心是面向对象编程(OOP),所有OOP语言都应至少具有三个特性:
A. 封装、继承和多态 B. 类、对象和方法
C. 封装、继承和派生 D. 封装、继承和接口
2. C#中MyClass 为一自定义类,其中有以下方法定义public void Hello(){..}使用以下语句创建了该类的对象,并使变量obj 引用该对象:MyClass obj = new MyClass();那么,可如何访问类MyClass 的Hello 方法?
A. obj.Hello(); B. obj::Hello();
C. MyClass.Hello(); D. MyClass::Hello();
3. 在编写c#程序时,若需要对一个数组中的所有元素进行处理,则使用___循环体最好?
A. while循环 B. for each 循环
C. do循环 D. for 循环
4. 在c#程序中,入口函数的正确声明为:
A. static int main(){……} B. static void Main(){……}
C. static void main(){……} D. void Main(){……}
5. 在C#中,引用命名空间system 的正确语句是:
A. using System; B. #import<System>;
C. uses System; D. #include<System>;
6. MyClass为一个自定义的类,则下列语句创建了多少个类MyClass的对象?
MyClass[,] myArray = new MyClass[2][3];
A. 0 B. 2
C. 3 D. 6
7. 下面有关析构函数的说法中,不正确的是:
A. 析构函数中不可以包含return语句
B. 一个类中只能有一个析构函数
C. 析构函数在对象被撤销时,被自动调用
D. 用户可以定义有参析构函数
8. 下列说法哪个正确?
A. 不需要定义类,就能创建对象
B. 属性可以定义为抽象的
C. 对象中必须有属性和方法
D. 常量不能作为类成员
9. 下列说法哪个正确?
A. 允许一个子类有多个父类
B. 某个类是一个类的子类,它仍有可能成为另一个类的父类
C. 一个父类只能有一个子类
D. 继承关系最多不能超过4层
10. C#语言源代码文件的后缀名为:
A. .C# B. .CC C. .CSP D. .CS
11. C#中导入某一个命名空间的关键字是:
A. using B. use C. import D. include
12. 方法中的值参数是_________的参数。
A. 按值传递 B. 按引用传递
C. 按地址传递 D. 不传递任何值
13. 结构化程序设计的3种结构是:
A. 顺序结构、if结构、for结构
B. if结构、if…else结构、else if结构
C. while结构、do…while结构、foreach结构
D. 顺序结构、分支结构、循环结构
14. 下列描述错误的是:
A. 类不可以多重继承而接口可以
B. 抽象类自身可以定义成员而接口不可以
C. 抽象类和接口都不能被实例化
D. 一个类可以有多个基类和多个基接口
15. 下列关于构造函数的描述正确的是:
A. 构造函数可以声明返回类型。
B. 构造函数不可以用private修饰
C. 构造函数必须与类名相同
D. 构造函数不能带参数
16.C#中MyClass 为一自定义类,其中有以下方法定义public void Hello(){..}使用以下语句创建了该类的对象,并使变量obj 引用该对象:MyClass obj = new MyClass();那么,可如何访问类MyClass 的Hello 方法?
A.obj.Hello(); B.obj::Hello();
C.MyClass.Hello(); D.MyClass::Hello();
17.在类的定义中,类的_______描述了该类的对象的行为特征。
A.类名 B.方法 C.所属的名字空间 D.私有域
18.C#语言中,下列能够作为变量名的是:
A.if B.3ab C.a_3b D.a-bc
19.能正确表示逻辑关系“a>=10 或a<=0”的C#语言表达式是:
A.a>=10 or a<=0 B.a>=10|a<=0
C.a>=10&&a<=0 D.a>=10||a<=0
20.以下叙述正确的是:
A.do….while语句构成的循环不能用其他语句构成的循环来代替
B.do….while语句构成的循环只能用break语句退出
C.用do….while语句构成的循环,在while后的表达式为true时结束循环
D.用do….while语句构成的循环,在while后的表达式应为关系表达式或逻辑表达式
二:判断题(共20分,20小题,每小题1分。请将答案√或×填入下表)
题号 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 |
答案 | × | × | × | × | √ | × | √ | × | × | √ |
题号 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 |
答案 | √ | × | × | √ | √ | × | × | × | √ | × |
1.软件危机是二十一世纪软件领域出现的新问题。
2.结构化程序设计对基本模块的要求是单入口、多出口。
3.从提出软件开发计划的那一刻起开始直到软件投入实际应用为止可以认为是一个完整的软件生存周期。
4.喷泉模型主要用于面向过程的软件项目。
5.在面向对象方法中,由于对象中的数据以及对数据的操作是封装的,所以对某一类对象的修改一般只涉及该类,通常不会对整个系统造成很大影响。
6.书写需求陈述时,要做到语法正确,至于词汇选择则无关紧要。
7.利用多重继承虽然可以提高类的共享程度,但也会增加系统的复杂程度。
8.脚本(script)就是详细描述类的静态结构的信息。
9.面向对象程序设计应该遵循低内聚、高耦合的原则。
10.作为一种建模语言,UML的定义包括UML语义和UML表示法两个部分。
11.用例图、类图、对象图、状态图和顺序图属于静态建模机制。
12.顺序图和协作图虽然都是用来描述交互的,但顺序图强调的是空间,而协作图强调的是时间。
13.面向对象设计中的"开-闭"原则指的是软件对修改应该是开放的,对扩展应该是关闭的。
14.单一职责原则、里氏代换原则、依赖倒置原则等,都可以看成是“开放-封闭”原则的实现方法。
15.一般来说,继承必须确保超类所拥有的性质在子类中仍然成立。
16.当一个超类的实例能够替换任何其子类的实例时,它们之间才具有is-A关系。
17.工厂方法是抽象工厂模式的扩展。
18.结构型模式在破坏类的封装性的基础上,实现新的功能。
19.具有抽象方法的类必须声明为abstract。
20.类和对象的区别就是,类是对象的实例,而对象则是类的抽象。
三:简答题(共25分,5小题,每小题5分。)
1. 什么是设计模式?
答:设计模式(Design pattern)是一套被反复使用、多数人知晓的、经过分类编目的、代码设计经验的总结。使用设计模式是为了可重用代码、让代码更容易被他人理解、保证代码可靠性。 毫无疑问,设计模式于己于他人于系统都是多赢的,设计模式使代码编制真正工程化,设计模式是软件工程的基石脉络,如同大厦的结构一样。
2. 面向对象设计中需要遵循哪些原则?为什么要遵循这些原则?
答:面向对象设计中需要遵循的原则:
(1)"开-闭"原则:软件对扩展应该是开放的,对修改应该是关闭的。
(2)单一职责原则:就一个类而言,应该仅有一个引起它变化的原因。
(3)里氏代换原则:继承必须确保超类所拥有的性质在子类中仍然成立
(4)依赖倒置原则:如果一个类的一个成员或参数为一个具体类型,那么这个类就依赖于那个具体类型。
遵循以上原则,可以使我们的软件更具灵活性,强壮性。但灵活是需要付出代价的,由多态带来的性能损失就是最明显的一个问题。所以我们需要权衡,需要做出选择,在灵活与性能之间做出选择。
追本溯源,促使我们使用这些原则的原因是为了满足需求的变更,于是需求分析就显得格外重要。然而不管怎么充分的需求分析都可能遭遇需求变更,于是预测变化就成了一个让人头痛的事。还是让我们来看看敏捷设计(XP)是怎么解决这些问题的:“敏捷开发人员不会对一个庞大的预先设计应用那些原则和模式,相反,这些原则和模式被应用在一次次的迭代中,力图使代码以及代码所表达的设计保持干净。”也就是说敏捷设计通过快速的迭代来刺激变化,让这些变化及早暴露,再根据变化进行相应改动。很明显这要比一次性完整设计轻松容易的多.
3. 结构型模式的功能有哪些?
答:结构型模式能够解决如下几个方面的问题:
(1)在不破坏类的封装性的基础上,实现新的功能;
(2)在不破坏类的封装性的基础上,使得类可以同不曾估计到的系统进行交互;
(3)创建对一组类的统一的访问接口;
(4)对同一类,创建不同的访问界面,提供给不同的访问者。
4. 简述建造者模式。
将一个复杂对象的构造与它的表示分离,使同样的构建过程可以创建不同的表示,这样的设计模式被称为建造者模式。
1 当创建复杂对象的算法应该独立于该对象的组成部分以及它们的装配方式时。
2 当构造过程必须允许被构造的对象有不同表示时。
在这样的设计模式中,有以下几个角色:
1 builder:为创建一个产品对象的各个部件指定抽象接口。
2 ConcreteBuilder:实现Builder的接口以构造和装配该产品的各个部件,定义并明确它所创建的表示,并 提供一个检索产品的接口。
3 Director:构造一个使用Builder接口的对象。
4 Product:表示被构造的复杂对象。ConcreteBuilder创建该产品的内部表示并定义它的装配过程,包含定义组成部件的类,包括将这些部件装配成最终产品的接口。
5. 试简述重载与覆盖的区别。
答:覆盖”指的是重新定义基类的方法,使得该方法在派生类中有着不同的含义。“重载”指的是赋予方法名两个定义,解析出来有不同的参数列表。重载可以存在于任何类中, 不管定义类时是否明确指定了基类。
下面解释如何区分他们:“覆盖”方法定义时,派生类中给出的新方法定义拥有完全一样的参数数目及类型;另一方面,如果派生类的方法拥有不同的参数数目,或者如果某个参数类型不同于基类中的地,则派生类会拥有这两人方法。这时就是“重载”。重载时也可以不涉及到基类,只要在类定义中同时给出两个方法定义即可
四:综合题(共15分)
假设你现在是一家快餐店的的管理者,要给顾客提供一系列的食品,如鸡翅、鸡腿等,顾客每要求一种食品,快餐店应当很快“生产”出来。请采用工厂模式来实现这个过程,用C#语言编写相应的类代码。
//抽象的KFC食品,Product角色
public abstract class KFCFood
{
public abstract void show();
}
//下面两个类表示两种具体的KFC食品,它们继承了抽象的KFC食品Concrete Product1角色
public class Chicken: KFCFood
{
public override void show()
{
Console.WriteLine(“鸡腿+1”);
}
}
//Concrete Product2角色
public class Wings: KFCFood
{
public override void show()
{
Console.WriteLine(“鸡翅+1”);
}
}
//产品工厂,Factory角色
interface IKFCFactory
{
KFCFood CreatFood();
}
//鸡翅膀工厂,ConcreteFactory角色
public class WingsFactory: IKFCFactory
{
public KFCFood CreateFood()
{
return new Wings();
}
}
//鸡腿工厂,ConcreteFactory角色
public class ChickenFactory: IKFCFactory
{
public KFCFood CreateFood()
{
return new Chicken();
}
}
Static void Main(String[] args)
{
//定义一个鸡腿工厂
IKFCFactory factory=new ChickenFactory();
//生产鸡腿
KFCFood food1=factory.CreateFood();
food1.show();
//生产鸡腿
KFCFood food2=factory.CreateFood();
food2.show();
//生产鸡腿
KFCFood food3=factory.CreateFood();
food3.show();
Console.Read();