新書推薦:
《
创客精选项目设计与制作 第2版 刘笑笑 颜志勇 严国陶
》
售價:NT$
281.0
《
佛山华家班粤菜传承 华家班59位大厨 102道粤菜 图文并茂 菜式制作视频 粤菜故事技法 佛山传统文化 广东科技
》
售價:NT$
1010.0
《
武人琴音(十周年纪念版 逝去的武林系列收官之作 形意拳一门三代:尚云祥、韩伯言、韩瑜的人生故事 凸显百年武人命运)
》
售價:NT$
199.0
《
剑桥斯堪的纳维亚戏剧史(剑桥世界戏剧史译丛)
》
售價:NT$
704.0
《
禅心与箭术:过松弛而有力的生活(乔布斯精神导师、世界禅者——铃木大拙荐)
》
售價:NT$
301.0
《
先进电磁屏蔽材料——基础、性能与应用
》
售價:NT$
1010.0
《
可转债投资实战
》
售價:NT$
454.0
《
王氏之死(新版,史景迁成名作)
》
售價:NT$
250.0
|
編輯推薦: |
1. 在对实训式教学模式进行了探讨和实践的基础上,以实训为主线组织本书内容编写,将理论和实践成果更好地应用于教材建设中,对加强学生的应用实践能力和创新能力的培养提供有力支撑,为社会培养应用创新型人才做出贡献。2. 通过在网络课程建设中的应用,为本教材积累了相关的教学资源,使本教材更充实,本教材的编写也推动了网络课程更好地建设。3. 本书吸收了众多相关资源的精华,同时结合教学中的实践经验合理地进行内容的取舍,使整体内容既具备较新的技术知识,又满足教学的需要,易于为学生所理解。适合于普通本科院校、大专高职院校使用,据作者所知选用本教材*版的院校有沈阳师范大学、沈阳工业大学、广东科技学院、山东德州职业技术学院、山东商务职业学院。
|
內容簡介: |
本书系统地讲解了C#语言的基础语法和高级应用。每一章的内容从一个问题开始,按照提出问题分析问题明确目标学习知识解决问题总结提高的思路进行编写。每一部分的知识点都给出了应用案例,并对案例进行了剖析,有利于读者自我学习。综合案例采用三层架构开发的Web应用程序,对开发工具、技术和开发过程进行了全面讲解,读者学习后可以举一反三。本书内容包括: C#语法基础; 面向对象程序设计、泛型; Windows程序设计; 文件操作、数据库操作; 异常处理、网络编程和多线程; 综合开发案例全程讲解; 课后习题; 实训指导。 本书可作为高等院校C#程序设计相关课程的教材,也可供广大.NET开发人员学习和参考。
|
目錄:
|
目录
第1章概述
1.1Microsoft .NET技术
1.1.1Microsoft .NET概述
1.1.2Microsoft .NET框架
1.2C#语言简介
1.2.1C#的起源
1.2.2C#语言的特点
1.3Visual Studio 2012开发环境
1.3.1安装Visual Studio 2012
1.3.2熟悉Visual Studio 2012开发环境
1.4第一个C#程序
1.5程序的调试与规范
1.5.1断点设置与程序调试
1.5.2C#编写命名建议
小结
课后练习
第2章C#编程基础
2.0问题导入
2.1数据类型
2.1.1值类型和引用类型概述
2.1.2值类型
2.1.3引用类型
2.2常量与变量
2.2.1变量
2.2.2常量
2.2.3隐式类型的局部变量
2.3类型转换
2.3.1隐式转换
2.3.2显式转换
2.3.3使用Convert类转换
2.3.4装箱和拆箱
2.3.5数值和字符串之间的转换
2.4操作符和表达式
2.4.1算术操作符
2.4.2自增和自减操作符
2.4.3位操作符
2.4.4赋值操作符
2.4.5关系操作符
2.4.6逻辑操作符
2.4.7条件操作符
2.4.8运算符的优先级
2.5流程控制语句
2.5.1分支语句
2.5.2循环语句
2.5.3跳转语句
2.6数组和枚举
2.6.1数组的定义和使用
2.6.2Array类
2.6.3匿名数组
2.6.4枚举的定义和使用
2.7字符串
2.7.1字符串的创建与表示形式
2.7.2字符串比较
2.7.3字符串查找
2.7.4求子字符串
2.7.5字符串的插入、删除与替换
2.7.6移除首尾指定的字符
2.7.7字符串的合并与拆分
2.7.8字符串中字母的大小写转换
2.7.9String与StringBuilder的区别
2.8问题解决
小结
课后练习
第3章面向对象编程基础
3.0问题导入
3.1类的定义
3.1.1类的声明与成员组织
3.1.2字段和局部变量
3.1.3静态成员和实例成员
3.1.4访问修饰符
3.2构造函数和析构函数
3.2.1构造函数
3.2.2析构函数
3.3类的方法
3.3.1方法的声明
3.3.2方法中的参数传递
3.3.3方法重载
3.4属性与索引器
3.4.1属性
3.4.2索引器
3.5结构
3.5.1结构的定义及特点
3.5.2结构的使用
3.6操作符重载
3.7问题解决
小结
课后练习
第4章面向对象高级编程
4.0问题导入
4.1继承
4.1.1基类和派生类
4.1.2继承过程中的构造函数和析构函数
4.2多态
4.2.1成员的虚拟和重写
4.2.2成员隐藏
4.3抽象类
4.4密封类
4.5接口
4.5.1接口的声明与实现
4.5.2显式方式实现接口
4.6委托与事件
4.6.1委托
4.6.2事件
4.7泛型
4.7.1泛型的定义和使用
4.7.2可空类型的泛型
4.8泛型集合
4.8.1列表
4.8.2字典
4.9问题解决
小结
课后练习
第5章Windows程序设计
5.0问题导入
5.1Windows窗体
5.1.1Windows窗体简介
5.1.2创建简单的Windows Form
5.2窗体控件
5.2.1文本输入类控件
5.2.2选择类控件
5.2.3列表控件
5.2.4容器
5.2.5菜单、状态栏和工具栏
5.2.6对话框
5.2.7其他常用控件
5.3多文档界面
5.3.1设置MDI窗体
5.3.2排列子窗体
5.4GDI 编程
5.4.1创建Graphics对象
5.4.2创建Pen对象
5.4.3创建Brush对象
5.4.4绘制基本图形
5.5问题解决
小结
课后练习
第6章目录与文件管理
6.0问题导入
6.1目录管理
6.1.1DirectoryInfo类
6.1.2Directory类
6.1.3Path类
6.2文件管理
6.2.1FileInfo类
6.2.2File类
6.3驱动器管理
6.4文件的读写
6.4.1文件编码
6.4.2Stream类
6.4.3StreamReader和StreamWriter类
6.4.4BinaryReader和BinaryWriter类
6.5问题解决
小结
课后练习
第7章数据库与ADO.NET
7.0问题导入
7.1ADO.NET简介
7.2数据源连接
7.2.1操作数据库的简单示例
7.2.2通过向导的方式建立数据库连接
7.2.3通过编程的方式建立数据库连接
7.2.4连接字符串
7.2.5连接池的使用
7.3Command对象与DataReader对象
7.3.1Command对象与DataReader对象简介
7.3.2建立SqlCommand对象
7.3.3使用SqlCommand执行SQL语句
7.4DataAdapter对象与DataSet对象
7.4.1SqlDataAdapter对象
7.4.2DataTable对象
7.4.3DataSet对象
7.5存储过程
7.6综合实例
7.7问题解决
小结
课后练习
第8章LINQ语言集成查询
8.0问题导入
8.1LINQ概述
8.2LINQ预备知识
8.2.1对象和集合初始化器
8.2.2Lambda表达式
8.2.3扩展方法
8.3LINQ查询
8.3.1查询步骤
8.3.2查询方法定义查询
8.3.3查询表达式定义查询
8.4LINQ to SQL
8.4.1创建对象映射模型
8.4.2设定DataContext
8.4.3LINQ to SQL查询和操作
小结
课后练习
第9章异常处理
9.0问题导入
9.1错误和异常
9.2C#中的异常处理结构
9.2.1使用trycatch语句捕捉异常
9.2.2使用trycatchfinally语句捕捉异常
9.2.3使用throw语句抛出异常
9.3C#中异常的层次结构
9.3.1异常传播
9.3.2Exception类和常见异常类型
9.4使用异常的原则和技巧
9.5问题解决
小结
课后练习
第10章网络编程
10.0问题导入
10.1网络编程基础
10.2主机的定义及管理
10.2.1IPAddress类
10.2.2IPEndPoint类
10.2.3Dns类
10.3Socket网络通信
10.3.1Socket连接原理
10.3.2Socket数据处理模式
10.3.3Socket类
10.4TcpClient类和TcpListener类
10.4.1TcpClient类
10.4.2TcpListener类
10.4.3TcpListener类和TcpClient类应用
10.5UdpClient类
小结
课后练习
第11章进程和线程技术
11.0问题导入
11.1进程与线程
11.2进程
11.3线程概述
11.3.1线程的定义和分类
11.3.2多线程的使用
11.3.3线程的生命周期和状态
11.3.4线程对象和属性
11.4线程调度
11.4.1创建线程
11.4.2线程休眠
11.4.3终止线程
11.5线程优先级
11.6线程同步
11.6.1线程同步机制
11.6.2使用lock关键字实现线程同步
11.6.3使用Monitor驱动对象实现线程同步
11.6.4使用Mutex类实现线程同步
11.7问题解决
小结
课后练习
第12章综合实例图书馆管理系统
12.1开发背景
12.2需求分析
12.3系统设计
12.3.1系统目标
12.3.2业务流程图
12.3.3系统功能结构
12.3.4系统预览
12.3.5数据库设计
12.4系统架构的设计与实现
12.5数据访问层的设计与实现
12.5.1数据实体类的设计与实现
12.5.2数据访问类的设计与实现
12.5.3其他问题说明
12.6业务逻辑层的设计与实现
12.7呈现层的设计与实现
12.7.1母版页的设计
12.7.2系统首页的设计
12.7.3典型模块的设计
12.8发布和部署应用
小结
第13章实训指导
13.1实训1熟悉C#开发环境
13.1.1实训目的和要求
13.1.2题目1如何运行和中断程序
13.1.3题目2模拟邮箱注册
13.1.4题目3创建和调用C#类库程序
13.2实训2C#数据类型与数组
13.2.1实训目的和要求
13.2.2题目1定义用户结构体
13.2.3题目2数组的统计运算
13.2.4题目3使用DateTime结构
13.3实训3表达式和流程控制
13.3.1实训目的和要求
13.3.2题目1计算购物金额
13.3.3题目2计算最小公倍数和最大公约数
13.3.4题目3冒泡排序算法的实现
13.4实训4类和结构
13.4.1实训目的和要求
13.4.2题目1圆类
13.4.3题目2用户注册登录模型
13.4.4题目3按销量对图书排序
13.5实训5继承和多态
13.5.1实训目的和要求
13.5.2题目1顾客类的派生
13.5.3题目2汽车类的派生与多态
13.5.4题目3管理学生信息
13.6实训6接口和泛型
13.6.1实训目的和要求
13.6.2题目1接口定义和实现
13.6.3题目2泛型方法
13.6.4题目3泛型集合
13.7实训7Windows应用程序
13.7.1实训目的和要求
13.7.2题目1计算器的设计
13.7.3题目2菜单设计
13.7.4题目3多文档界面设计
13.7.5题目4控件综合应用
13.8实训8GDI 编程
13.8.1实训目的和要求
13.8.2题目1基本图形绘制
13.8.3题目2绘制实体图形
13.8.4题目3绘制图形和文字
13.9实训9文件和流
13.9.1实训目的和要求
13.9.2题目1目录的管理
13.9.3题目2文件的管理
13.10实训10数据库应用
13.10.1实训目的和要求
13.10.2题目1数据库显示
13.10.3题目2数据库操作
13.10.4题目3学生信息的管理
13.11实训11异常处理
13.11.1实训目的和要求
13.11.2题目1处理运算溢出异常
13.11.3题目2自定义异常及处理
参考文献
|
內容試閱:
|
前言
C#语言是一种安全的、稳定的、简单的、优雅的面向对象编程语言。它在继承C和C强大功能的同时去掉了它们的一些复杂特性(例如,没有宏以及不允许多重继承)。C#综合了VB简单的可视化操作和C的高运行效率,以其强大的操作能力、优雅的语法风格、创新的语言特性和便捷的面向组件编程等特性成为 .NET开发的首选语言。C#增强了开发者的效率,同时也致力于消除编程中可能导致严重结果的错误。C#使CC程序员可以快速进行网络开发,同时也保持了开发者所需要的强大性和灵活性。1. 编写背景国家中长期教育改革和发展规划纲要20102020指出: 坚持能力为重。优化知识结构,丰富社会实践,强化能力培养。着力提高学生的学习能力、实践能力、创新能力,教育学生学会知识技能,学会动手动脑。本教材就是按照构建创新型、应用型人才培养模式的要求,突出对学生实践应用能力的培养,适应社会需求。从问题开始,按照提出问题分析问题明确目标学习知识解决问题总结提高的思路编写。激发学生学习的主动性,提高学生的思考能力和创新应用能力。2. 本书内容在第一版的基础上,本书对原有的部分内容进行了精简,增加了部分习题。根据实际应用的需要,新增了LINQ集成查询和网络编程的内容,包括以下6部分。(1) C#语法基础: 包括基本语法、类型系统、表达式和流程控制。(2) 面向对象程序设计: 包括类、接口、继承和多态性、泛型。(3) Windows程序设计: 包括各种常用控件的使用和GDI 编程。(4) 商业开发的知识: 包括文件操作、数据库操作、异常处理、网络编程和多线程编程。(5) 综合开发案例全程讲解。(6) 实训指导。3. 本书特色(1) 充分研讨,适合教学。作者根据多年的实际教学经验,在内容深度、编程方法和案例选择等方面进行了深入的分析和研讨,使本书内容尽量满足高等院校学生的学习需要。(2) 由浅入深,通俗易懂。书中知识点的讲解尽量用简洁、形象的语言来表达,避免过于冗长和烦琐的表述。(3) 问题导入,以问开始。每一章的内容从一个问题开始,按照提出问题分析问题明确目标学习知识解决问题总结提高的思路编写。(4) 案例丰富,以用促学。书中每一个知识点都有相应的应用案例,案例程序符合实际应用,减少理论知识的讲解,通过实践应用让读者来领悟知识的内涵。(5) 案例讲解,满足自学。对每一个案例的程序都进行了分析讨论,特别是涉及扩充知识的会详细说明,有利于读者很好地自我学习。(6) 校企合作,保证质量。本书的作者既有院校的一线授课教师,也有IT企业的资深技术人员,将教师的教学经验与工程技术人员的工程实践经验相结合,满足培养应用实践型人才的需要。(7) 代码详细,配套完善。书中每个案例都有详细的源代码,另外提供相应的PPT课件、实训指导、习题及参考答案、综合开发案例,满足课堂教学、课后练习、上机实验和课程设计的一体化需要。4. 读者对象本书以问题导入知识的学习,通过丰富的案例和案例剖析,帮助读者在实践中体会知识的应用,通过问题的解决获得学习的成就感。综合案例是采用三层架构开发的Web应用程序,对开发工具、技术和开发过程进行了全面讲解,读者学习后可以举一反三。本书可作为高等院校C#程序设计相关课程的教材,也可供广大 .NET开发人员学习和参考。本书第3、4、6、7、9、12、13章由于世东编写,第1、2章由邵中编写,第10章由刘春颖编写,第8章由卜霄菲编写,第5、第11章由王艳编写。辽宁省信息中心高级工程师高山对第12、13章的编写进行了指导。杜庆东教授审阅了全稿并提出了许多有益的意见。沈阳工业大学牛连强教授在本书编写过程中给予了指点和帮助,在此谨向他们表示衷心的感谢。感谢清华大学出版社在本书的出版过程中给予的支持。由于作者学识浅陋,见闻不广,书中必然存在不足之处,敬请读者批评、指正和建议。作者的Email地址是: ysd0510@sina.com,欢迎读者与作者进行交流和探讨。编者2017年3月
第3章面向对象编程基础
面向对象程序设计是在面向过程程序设计的基础上发展而来的,它将数据和对数据的操作看作是一个不可分割的整体。通过采用数据抽象和信息隐藏技术,将现实世界问题的求解简单化,从而获得更好的应用架构和开发效率,同时提高程序的可维护性。本章将对面向对象程序设计中的基础知识进行详细讲解。3.0问 题 导 入【导入问题】我们需要创建一个程序来描述多辆汽车的信息,每辆车的基本信息包括: 车辆型号、发动机型号、车轮个数、车轮型号。假定车辆分为两大类: 轿车类和公共汽车类,两类汽车都有鸣笛行为,但鸣笛发出的声音是不同的,该如何实现呢?【初步分析】按照前面所学的知识,需要定义多个数组,每个数组存储车辆的一种信息,要获取一辆车的完整信息需要访问多个数组。对两类汽车的鸣笛行为分别调用不同的方法实现。这种操作方式是比较烦琐的,操作也不够灵活,那么利用面向对象的编程思想来创建应用程序会使问题简化吗?3.1类 的 定 义类是封装数据的基本单位,是一组具有相同数据结构和相同操作的对象的集合,用来定义对象的组成及可执行的操作。我们将类的实例称为对象,一旦创建了一个对象,就可以调用对象的属性、方法和事件来访问对象的功能。对象是现实中一个具体的事物可以是具体的也可以是抽象的,类是对对象的概括。比如一个苹果、一个梨等都是一个对象,水果类就是对所有对象的抽象。3.1.1类的声明与成员组织C#语言中,声明类的一般形式为:
[访问修饰符] class类名称[: [基类] [,接口序列]]
{
[字段声明]
[构造函数]
[方法]
[事件]
}
关于声明类的说明如下。(1) []中的内容为可选项,冒号:后面的内容表示被继承的类或接口。(2) 当一个类从另一个类继承时,被继承的类叫做基类或父类,继承的类叫做派生类或子类。(3) 基类只能有一个,但一个类可以继承多个接口,继承的内容多于一项时,各项之间用逗号分开。(4) 如果一个类同时继承基类和接口,则要把基类放在冒号后面的第一项,然后才是接口。【例31】类的声明举例。
01.namespace Example3_1
02.{
03.public class Apple
04.{
05.private string productId;
06.private double productPrice;
07.带参数的构造函数
08.public Applestring id, double price
09.{
10.productId = id;
11.productPrice = price;
12.}
13.方法
14.public void OutPut
15.{
16.Console.WriteLine"{0}_apple''s price is:{1}",productId, productPrice;
17.}
18.}
19.class Example3_1
20.{
21.static void Mainstring[] args
22.{
23.Apple apple1 = new Apple"a001",2.3;
24.Apple apple2 = new Apple"a002",3.3;
25.Apple apple3 = new Apple"a003",4.6;
26.apple1.OutPut;
27.apple2.OutPut;
28.apple3.OutPut;
29.Console.Read;
30.}
31.}
32.}
33.}
【运行结果】单击工具栏中的开始按钮,即可在控制台中输出如图31所示的结果。
图31例31运行结果
【程序说明】(1) 在这个实例中,声明了一个Apple类,第5、6行声明了Apple类的两个私有字段,分别代表产品的编号和价格。(2) 第8行定义了一个Apple类的带参构造函数,通过该构造函数在创建对象时,可以定义产品的编号和价格。(3) 第14行定义了一个Apple类的公有输出方法,通过该方法在外部可以读取产品的信息。(4) Example3_1类中主函数的前三行,使用new创建了三个Apple类的对象,在创建对象的同时定义了产品的编号和价格。(5) 主函数中第26~28行对每个Apple类对象调用其OutPut方法输出产品信息。说明: 如果不使用类去创建三个苹果对象,你会怎么做呢?按以前的方法需要对三个苹果的信息分别创建一次,而在Apple类中通过构造函数可以轻松创建多个对象,Apple类中定义的方法可以为所有对象共同使用。跟面向过程的编程方式比较一下,感觉到面向对象编程方式的好处了吗?3.1.2字段和局部变量字段是在类或结构中声明的任何类型的类级别变量,它是类或结构的直接下属,是整个类内部所有方法和事件都可以访问的变量。局部变量是相对于字段来说的,可以将它理解为块一级的变量。例如,在某个方法或循环体内定义的变量等,其作用域仅局限于定义它的语句块内。两者在使用上要注意: 对于字段如果没有初始化,C#会自动将其初始化为默认值; 但对于局部变量,C#不会自动为其进行初始化,如果局部变量在使用前未被赋值,在编译时会报错。【例32】字段和局部变量的使用举例。
01.namespace Example3_2
02.{
03.class Example3_2
04.{
05.public static int m;
06.static void Mainstring[] args
07.{
08.int n=1;
09.Console.WriteLine"静态字段m的值是: {0}",m;
10.Console.WriteLine"局部变量n的值是: {0}",n;
11.Console.Read;
12.}
13.}
14.}
【运行结果】单击工具栏中的开始按钮,即可在控制台中输出如图32所示的结果。
图32例32运行结果
【程序说明】1 第5行定义了一个静态整型字段m,未对其赋初始值,则其默认值为0。2 第8行在Main函数中定义了一个局部整型变量n,如果对n未进行初始化,编译时就会报错。3 局部变量未有与静态字段m重名的,所以在m的前面未加类名也可以。当字段和局部变量名相同时程序设计时尽量避免,如果要引用静态字段,可以使用下面的形式。
类名.字段名
如果是实例字段,则使用下面的形式:
this.字段名
这里的this指当前实例。3.1.3静态成员和实例成员在类中定义的数据称为类的数据成员,如字段、常量等。而函数成员则提供类的某些操作功能,如方法、属性等。默认情况下这些成员都是实例成员,这些成员属于类的实例所有,每创建一个对象时这些成员就会被创建一次。有一些成员是所有对象共用的,如果把这样的成员作为实例成员,当创建了多个对象时,在堆中就会出现很多相同的内容,这样会导致系统资源的浪费。解决这个问题的办法是将成员定义为静态的,静态成员属于类所有,为这个类的所有实例所共享,无论为这个类创建了多少对象,一个静态成员在内存中只占一块区域。实例成员通过类的实例进行调用,静态成员由类本身进行调用。【例33】实例成员与静态成员的使用。
01.namespace Example3_3
02.{
03.public class Payment
04.{
05.int productNums;商品数量
06.double productPrice;商品单价
07.static double totalPrice;所有商品总价
08.public Paymentint nums, double price 实例构造函数
09.{
10.productNums = nums;
11.productPrice = price;
12.}
13.static Payment 静态构造函数
14.{
15.totalPrice = 0.0;
16.}
17.public void Calculate 实例方法
18.{
19.totalPrice= productNums * productPrice;
20.}
21.public static void PrintTotal 静态方法
22.{
23.Console.WriteLine"所有商品总价为: {0}",totalPrice;
24.}
25.}
26.class Example3_3
27.{
28.static void Mainstring[] args
29.{
30.Payment apple = new Payment5, 1.2;
31.Payment banana = new Payment6, 1.7;
32.apple.Calculate;
33.banana.Calculate;
34.Payment.PrintTotal;
35.Console.Read;
36.}
37.}
38.}
【运行结果】单击工具栏中的开始按钮,即可在控制台中输出如图33所示的结果。
图33例33运行结果
【程序说明】1 在这个实例中,Payment类中首先定义了三个字段,其中,totalPrice是静态字段。2 Payment类中第8~12行定义了一个带参数的构造函数,通过该构造函数可以指定商品的数量和单价; 第13~16行定义了一个静态的构造函数,该函数完成对静态字段totalPrice的初始化。3 Payment类中第17~20行定义了一个实例计算方法,计算当前商品的总价后加到静态字段totalPrice上; 第21~24行定义了一个静态方法用于输出所有商品的总价,即输出totalPrice的值。4 在类Example3_3的Main函数中实例化了两个Payment类的对象,并调用相应的方法。静态构造函数只被调用一次,所以静态字段totalPrice也只被初始化一次; 而实例构造函数被调用两次分别生成apple和banana对象。5 实例方法Calculate为每个对象所有,在第32行和33行通过对象自身的调用分别计算出apple和banana的总价。6 静态方法PrintTotal为Payment类本身所有,在第34行通过类本身进行调用,输出所有商品的总价。3.1.4访问修饰符访问修饰符用于控制类及类的成员的访问权限,便于对数据进行控制和修改,下面分别进行介绍。1. 类的访问修饰符类的访问修饰符及每个修饰符的含义如下。(1) public: 公有类,不限制对该类的访问。(2) internal: 项目内类,在当前项目内可以被自由访问,而对其他程序集来说无法访问。(3) partial: 分部类型,类的定义和实现可以分布在多个文件中,但都需要使用partial标注。2. 类成员访问修饰符类成员的访问修饰符及每个修饰符的含义如下。(1) public: 公有访问,外部类可以不受限制地存取这个类的数据成员或访问其方法。(2) private: 私有访问,类的数据成员和方法只能在此类中使用,外部无法存取。(3) protected: 保护访问,类及派生类中的成员可以访问,无法从类的外部进行访问。(4) internal: 内部访问,在当前项目内可以被自由访问,而对其他程序集来说无法访问。(5) protected internal: 在当前项目内,只有类及派生类中的成员可以访问。【例34】访问修饰符的使用。改写例33
01.namespace Example3_4
02.{
03.class Payment
04.{
05.int productNums;
06.double productPrice;
07.static double totalPrice;
08.public Paymentint nums, double price
09.{
10.productNums = nums;
11.productPrice = price;
12.}
13.static Payment
14.{
15.totalPrice = 0.0;
16.}
17.internal void Calculate
18.{
19.totalPrice= productNums * productPrice;
20.}
21.internal static void PrintTotal
22.{
23.Console.WriteLine"所有商品总价为: {0}", totalPrice;
24.}
25.}
26.class Example3_4
27.{
28.static void Mainstring[] args
29.{
30.Payment apple = new Payment5, 1.2;
31.Payment banana = new Payment6, 1.7;
32.apple.Calculate;
33.banana.Calculate;
34.Payment.PrintTotal;
35.Console.Read;
36.}
37.}
38.}
【运行结果】单击工具栏中的开始按钮,即可在控制台中输出如图34所示的结果。
图34例34运行结果
【程序说明】(1) 本例中未对Payment类加访问修饰符,默认为internal; 第5~7行定义的三个字段默认访问修饰符为private,在类的外部无法被访问。(2) 实例构造函数的访问修饰符一般为public,静态构造函数不允许使用访问修饰符,对于构造函数3.2节中将进行介绍。(3) 第17和21行的Calculate和PrintTotal方法的访问修饰符定义为internal,在此项目内namespace Example3_4命名空间下可以被访问,项目外无法被访问。如果将这两个方法的访问修饰符改为private或protected,在类Example3_4的Main函数中就无法访问了。(4) 由此例可以看出,类的默认访问修饰符为internal; 类中的数据成员和函数成员的默认访问修饰符为private。3.2构造函数和析构函数对象和客观世界中的事物一样,从创建到消亡都有一个生命周期,对象的创建和销毁是通过类的构造函数和析构函数来完成的。3.2.1构造函数构造函数是在创建给定类型的对象时执行的类方法,通常用于初始化新对象的数据成员。构造函数具有以下特点。(1) 构造函数的名称与类名相同。(2) 构造函数不包含任何返回值。(3) 每个类至少有一个构造函数,如果没有显式地定义构造函数,系统会自动为该类提供一个默认的构造函数。(4) 构造函数在创建对象时被自动调用,不能被显式地调用。(5) 一般使用访问修饰符public定义构造函数,以便在其他函数中可以创建该类的实例。如果使用访问修饰符private定义构造函数则是私有构造函数,私有构造函数是一种特殊的构造函数,通常用在只包含静态成员的类中,用来阻止该类被实例化。1. 默认构造函数如果在类中没有显式定义构造函数,系统会自动提供一个默认的构造函数,默认构造函数没有参数。提供默认构造函数的目的是为了保证能够在使用对象前先对未初始化的非静态类成员进行初始化。具体如下。(1) 对数值型,如int、double等,初始化为0。(2) 对bool类型,初始化为false。(3) 对引用类型,初始化为null。2. 静态构造函数静态构造函数主要用于对类的静态字段进行初始化,它不能使用任何访问限制修饰符。在程序中第一次用到某个类时,类的静态构造函数自动被调用,而且是仅此一次。3. 带参构造函数不带任何参数的构造函数称为默认构造函数。有时希望通过传递不同的数据来创建不同的对象,这时可以使用带参数的构造函数。根据传递参数的不同,一个类可以有多个构造函数,以便根据不同的需要来创建不同的对象。3.2.2析构函数析构函数是对象销毁前释放所占用系统资源的类成员。 .NET Framework类库具有垃圾回收功能,当对象使用完毕后,并符合析构条件时,.NET Framework类库的垃圾回收功能就会调用对应类的析构函数实现垃圾回收。析构函数具有以下特点。(1) 析构函数的名称与类名相同,但在名称前面需加一个符号~。(2) 析构函数不带任何参数,也不返回任何值。(3) 析构函数不能使用任何访问限制修饰符。(4) 析构函数的代码中通常只进行销毁对象的工作,而不应执行其他的操作。(5) 析构函数不能被继承,也不能被显式地调用,一个类只能有一个析构函数。【例35】构造函数和析构函数使用示例。
01.namespace Example3_5
02.{
03.public class Destructor
04.{
05.public Destructor
06.{
07.Console.WriteLine"---创建对象时自动调用默认构造函数!---";
08.}
09.~Destructor
10.{
11.Console.WriteLine"---程序运行结束时自动调用析构函数!---";
12.Console.Read;
13.}
14.}
15.class Example3_5
16.{
17.static void Mainstring[] args
18.{
19.Destructor test = new Destructor;
20.}
21.}
22.}
【运行结果】单击工具栏中的开始按钮,即可在控制台中输出如图35所示的结果。
图35例35运行结果
【程序说明】(1) 第3行定义了一个Destructor类,其中包含一个无参的默认构造函数和一个析构函数。(2) 第19行在Main函数中创建一个Destructor类对象test时,首先调用了该类的默认构造函数,当程序运行结束时自动调用析构函数。说明: 如果类中没有显式地定义析构函数,编译器会为其生成一个默认的析构函数,其执行代码为空。事实上,在C#语言中使用析构函数的机会很少,通常只用于一些需要释放资源的场合,如删除临时文件、断开与数据库的连接等。3.3类 的 方 法方法是一组程序代码的集合,用于完成指定的功能。每个方法都有一个方法名,便于识别和让其他方法调用。方法实际上就是函数,在面向过程的程序设计语言中称为函数,在面向对象的程序设计语言中,除了构造函数以外,其他的函数可以是方法或事件。3.3.1方法的声明C#程序中方法必须包含在类或结构中。声明方法的一般形式为:
[访问修饰符] 返回值类型 方法名称[参数序列]
{
[语句序列]
}
一个方法的名称和参数列表定义了该方法的签名,即一个方法的签名由方法的名称、参数的个数、参数的修饰符及参数的类型组成。在定义方法时,需要注意以下几点。(1) 如果参数序列中的参数有多个,用逗号分隔开; 如果没有任何参数,方法名后面的小括号必须保留。(2) 如果声明一个非void类型的方法,则方法中至少要有一个return语句; 如果方法的返回类型为void,则可以没有return语句。(3) 方法的名称必须与在同一个类中声明的所有其他非方法成员的名称都不相同。例34中的Calculate和PrintTotal方法都是不带参数的,关于带参数的方法下面进行详细介绍。3.3.2方法中的参数传递C#中的许多方法成员是有参数的,定义方法时声明的参数是形式参数或叫虚拟参数,调用方法时要给形式参数传值,传递的值是实在参数。C#有值传递和引用传递两种参数传递方式。具体的传递形式有以下几种。1. 传递值类型的参数值传递是C#默认的传递方式,使用值传递方式时,向形式参数传递的是实在参数的副本,方法内对形式参数的更改对实在参数本身没有任何影响,就像文件的复印件一样,无论如何修改复印件,原件没有任何改变。【例36】以值传递的方式传递值类型数据。
01.namespace Example3_6
02.{
03.class Swap
04.{
05.public static void SwapIntint x, int y
06.{
07.int temp;
08.temp = x;
09.x = y;
10.y = temp;
11.}
12.}
13.class Example3_6
14.{
15.static void Mainstring[] args
16.{
17.int m = 5, n = 10;
18.Console.WriteLine"交换前: m={0}, n={1}", m, n;
19.Swap.SwapIntm, n;
20.Console.WriteLine"交换后: m={0}, n={1}", m, n;
21.Console.Read;
22.}
23.}
24.}
【运行结果】单击工具栏中的开始按钮,即可在控制台中输出如图36所示的结果。
图36例36运行结果
【程序说明】(1) 在类Swap中定义了一个静态的SwapInt方法,该方法的功能是完成两个整数的交换。(2) Main函数中第17行定义了两个整型变量m和n,并赋予初始值; 第19行在Main函数中调用Swap类的SwapInt方法,m、n作为实参将值传递给形参x、y,从运行结果可以看到m、n的值并未发生改变。(3) 出现上述情况的原因在于m、n的值分别传给x、y时,x和y开辟了新的存储空间,它们是m和n的复印件,所以在SwapInt方法内对x和y的交换并不能改变m和n的值。【例37】以值传递的方式传递引用类型数据。
01.namespace Example3_7
02.{
03.class Swap
04.{
05.public static void AddOneint[] a
06.{
07.for int i = 0; i max max = a[i];
11.if a[i] 属性
{
get
{
return age;
}
}
}
set访问器: 没有返回值,它使用称为value的隐式参数,此参数的类型与属性的类型相同。例如:
class Student
{
private int age;字段
public int Age属性
{
set
{
age = value;
}
}
}
关于属性的说明如下。(1) 当读取属性时,执行get访问器的代码块; 当向属性分配一个新值时,执行set访问器的代码块。(2) 只包含get访问器的属性称为只读属性,只包含set访问器的属性称为只写属性,同时具有这两个访问器的属性称为读写属性。(3) get访问器的返回值类型与属性类型相同,所以在其语句块中return语句的返回值必须与属性类型相同或能隐式转换为属性类型。(4) 属性也可以使用static关键字声明为静态属性。当属性访问器中不需要其他逻辑时,也可以用简单的方式声明属性,这种方式称为自动实现的属性。自动实现的属性必须同时声明get和set访问器。如果希望声明只读属性,必须将set访问器声明为private; 如果希望声明只写属性,必须将get访问器声明为private。使用自动实现的属性可使属性声明变得更简单,因为这种方式不再需要声明对应的私有字段。例如:
class Student
{
public int Age 只读属性
{ get; private set;}
public sting Name 读写属性
{ get; set; }
}
上面这段代码中声明了两个自动实现的属性,其中,Age是只读属性,Name是读写属性。【例312】属性的声明与使用。
01.namespace Example3_12
02.{
03.public class Student
04.{
05.public string Name { get; set; }
06.private DateTime birthday;
07.private int grade = 0;
08.public int Age
09.{
10.get { return DateTime.Now.Year - birthday.Year; }
11.}
12.public int Grade
13.{
14.get { return grade; }
15.set
16.{
17.if value = 0 && value ; ==、!=; true、false必须成对出现,即重载了,重载了==就必须重载!=,重载了true就必须重载false。【例315】操作符重载示例。
01.namespace Example3_15
02.{
03.struct Hour
04.{
05.private int hvalue;
06.public Hourint ivalue
07.{
08.this.hvalue = ivalue;
09.}
10.public int HValue
11.{
12.get
13.{ return hvalue; }
14.set
15.{ hvalue = value; }
16.}
17.public static Hour operatorHour h1, Hour h2
18.{
19.Hour h3 = new Hour;
20.
21.h3.HValue = h1.HValue h2.HValue;
22.return h3;
23.}
24.public static Hour operatorHour h1, int h2
25.{
26.return new Hourh2 h1;
27.}
28.public static Hour operator Hour hrValue
29.{
30.hrValue.HValue;
31.return hrValue;
32.}
33.public static bool operator ==Hour hr1, Hour hr2
34.{
35.return hr1.HValue == hr2.HValue;
36.}
37.public static bool operator !=Hour hr1, Hour hr2
38.{
39.return hr1.HValue != hr2.HValue;
40.}
41.}
42.class Example3_15
43.{
44.static void Mainstring[] args
45.{
46.Hour hrValue1 = new Hour10;
47.Hour hrValue2 = new Hour20;
48.Hour hrSum = hrValue1 hrValue2;
49.Console.WriteLine"hrValue1 hrValue2 = {0}",hrSum.HValue;
50.Hour hrSumInt = hrValue1 10;
51.Console.WriteLine"hrValue1 10 = {0}", hrSumInt.HValue;
52.Console.ReadLine;
53.}
54.}
55.}
【运行结果】单击工具栏中的开始按钮,即可在控制台中输出如图315所示的结果。
图315例315运行结果
【程序说明】(1) 结构Hour中包含一个字段和一个属性,实现了4种操作符的重载。(2) 第17~23行实现对两个Hour类型的变量进行相加的重载; 第24~27行实现一个Hour类型的变量和一个整型变量相加的重载。(3) 第28~32行实现对一元操作符的重载,使Hour类型的变量的HValue字段值加1。(4) 第33~36行实现对二元操作符==的重载,用于判定两个Hour类型的变量是否相等。按照C#中的操作符重载规则,重载==就需要重载!=,所以第37~40行实现了对!=运算符的重载。3.7问 题 解 决经过对类的基本知识的学习,我们对导入问题的解决方法有了另一种思考。可以采取下面的步骤来加以解决。1 声明轿车类,使用成员方法定义其鸣笛行为。2 声明公共汽车类,使用成员方法定义其鸣笛行为。根据以上思路,解决问题的完整代码如下。【例316】解决导入问题。
01.namespace Example3_16
02.{
03.public class Car
04.{
05.private string id; 汽车型号
06.private double engine; 发动机型号
07.private int wheels; 车轮个数
08.private int whlType; 车轮型号
09.public Carstring cid, double e, int whls, int wtype
10.{
11.id = cid;
12.engine = e;
13.wheels = whls;
14.whlType = wtype;
15.}
16.public void PrintInfo
17.{
18.Console.WriteLine"{0}:排气量{1},车轮数{2},车轮型号{3}", id, engine, wheels, whlType;
19.}
20.public void Whistle
21.{
22.Console.WriteLine"小轿车: 嘀嘀!";
23.}
24.}
25.public class Bus
26.{
27.private string id;
28.private double engine;
29.private int wheels;
30.private int whlType;
31.public Busstring bid, double e, int whls, int wtype
32.{
33.id = bid;
34.engine = e;
35.wheels = whls;
36.whlType = wtype;
37.}
38.public void PrintInfo
39.{
40.Console.WriteLine"{0}:排气量{1},车轮数{2},车轮型号{3}", id, engine, wheels, whlType;
41.}
42.public void Whistle
43.{
44.Console.WriteLine"大公交: 嘟嘟!";
45.}
46.}
47.class Example3_16
48.{
49.static void Mainstring[] args
50.{
51.Car c1 = new Car"红旗2012", 1.6, 4, 20;
52.Car c2 = new Car"中华2012", 1.4, 4, 20;
53.Bus b1 = new Bus"黄海2012", 4.2, 6, 50;
54.c1.PrintInfo;
55.c1.Whistle;
56.c2.PrintInfo;
57.c2.Whistle;
58.b1.PrintInfo;
59.b1.Whistle;
60.Console.Read;
61.}
62.}
63.}
【运行结果】单击工具栏中的开始按钮,即可在控制台中输出如图316所示的结果。
图316例316运行结果
【程序说明】(1) 程序中定义了轿车类Car和公共汽车类Bus,通过类的构造函数完成车辆信息的初始化,PrintInfo方法输出车辆信息,Whistle方法输出鸣笛信息。(2) 在主程序中实例化了两个Car对象和一个Bus对象,通过调用对象的方法输出各自的信息和实现各自的鸣笛行为。(3) 通过本例可以看到,通过类对车辆对象进行封装后,大大提高了车辆的生产效率,操作上非常方便、快捷。小结类是面向对象程序设计的基本元素,是C#中最重要的一种数据类型。类可以包含字段成员、方法成员以及其他的嵌套类型。构造函数、析构函数、属性、索引器、事件和操作符都可以视为特殊的方法成员,它们在使用中都有着各自的特点。对象的生命周期从构造函数开始,到析构函数结束; 类的构造函数用于对象的初始化,而析构函数用于对象的销毁。利用事件和索引函数提供的访问方法,可以隐藏数据处理的细节,更好地实现对象的封装性。通过操作符重载,C#预定义的操作符就能直接作用于各种自定义类型。类的大部分成员用法也适用于结构,唯一的区别在于类是引用类型,而结构是值类型。对于方法来说,学习的重点在于掌握形参和实参的区别,以及不同类型参数的使用方法。课 后 练 习一、 选择题1. C#语言的核心是面向对象编程OOP,所有OOP语言应至少具有三个特性。
A. 类、对象和方法B. 封装、继承和多态C. 封装、继承和派生D. 封装、继承和接口2. 在类的定义中,类的描述了该类的对象的行为特征。A.方法B. 类名C. 所属的命名空间D.私有域3. C#可以采用下列技术来进行对象内部数据的隐藏。A. 静态成员B. 变量C. 属性D. 装箱技术4. C#的构造函数分为实例构造函数和静态构造函数,实例构造函数可以对进行初始化,静态构造函数只能对进行初始化。A. 静态成员B. 非静态成员C. 静态成员或非静态成员D. 常量成员5. C#实现了完全意义上的面向对象,所以它没有,任何数据域和方法都必须封装在类体中。A. 全局变量B. 全局常数C. 全局方法D. 全局变量、全局常数和全局方法6. 方法中的值参数是的参数。A. 按引用传递B. 按值传递C. 按地址传递D. 不传递任何值7. 假设class Myclass类的一个方法的签名为: public void Max out int max, params int[ ] a,m1是Myclass类的一个对象,maxval是一个int型的值类型变量,arrayA是一个int型的数组对象,则下列调用该方法有错的是。A. m1.Max out maxvalB. m1.Max out maxval,4,5,3C. m1.Max out maxval,ref arrayAD. m1.Max out maxval,3,3.58. 类Myclass中有下列方法定义:
public void testParamsparams int[] a
{Console.Write"使用Params参数!"; }
public void testParamsint x, int y
{Console.Write"使用两个整型参数!"; }
请问上述方法重载有无二义性?若没有,则下列语句的输出为。
Myclass m1 = new Myclass;
m1. testParams1;
m1. testParams1,2;
m1. testParams1,2,3;
A. 有语义二义性B. 使用Params参数!使用两个整型参数!使用Params参数!C. 使用Params参数!使用Params参数!使用Params参数!D. 使用Params参数!使用两个整型参数!使用两个整型参数!9. 下面有关属性的说法,不正确的是。A. 属性可以有默认值B. 属性可以不和任何字段相关联C. 属性的get访问函数是不带参数的特殊方法D. 属性的set访问函数是没有返回值的特殊方法10. 分析下列程序:
public class Myclass
{
private string _sData = "";
public string sData {set {_sData = value;}}
}
在Main函数中,成功创建该类的对象m1后,下列哪些语句是合法的?
A. Console.Writem1.sData;B. m1._sData = "Good!";C. m1.setm1.sData;D. m1.sData = "Good!";11. 下面有关结构的说法,正确的是。A. 结构是轻量级引用类型B. 结构有默认的构造函数C. 结构有析构函数D. 结构的效率低于类12. 以下不能作为复合赋值操作符被重载的是。A. *=B.=C. &=D. ~=二、 简答题1. 对比面向对象程序设计和面向过程程序设计之间的优劣性。2. 写出下面程序的运行结果。
namespace Lx3_0202
{
class Myclass
{
public void SortArrayint[] a
{
int i, j, pos, tmp;
for i = 0; i a[j] pos = j;
if pos != i
{
tmp = a[i];
a[i] = a[pos];
a[pos] = tmp;
}
}
}
}
class Test
{
static void Main
{
Myclass m = new Myclass;
int[] score = { 87, 89, 56, 90, 100, 75, 64, 45, 80, 84 };
m.SortArrayscore;
for int i = 0; i
|
|