首页 > 代码库 > 深入.net平台和c#编程 学习笔记

深入.net平台和c#编程 学习笔记

深入.net平台和c#编程

一:理解.nteFramwork与c#
1.1,:Microsoft.net框架概述
1.2:.net框架结构
1.3.:c#语言概述
1.4:体验框架类库的强大功能
二:用对象思考:属性和方法
2.1:类和对象
2.2::编写一个自己的类
2..3:综合实践
三:用对象思考;值类型和应用类型
3.1:在类中使用几种新的数据类型
3.2::理解c#中的值类型和引用类型
3.3:在类中使用索引器
3.4:使用类图描述类和类成员
四:用集合组织相关数据
4.1::集合概述
4.2:泛型和泛型集合
4.3:综合实践
五:文件读写和xml
5.1:文件
5.2::新闻阅读器工作原理概述
5.3:操作XML实现抓取新闻功能
六:用对象思考:继承
6.1继承概述
6.2继承的使用
6.3综合实战
七:用对象思考:多态
7.1面向对象的多态性
7.2使用抽象类和抽象方法是实现多态
7.3使用虚方法实现多态
7.4简单工厂设计模式
八:用对象思考:接口
8.1接口
8.2泛型接口
8.3接口的典型应用
九:序列化与反射
9.1序列化和反序列化
9.2程序集和反射


快捷键——紫色,注意事项——绿色,关键点——红色。
----------------------------------------------------------------------------------------------------------------------
一:
1.1,:Microsoft.net框架概述
.NET框架是.NET战略的基础,是一种新的便捷的开发平台,只有在计算机上安装部署了.NET框架,我们才能获得.NET框架带给我们的便捷与强大功能。体现在:
1,提供了一个面向对象的编程环境,完全支持面向对象编程。
2,为WEB应用的强大支持
3,对WebService(Web服务)的支持
4,VisualStudio是一个世界级的开发工具,和.NET框架配合(能够方便开发多种.net应用程序,及进行测试,版本控制,Team开发,部署等)

1.2:.net框架结构




.NET Framwork
1,.NET Framwork类库
Web窗体,WebService,WinForms,ADO.NET和XML类,基本框架类
2,CLR
CLS,CTS

1.NET框架运行于操作系统上,是.NET最基础的框架。提供了创建,部署,和运行.NET应用的环境。包含:CLR和框架类库,支持多种语言开发。
2CLR(Common Language Runtime)公共语言运行时:是所有.NET应用程序运行时环境,是所有.NET应用程序都要使用的编程基础(支持.NET应用程序运行和开发的虚拟机,开发和安装.NET应用程序都必须安装.NET Framework),可以看做是一个执行时管理代码的代理(管理代码是CLR的基本原则,能被管理的代码称为托管代码,反之为非托管代码),包含两个组件:CLS,CTS。
CTS(Common Type System通用类型系统):用于解决不同语言的数据类型不同的问题;
CLS(Common Language Specification公共语言规范):最低的语言标准,制定了一种以.NEt平台为目标的语言所必需支持的最小特征以及该语言与其他.NET语言之间实现互操作性所需要完备特征(遵循这个标准的语言在.NET框架下都可以实现互相调用)

3.NET编译技术
代码托管:例如,MSIL(Microsoft Intermediate Language微软中间代码)-----JIT(Just In Time编译器)--->>机器代码(平台(操作系统)专用代码)
     1.2.3框架类库
(1)基础数据的类库
(2)I/O访问(主要用于操作文件)
(3)安全控制(为.net安全机制提供一系列的功能)
(4)数据访问(利用ado.net开发数据库的应用程序)
(5)xml适用于描述数据的一种文件格式

1.3.:c#语言概述
1.3.1: 专门为.net平台设计的一种语言,设计者:Anders Hejlsberg(Pascal和Delphi语言的缔造者)
1.3.2:c#锐利体验:
(1)c#2003成为了一个ISO标准
(2)完全面向对象设计
(3)对泛型的完整支持(从2.0版本开始)
(4)C#语言与Web应用开发紧密地结合在一起
(5)强大的类库支持
(6)可以开发多种应用程序
1.4:体验框架类库的强大功能
注意:Java是一个跨平台的语言而.NET是一个跨语言的平台
1.4.1:类库的使用
例如:用程序实现用ping命令检验一个ip地址的功能

using System.Net;
using System.Net.NetworkInformation; //引入明命空间

private void btnPing_Click(Object sender,EventArgs e)
{
Ping pingSender=new Ping();
PingReply reply=pingSender.Send(txtIP.Text);
If(reply.Status==IPStatus.Success)
{
string message=string.Format("地址:{0}测试连接成功!",txtIP.Text);
MessageBox.Show(message);
}
else
{
string message=string.Format("地址:{0}测试连接成功!",txtIP.Text);
MessageBox.Show(message);
}
}
例如:下载图片(调用WebClient类中的DownLoadFile()的方法)
using System.Net;
Private void btnDownload_Click(object sender,EventArgs e)
{
try
{
WebClient webClient=new WebClient();
webClient.DownloadFile("http://localhost/mynewsreader/dingdang.png","dingdang.png");//指定自己的WebUrl
}catch(Exception ex)
{
MessageBox.Show(ex.ToString());
}
}
1.4.2框架类库中的命名空间
在类库中包含170多个命名空间,上千个类,框架类库的内容被组织成一个树状命名空间(Namespace Tree)
System:Data,Windows(Forms),Net,Collections(Generic),Security

System:树的“根”,此命名空间包含.net框架类库中的其他所有命名空间
System.Data:访问ADO.NET;(DataTable,DataSet)
System.Windows.Forms:开发Windows应用程序;(才能使用WinForms的控件和各种特性)
System.Collections.Generic:泛型;
System.Net:对网络协议进行编程;
System.Security:提供系统的安全控制功能;
1.4.3定义自己的命名空间
组织自己的类,避免类名冲突。
1.4.4命名空间的使用
C#中的命名空间只是一种逻辑上的结构,允许所组织的类文件的物理存放位置与逻辑结构不一致,而java中的类文件的物理结构必须与包的结构一致。
1,用自定义的命名空间组织类
2,引用命名空间
3,使用命名空间
4,命名空间的别名
指定别名的语句要放在程序头引入命名空间的位置
Using user=City.MySchool.Class; //指定别名
user.Student stu=new user.Student(); //使用别名调用

----------------------------------------------------------------------------------------------------------------------

二:用对象思考:属性和方法
2.1:类和对象
2.1.1:一切皆对象
2.1.2:类和类的成员
类的属性,类的方法
2.1.3:类和对象的关系
由对象归纳为类,是归纳共性的过程
在类的基础上,将状态和行为实例化为对象的过程成为实例化
2.1.4:类和对象的使用
将类实例化,访问对象的属性或方法
2.2::编写一个自己的类
2.2.1:定义类和类的成员
字段:表示与类和对象相关联的数据;
属性:表示类的状态;
方法:标识类的行为;
2.2.2:在类中添加属性
1,访问修饰符----可以更安全的编程,保护类中比较敏感的成员,公开外部需要访问的成员。
注意:如果不加修饰符,则:定义类的成员时,默认的访问类型为私有的(private)。
而类则默认是internal访问类型。
2,数据安全
将类中敏感的字段设置为私有,加入共有的属性成员,通过属性访问内部字段。
3,如何使用c#属性
get访问器:返回相应的私有字段的值,用return来返回;
set访问器:设定相应的私有字段的值,可以看作是一个隐含的输入参数(value)
4,使用属性的注意事项
定义一个属性时,类型必须与它所访问的字段类型一致。
5,属性的类型:
设定值或获取值,也可以设置为 [读写/只读/只写] 属性。
6,在编码中如何快速地创建属性:重构——封装字段(ctrl+r)+(ctrl+e)
选中字段,右击,重构,封装字段————创建与字段关联的属性(将字段封装)
7,封装
优点:避免使用非法数据赋值,保证数据的完整性,避免内部发生修改时导致整个程序的修改。
2.2.3:在类中使用方法、
访问修饰符 返回类型 方法名(参数)
{
方法体
}
2,方法的参数
使用值传递和ref方式传递,out方式传递:
值传递:在方法中对参数更改在调用后不能保留;
使用ref方式传递:可以将参数值的更改保留,侧重于修改;
out传递:可以保留修改,侧重于输出;(out类型的参数没有赋值前,是不能使用这个参数的)
3,使用方法:
4,方法重载:
处理不同类型类型的数据参数时可以不用判断类型,只要方法名相同,使用的参数类型或参数个数不同,编译器便知道在何种情况下应该调用哪个方法。两种:类型不同,个数不同。
5,静态方法和实例方法:
实例方法:使用类的实例对象来调用的方法
小结:静态方法不能直接访问实例成员,需要static关键字,需要类名调用,而实例方法不需要static关键字,可以访问实例成员和静态成员。当某个功能不依赖于具体的对象时则可以使用静态的。
2.2.4:使用构造函数创建对象
1,构造函数的使用
通常使用构造函数需注意:
类的构造函数名通常与类名相同,没有返回值,一般是Public类型的。注意:在构造函数中不要对类的示例做初始化以外的事,不要尝试显示的调用构造函数(直接调用)。
特殊情况下,构造函数可以是非public,例如:类的单例(在类的内部调用构造函数,设置相应的构造函数为私有的,而提供相应的调用方法为公有静态的等,在公有的方法中调用构造函数实例化对象)。
类的单例(log4j):声明类的对象为全局变量,在公有方法内调用私有构造函数并将对象赋给全局的静态对象(变量),结果是,不论什么时候重新调用那个方法获得的对象都是第一次实例化的那个对象。
2,this关键字——代表当前对象。
3..3:综合实践
1:设计新闻阅读器的类
2:命名规范
Pascal命名法:单词的第一个字母要大写。(适用于公有成员)
Camel命名法:首字母小写,后面的每个单词首字母大写。(适用于私有成员)

----------------------------------------------------------------------------------------------------------------------

三:用对象思考;值类型和应用类型
(应用程序的本质上说是对各种类型的数据进行加工和处理)
3.1:在类中使用几种新的数据类型
3.1.1在程序中使用的常量const:
常量是在程序的使用过程中不会发生改变的变量。(用于在程序中一旦设定就不需要修改,经常使用的值)
访问修饰符 const 数据类型 常量名 = 值
3.1.2:枚举enum(使用枚举避免不合理的赋值)
1, 优点:避免不合理赋值,设定特定量的值供以调用
2,给枚举成员赋值
枚举允许用描述性的名称表示整数值,即将相应的枚举值强制转换为定义枚举时所指定的整数型,获取枚举值的字符串表示,从一个字符串获取枚举的值。
例如:
public enum Genders()
{
Male=0,Female =1
}
static void Main(string[] args)
{
stu.Gender=Genders.Male;
//强制转换为int型,得到定义枚举是所指定的整数值
int genderNum=(int)stu.Gender; 
//获取它的字符串表示
Console.WriteLine("您输入的性别是{0}",stu.Gender.ToString());
//从一个字符串中获取枚举的值
stu.Gender=(Genders)(Enum.Parse(typeof("Genders"),"Female"));
Console.WriteLine("您输入的性别是{0}",stu.Gender.ToString());
//枚举类型转换:(枚举类型--强转)(枚举类型转换(要转换的枚举类型,“要转换为枚举类型的字符串”))—Enum.Parse()方法,关键字typeof()—(Genders)(Enum.Parse(typeof("Genders"),"Female"));
}
3,用过的枚举:
MessageBox相应的DialogResult就是个枚举
枚举的主体中不可以定义方法和属性。
3.1.3:结构——不是“类”
1,结构的定义
访问修饰符 struct 结构名
{
定义结构成员
}
定义结构时的数据字段是不能赋初始值的。
2,结构的使用
可以不用new直接定义,但必须为结构的成员复初值,直接用结构的名字访问成员。
解释:结构有一个无参的构造函数,固而我们使用结构时可以不用new关键字,可以重载有参数的构造函数,使用构造函数的方法与类相同,通过new关键字实现的。
注意:结构有默认的无参构造函数,但不可以显式的写出来,可以添加带参的构造函数。没有重载无参的构造函数时可以直接声明就使用,因为结构默认一定有一个无参的构造函数。
?问:倘若给结构定义一个有参的构造函数时,还可以直接声明并使用吗?
答案:可以??——方法的重载
3.2::理解c#中的值类型和引用类型
3.2.1: 值类型:源于System.ValueType家族,每个值类型的对象都有一个独立的内存区域保存自己的值。值类型的变量总是包含着自身的变量,包括基本数据类型,结构类型,枚举类型等。
3.2.2: 引用类型:源于System.Object家族,存储对值得引用,两个不同的引用变量指向了同一个内存中的物理地址。引用类型的变量赋值只复制对象的引用,而不复制对象本身。主要包括:类类型,接口类型。
3.2.3:装箱和拆箱
值类型(基本数据类型,枚举,结构)——装箱(隐式)——》引用类型(类,对象)
值类型(基本数据类型,枚举,结构)《——装箱(显式)——引用类型(类,对象)
注意:拆箱时,所定义的值类型和引用类型的数据类型要一致,类型错误,引发异常。
3.2.3:不同类型的参数传递
1,值方式参数传递
1,值类型参数:程序不修改参数的值;
2,引用类型参数:当类作为参数,被修改时可能修改类成员的值;
2,引用方式参数传递(用ref修饰参数)
Ref方式传递两种类型没有区别,都会保存方法中的修改。
3.2.4:细分值类型和引用类型

3.3:在类中使用索引器
3.3.1索引器的使用:
public Student this[int  index]
{
get{return students[index]}
}
public Student this[string name]
{
get
{
int i;
bool found=false;
for(i=0;i<students.Length;i++)
{
If(studnets[i].Name==name)
{
found=true;
break;
}
}
If(found)
{
Return students[i];
}else
{
Return null;
}
}
}
3.3.2索引器的特点及其应用:
定义一个索引器的时候,要使用this关键字,而get和set访问器也类似于属性。索引器和数组属性有些类似,但数组只能通过下标(索引)访问,而索引器可以通过重载它,从而自定义它的访问方式。
3.4:使用类图描述类和类成员
类图——一种表示类的构成与类和类之间关系的图表。(私有成员会在图标的左下方有一个“小锁”)
通用的类图格式,使用于所有的面向对象语言。在类图中,字段属性放在方法前面,变量类型和返回类型在冒号后面,私有成员前加一个“—“号,公有成员则是加”+“号。

小结:
常量:在程序中不能被修改,适用于经常使用,且不能改变的数据。
枚举:是一组指定的常数,可以用描述性的名称表示,对可能值进行约束。
结构:轻量级的类,使用时可以不用new ,可以有构造函数,但不能添加无参的构造函数,系统已经提供。
类是引用类型,结构是值类型。类中一般有大量的逻辑操作,结构中大多数情况下是一些数据和基本计算。
值类型转换为引用类型称为装箱,反之则称为拆箱。
引用方式(ref方式)传递值类型和引用类型的参数,程序中发生改变都保留修改。值类型传递引用类型的参数也会被修改,但值类型参数不会被修改。
索引器可以使用索引访问,也可以自定义方式访问。
类图是表示类的结构和类与类之间关系的图表。

----------------------------------------------------------------------------------------------------------------------

四:用集合组织相关数据
4.1::集合概述
复习:数组:一组具有相同类型和名称的变量的集合,可以通过索引(下标)来访问数组中的元素。一旦数组元素完成初始化工作,要在程序中动态添加和删除某个元素非常困难。
4.1.1ArrayList(数组列表):
ArrayList类来自于System.Collections命名空间,(在使用前需要引入这个命名空间),类似于数组,索引会根据你的扩展而重新进行分配和调整,实现对集合的动态访问,定义时可以指定容量也可以不指定容量。(ArrayList只提供一维的形式)
1,给ArrayList添加元素
ArrayList添加元素的方法是Add(Object value),参数是要添加的元素,该方法用于将对象插入到ArrayList集合的末尾处。
public int Add(Object  value),如果元素是值类型则会被转换为object引用类型然后保存。固,ArrayList中的所有元素都是对象的引用。
ArrayList的属性Count,用于获取集合元素的数目。
2,存取ArrayList中的单个元素
注意:ArrayList添加元素时可以添加任何对象,当添加到ArrayList中会转换为Object类型,所以在访问这些元素是必须把它们转换为本身的数据类型。
例如:Student stu1=(Student)students[0];
3,删除ArrayList中的元素
3种方式:RemoveAt(int index)方法删除指定index的元素,Remove(object value)——指定对象名的元素,Clear()——移除集合中所有的元素。
ArrayList添加删除元素都会使剩余元素的索引自动改变。
4,遍历ArrayList中的元素
//for循环遍历
For(int  i=0;i<student.Count;i++)
{
Student stuFor=(Student)students[i];
Console.WriteLine(stuFor.Name);
}
//foreach循环遍历
Foreach(Object stuo in students)
{
Student stuForeach=(Student)stuo;
Console.WriteLine(stuForeach.Name);
}
5,常见错误
1,stuent为结构类型
//遍历每个对象并给年龄赋值
foreach(student  stu  in  student)
{
student myStudent =(student )stu;
myStudent.Age=60;
}
//再遍历将每个对象的年龄显示
foreach(student  stu  in  students)
{
Console.WriteLine(stu.Age);
}
输入结果为:20,20,20而不是60,60,60。
原因:student 是值类型,在方法中给其赋值并不能将其改变保留下来。
2,对象的值相等——同一个对象是不同的
Student scofield=new Student("Scofield",Genders.Male,28,"越狱");
Student stu2=new Student("Scofield",Genders.Male,28,"越狱");
students.Remove(stu2);
结果:ArrayList中的元素没有被删除。——》第七章,关于Equals方法的重载。
3,通过RemoveAt()方法删除集合中的元素
students.RemoveAt(0);
students.RemoveAt(1);
students.RemoveAt(2);
结果:运行后发生异常,原因:ArrayList的索引会自动分配和调整。(集合中一共只有3个元素)
4.1.2HashTable:
ArrayList可以通过索引器用索引获得相应的值,而HashTable也可以做到。
1,给HashTable添加元素
HashTable属于System.Collections命名空间,每个元素都是一个键值对,添加对象使用Add()方法。
pbulic void Add(Object key,object value)
2,获取HashTable的元素
直接通过键名来获取具体值(由于值的类型是Object类型,固当得到一个值时也需要通过类型转换得到正确的类)
3,遍历HashTable
HashTable不能通过索引访问,所以遍历HashTable只能用foreach()方法。
//元素遍历
foreach(Object stuo in students.Values)
{
Student stu=(Student)stuo;
Console.WriteLine(stu.Name);
}
System.Values 属性用来获取哈希表中所有的值,System.Keys属性遍历出所有的键值。
4,删除HashTable的元素
public void Remove(Object key)
通过key,使用Remove()方法删除哈希表的元素。可以通过Clear()方法清除所有元素,用法和ArrayList相同。
注意:HashTable和ArrayList在存储对象是队会转换为Object类型,但取出时倘若不进行相应的类型转化会出现异常。(传统的ArrayList和HashTable集合认为每个元素都是Object类,在添加时不会做严格的检查)
4.2:泛型和泛型集合
4.2.1泛型:
应用,创建集合类——典型:List<T>,Dictionary<K,V>,。特点:性能高(无需拆箱装箱的操作),类型安全。
4.2.2泛型集合List<T>:
许多泛型集合类定义于System.Collections.Generic命名空间中,可以用于代替前面的ArrayList和HashTable.
语法:
List<Student> students=new List<Student>();
"<T>"中的T可以对集合中的元素类型进行约束,T表明集合中管理的元素类型。(注意:泛型集合必须实例化,实例化是要在后面加上“()”)。
4,,2,3泛型集合Dictionary<K,V>:
Dictionary<K,V>,具有泛型的全部特征,编译时检查类型约束,获取元素时无需类型转换,存储方式和哈希表类似,通过Key/Value键/值对保存元素。
Dictionary<string  ,  类类型> =new Dictionary<string  ,   类类型>();
Dictionary<K,V>和HashTable的异同点同上List<T>和ArrayList的区别,只是相同点多了一条:通过Key获取Value;
4,2,4泛型总结:
解决繁琐的操作问题,提供更好的类型安全性,CLR可以支持泛型。
4.3:综合实践
C#中的时间间隔类型TimeSpan;

本章小结:
哈希表类似于生活中的字典,元素都以键/值对存在,访问哈希表的元素需要类型转换,遍历哈希表时只能遍历它的Value,而不是整个元素,不能通过索引访问,只能通过键访问值。
泛型集合可以作为类中的一个属性,使用泛型集合必需实例化。

----------------------------------------------------------------------------------------------------------------------


五 文件读写与 XML
1如何读写文件 ?创建一个文件流,创建阅读器或者写入器,执行读写操作,关闭读写器,
关闭文件流
2 引入命名空间:using System.IO;
写文件
FileStream fs=new FileStream(要操作的文件,写入方式);
StreamWriter sw=new StreamWriter(fs);
sw.Write(内容);//记录写入的流,流是我们已经创建好的内容
sw.Close();
fs.Close(); 


直接写入方式
StreamWriter sw=new StreamWriter(要操作的文件);
sw.Write(要写的文件);
sw.close();
读文件
FileStream fs=new FileStream(要操作的文件,写入方式);
StreamReader sr=new StreamReader(fs);
string content=null;
content=sw.ReadToEnd();
  txtContent.Text=content;
sr.Close();
fs.Close(); 
  
直接读取
StreamReader sr=new StreamReader(要读取的文件(位置));
string content;
content=sr.ReadToEnd();
显示的区域=content;
sr.Close():

3 File类和 Directory类
File类
Exists(string path)  检查指定文件是否存在
Copy(源文件,目标文件)
Move(源文件,目标文件)
Delete(string path) 删除指定文件
 
Directory类的方法

Exists(string path)
Move(源文件,目标文件)
Delete(string ,bool)  删除指定目录,如果Bool为True 则删除子目录中的所有内容。

4 静态类与非静态类的异同
在使用File 类和 Directory 类的方法时,都不需要实例化,直接 类名.方法()
静态类是指包含静态方法的。
静态类                非静态类
用static 修饰  
只包含静态成员  可以包含静态成员
不可以包含实例成员 可以包含实例成员
使用类名调用静态成员 使用实例对象调用非静态成员
不能被实例化  可以被实例化
不可以包含实例构造函数 包含实例构造函数



5 XML(eXtensible Markup Language) 概述
特点:用于描述数据的各个节点可自由的扩展
       节点区分大小写
       节点是成对出现的,用来描述这个节电存储的内容

6读取xml文件
XmlDocument myxml=new XmlDocument();
myxml.load("xml文件");
XmlNode node=myxml.DocumentElement; //获得根节点
foreach(XmlNOde mynode in node.ChildNodes)
{
  switch(mynode.Name)
  {
   case "xml文件中的节点":
   break;
  }
}


XmlDocument 属性和方法:
DocumentElement 获得根节点
ChildNodes 获取所有子节点
Load() 读取整个Xml的结构

XmlNode 属性和方法
InnerText  当前节点的值
Name 当前节点的名字
ChildNodes 当前节点的所有子节点
 

小结:文件读写和xml
5.1:文件
5.2::新闻阅读器工作原理概述
5.3:操作XML实现抓取新闻功能



六  继承(提取公共的部分,减少代码冗余,方便其他同类的使用)
1 继承要符合 is-a 关系 ,子类是父类

2 三种修饰符 protected 允许被子类访问,而不允许其它类的访问
 
修饰符  类内部  子类  其他类
public   可以  可以  可以
private   可以  不可以  不可以
protected   可以  可以  不可以

4 this 表示当前实例, base表示父类

5继承的特性(传递性,单根性,密封性(用sealed修饰的类将不能被继承,称密封类))

6继承注意的事项 1.隐式调用父类构造函数 2.显示调用父类构造函数

7 继承的价值
模拟了现世界之间的关系 ,实现了代码的重用性,使程序结构清晰.

小结:用对象思考:继承
6.1继承概述
6.2继承的使用
6.3综合实战

七 多态
1 多态:对同一个方法做出的不同相应方式

2 抽象方法是没有实现的方法
  语法  :  访问修饰符  abstract 返回类型 方法();   //注:抽象方法没方法体
    访问修饰符  abstract  class 类名
3 抽象类不能被实现 ,实现抽象方法的方式是使用 override 关键字重写抽象方法
实现时不能改变抽象方法的修饰符,抽象类不能用sealed 和 static 修饰
10 里氏替换原则是指父类的方法都要在子类中实现或者重写
11 is 操作符  作用:检查对象是否与给定的类型相同. if(a is string){}
12 as 操作符的使用 作用:强制类型转换 例:a as studnt;
13 使用虚方法(virtual)实现多态
  访问修饰符 virtual 返回类型 方法(){}
虚方法可实现也可不实现  实现虚方法必须要使用 override 修饰 叫方法重写
若无virtual 修饰实现的方法,则会报错! 若在重写时出现下划线(new)则表示是否隐藏。
14 面向对象的三大特性:封装,继承,多态

15 虚方法和抽象方法
虚方法   抽象方法
用virtual修饰  用abstract 修饰
有方法体,哪怕一个分号 不允许有方法体
可以别子类override 必须被子类override
除了密封类外都可以写 只能在抽象类中。

16. 现使用的多态是利用抽象方法和抽象方法实现的。子类实现抽象方法时按自己所需实现,父类用abstract修饰。

小结:用对象思考:多态
7.1面向对象的多态性
7.2使用抽象类和抽象方法是实现多态
7.3使用虚方法实现多态
7.4简单工厂设计模式

八    接口

1.泛型集合中的sort()默认方法是按英文字母升序.
2.若要指定泛型集合具体某列的排序则要实现ICompareable接口 或 使用 IComparer<T> 泛型接口
3.IComparable 接口 
  public interface IComparable
  {
   int CompareTo(object obj);
  }
如果返回值小于0,则当前实例小于obj
如果返回值等于0,则当前实例等于obj
如果返回值大于0,则当前实例大于obj

简洁写法:
  public int CompareTo(object obj)
  {
   return this.age.CompareTo(obj.age);
  }
4.泛型接口 IComparable<T>
  语法:public void Sort(IComparer<T> comparer)

实例用法:
  publc class NameCompareDesc:IComparer<student>
  {
   public int Compare(student x,student y)
   return (y.name.CompareTo(x.name))
  }
调用时要使用实例的对象 sort(new NameCompareDesc);

小结:用对象思考:接口
8.1接口
8.2泛型接口
8.3接口的典型应用

九:序列化与反射
9.1序列化和反序列化
9.2程序集和反射

深入.net平台和c#编程 学习笔记