深入.NET框架和C#编程(一)

深入.NET框架和C#编程

一.深入.NET框架

1.1NET框架的体系结构

NET框架结构:

.NET框架运行在操作系统之上,是.NET最基础的框架,主要包含公共语言运行时(CLR)和框架类库(FCL)。

(1)公共语言运行时(CLR):

它是所有.NET应用程序运行时的环境,是所有.NET应用程序都要使用的编程基础,它如同一个支持.NET应用程序运行和开发的虚拟机。

MSIL:俗称中间语言,可被平台(操作系统)识别,从而进行编译

CLR包含两个组成部分:

  1. CLS(公共语言规范)
  2. CTS(通用类型系统)

CLS:编程语言区别不仅在于类型,语法或者语言规范都有很大的区别,CLS限制了不同点引发的互操性问题。

CTS:用来解决不同语言数据类型的不同的问题;

(2)框架类库(FCL)

就是指平常要引用的那些命名空间,.NET框架提供了非常丰富实用的类库。

1.2.面向对象回顾

1.2.1类和对象

类和对象有着本质的区别,类定义了一组概念的模型(抽象的),而对象是真正的实体。

①由对象归纳为类,是归纳对象共性的过程。

②在类的基础上,将状态和行为实体化为对象的过程称为实例化。

属性:

  1. 只写属性:只包含set访问器
  2. 只读属性:只包含get访问器
  3. 读写属性:同时包含set访问器和get访问器
private  int _id;
public int ID
{
    get {return_id;}
	set {_id=value;}
}
1.2.2封装

封装:使内部结构私有化

封装的魅力:

  • 保证数据的安全性
  • 提供清晰的对外接口
  • 类内部实现可以任意修改,不影响其他类

将字段封装为属性是封装的一种方式,类的私有方法也是一种封装。

1.2.3类图

在软件开发中,软件的规模一般都很大,一行行阅读是非常困难的,在面向对象编程中,我们经常使用类图来解决这个问题。类图将类的属性和行为以图的行为展示出来,使读者不用阅读大量的代码就可以知道类的功能及类之间的关系。

私有成员: “-”,公有成员:“+”;也有私有成员在右下角有“”标志

类图是表示类的结构及类与类之间关系的图表。

二.深入C#数据类型

1.值类型和引用类型

1.值类型

值类型源于System.ValueType命名空间,值类型数据所在的区域称为 “栈”,只要修改它,就会在它的内存区域内保存这个值,值类型主要包括的基本数据类型 :

int, long, float, double, char, bool, bool,enum, struct

2.引用类型

引用类型源于System.Object命名空间,在C#中引用类型主要包括 :

类(Class),数组,集合,接口

2.1 结构

1,结构的语法

访问修饰符  struct  结构名
{
      //结构体
}

2,结构的定义有以下的特点:

  • 结构中可以有字段,也可以有方法;
  • 定义时,结构中的字段不能被赋初始值;

3,在使用结构时要注意以下几个方面:

  • 可以不用new,直接定义结构的对象即可;
  • 声明结构后,必须给结构的成员赋初值;
1.1装箱和拆箱

我们说数据类型按照储存方式可以分为值类型和引用类型,两者可以互相转换。

  • 装箱:将值类型转换为引用类型的过程叫装箱。
  • 拆箱:将引用类型转换为值类型叫拆箱。
static void Main(string [] args)

{

  int i=123; 
//装箱
object o=i;  
//拆箱
int j=(int)o;  

}

2.参数传递

  1. 值传递:在方法中对参数值的更改在调用后不能保留;
  2. 引用传递:地址不变,可以保留对参数值的更改
  3. 使用ref传递:可以保留对参数值的更改;

总结

  1. 使用值方式(不用ref修饰)传递值类型参数时,参数在方法中的修改不会保留;
  2. 使用值方式(不用ref修饰)传递引用类型参数时,参数在方法中的修改会保留;
  3. 使用引用方式(用ref修饰)传递值类型或引用类型参数时,参数在方法中的修改都会保留;

三.使用集合组织相关数据

1.非泛型

1.1.ArrayList

ArrayList非常类似于数组,也有人称它为数组列表,ArrayList可以动态维护,一般数组的长度都是固定的,而ArrayList的容量可以根据需要自动扩充,它的索引会根据程序的扩展而重新分配调整.

ArrayList类属于System.Collections命名空间,这个命名空间包含接口和类;

ArrayList常用的方法和属性:

属性名称说明
Count获取ArrayList中实际包含的元素数
返回值类型方法名称说明
intAdd(Object value)将对象添加到ArrayList的结尾处
voidRemoveAt(int index)移除ArrayList指定的索引元素
voidRemove(Object value)从ArrayList中移除特定元素
voidClear()移除所有元素

遍历ArrayList中的元素

ArrayList array = new ArrayList();

foreach(Object item in array)
{
    Console.WirteLine(item);
}
1.2.Hashtable

C#提供了一种称为Hashtable的数据结构,通常称为哈希表,Hashtable的结构是通过键(Key)和值(Value)来组织的

Hashtable也属于System.Collections命名空间,它的每一个元素都是一个键/值对;

Hashtable的常用属性和方法:

属性名称说明
Count获取包含Hashtable中键/值对的数目
Keys获取包含在Hashtable中键的集合
Values获取包含在Hashtable中值的集合
返回值类型方法名称说明
voidAdd(Object key,Object value)带有指定键和值的元素添加到Hashtable
voidRemove(Object key)从Hashtable中移除带有特定键的元素
voidClear()从Hashtable中移除所有元素

遍历Hashtable中的元素

Hashtable<K,V> array = new Hashtable<K,V>();
//遍历所有的key
foreach(Object item in array.Keys)

{
	Console.WirteLine(item);
}
//遍历所有的Value
foreach(Object item in array.Values)

{
	Console.WirteLine(item);
}

3.泛型和泛型集合

泛型引入了一个概念:类型参数。通过使用类型参数(T),减少了运行时强制转换或装箱操作的风险,比较经典的泛型集合是List和Dictionary<K,V>。

3.1. List<>
List<T> 对象名=new List<T>();

""中的T可以对集合中的元素类型进行约束,T表明集合中管理的元素类型;

List的使用方法和ArrayList类似,只是List无须类型转换;

​ List与ArrayList的区别:

ListArrayList
不同点对所保存元素进行类型约束可以增加任何类型
添加/读取值类型元素无须拆箱和装箱添加/读取值类型元素需要拆箱和装箱
相同点通过索引访问集合中的元素
添加元素方法相同
删除元素方法相同
3.2.Dictionary<K,V>
Dictionary<K,V> 对象名=new Dictionary<K,V>();

说明:<K,V>中K表示集合中Key的类型,V表示Value的类型

例如:

Dictionary<string,SE> eng=new Dictionary<string,SE>();

eng集合的Key类型是string型,Value是SE类型;

​ Dictionary<K,V>和Hashtable的对比:

Dictionary<K,V>Hashtable
不同点对保存元素进行类型约束可以增加任何类型
添加/读取值类型元素无须拆箱和装箱添加/读取值类型元素需要拆箱和装箱
相同点通过Key获取Value
添加元素方法相同
删除元素方法相同
遍历方法相同

3.泛型类

使用泛型类,可以封装不是特定于具体数据类型的操作。定义泛型类的过程,与定义一个类相似,不同之处在于,尖括号里定义了类型参数;

public class 类名<T>
{
	//.....
}

T指类型参数,代表具体的数据类型,可以是类类型,也可以是基本数据类型。

泛型有以下优点:

  1. 性能高

  2. 类型安全

  3. 实现代码的重用

  4. 可以选择自己想用的数据类型

四.深入类的方法

1.构造函数

构造函数的用处

用于new对象。兼职:用于给成员变量赋值

构造函数具有以下特点:

  • 方法名和类名相同
  • 没有返回值类型
1.1无参构造函数

在默认的情况下,系统会给类分配一个隐式无参构造函数,并且没有方法体;

访问修饰符 类名()
{
	//方法体
}

也可以自定义无参构造函数(显式);

1.2带参构造函数(显式)

一般来讲,给方法设置参数可以调整方法的行为,使方法多样化。同样,构造函数也可以接收参数,用这些参数给属性赋值。语法如下:

访问修饰符  类名(参数列表)
{
	//方法体
}

在调用带参函数时需要注意的几点:

  • 参数的个数要对应
  • 参数的数据类型要一一对应;

2.方法重载(多态)

在面向对象的语言中,允许我们在同一个类中定义多个方法名相同,参数列表(参数个数,参数类型)不同的方法,称为方法重载;

方法重载的特点

  1. 在同一个类中;
  2. 方法名相同;
  3. 方法参数类型不同或者参数个数不同;
class PM
{  
    public void Show()
    {
        Console.WriteLine(" ");
    }
    
    public void Show(string name)
    {
        Console.WriteLine("名字是:{0}"+name)
    }
}

3,对象交互

在面向对象的世界里,一切皆为对象,对象与对象相互独立,但在一定外力的作用下,对象开始共同努力;

每个类都有自己的特性和功能,我们把它封装为属性和方法。对象之间通过属性和方法进行交互,可以认为方法的参数及方法的返回值都是对象间相互传递的信息。

六,初识继承和多态

1.继承的概述

1.1什么是继承

简单来说,继承就是子承父

生活中最简单的继承关系:

汽车(父类,基类

卡车和公共汽车(子类,派生类

1.2base关键字和protected修饰符
1.2.1base关键字

在子类中使用,可以调用父类的属性,还可以用base关键字调用父类的方法及父类的构造函数。

public class Employee
{
	public string Name{get; set;}
}
public class PM:Employee
{
	Console.WriteLine("名字是",base.Name)
}
1.2.2访问修饰符的限制:
修饰符类内部子类其他类
public可以可以可以
private可以不可以不可以
protected可以可以不可以

小结:子类可以调用父类的所有非private成员

1.3继承中构造函数

注意:每一个子类的构造函数一定会调用父类的构造函数

  • 没有明确指明,或使用:base()则调用父类的无参构造函数
  • 若使用:base(实参),则明确指明父类中的某个构造函数(根据参数个数以及类型)

2.继承的使用

2.1 继承的特性

注意:当类被sealed修饰时,该类为密封类,不允许被继承

2.1.1.继承的传递性:

正如人类有爸爸,也有爷爷

汽车有子类卡车,而卡车又可以有子类小型卡车,大型卡车

可以说汽车也是小型卡车,大型卡车的父类

此所谓继承的传递性

2.1.2继承的单根性:

假设某个人既有程序员的天赋,又有音乐家的气质,但是在C#中是不能明确规定的,一个子类不能提示继承多个类。

2.2 is a 的应用
if(emp is SE)
{
	Console.WriteLine(((SE)emp).Sahi());
}
if(emp is PM)
{
	Console.WriteLine(((PM)emp).Sahi());
}

在上列代码中使用 is 关键字,这个关键字用来判断对象是否属于给定的类型,如果属于则返回true,否则返回false;

2.3继承的价值

①继承模拟了现实世界的关系,OOP中强调一切皆为对象,这符合我们面向对象编程的思考方向。

②继承实现了代码的重用,合理的使用继承,会使代码更加简洁。

③继承使得程序结构清晰,子类和父类的层次结构清晰。

3.继承的优点
  1. 提高代码的重用性
  2. 形似父类,异于父类,保持个性
4.继承的缺点
  1. 继承编程侵入式
  2. 增加耦合

3.多态

3.1 虚方法

我们可以在父类和子类中定义如下的方法:

public virtual string Sayi()  //在父类中使用关键字virtual
{
	//省略方法体
}
public override string Sayi()  //在子类使用时是有关键字override
{
	//省略方法体
}

像这种virtual关键字修饰的方法,称为虚方法,虚方法有方法体,语法如下:

访问修饰符 virtual 返回值类型 方法名()//父类
{
	//方法体
}
访问修饰符 override 返回值类型 方法名()//子类
{
	//方法体
}

父类中定义的虚方法并非必须被子类重写,在父类中可以给出虚方法的默认实现。如果子类不重写父类的虚方法,依然执行父类的默认实现,如果子类重写了父类的虚方法,执行子类重写后的方法。

虚方法的特点

前提:两个类有继承关系

  1. 不同类
  2. 相同的方法名
  3. 相同的参数(个数,类型)
  4. 子类可以不重写父类方法

子类调用父类

根据方法名与参数调用,而不根据访问修饰符和返回值类型

七,深入理解多态

1.里氏替换和多态应用

1.1 里氏替换概述

子类对象可以赋给父类对象,也可以说子类可以替换父类,并且出现在父类能够出现的地方,且程序的行为不会发生变化,但是反过来,父类对象是不能够替换子类对象的,这种特性被称为:“里氏替换原则”;

“里氏替换原则”:是软件设计应该遵守的重要原则之一,有了里氏替换原则,才使继承复用成为可能。

小结引用父类的地方,都可以透明的使用子类对象

1.2 is 和 as操作符的使用

is操作符用于检查对象和指定的类型是否兼容,而as操作符用于对象之间的类型转换:

if(emp[i] is SE)
{
	PM pm=emp[i] as PM;
}

先用 is 关键字判断员工类,再用 as 关键字将此员工对象转换为对应的的类。

里氏替换原则提出子类对象可以替换父类对象,在编写时以父类类型作为形式参数的方法,在实际调用时传入子类对象。

2.抽象类和抽象方法

2.1为什么使用抽象类和抽象方法

抽象方法是一个没有实现的方法,通过在定义方法时增加关键字 abstract 可以声明抽象方法,其语法如下:

访问修饰符  abstract 返回类型 方法名();

注意:抽象方法没有闭合的大括号,而是直接跟一个分号 “:”也就是说,它没有包括方法执行逻辑的方法体。

1.含有抽象方法的类必然是抽象类,同样,我们用关键字 abstract 来定义一个抽象类,语法如下:

访问修饰符 abstract class 类名{}
2.2 抽象类和抽象方法的应用

1.如何实现抽象方法

从一个抽象父类派生一个子类时,子类将继承父类的所有特征,包括它未实现的抽象方法。抽象方法必须在子类中实现,除非它的子类也是抽象类,与子类重写父类的虚方法一样,在子类中也是使用 “override”关键字来重写抽象方法。

访问修饰符 override 返回类型 方法名();

举例一个示例:

public abstract class SE
{
	public abstract void Run(); //抽象方法不能有方法体
}

public void PM:SE
{
	public override void Run(){}  //继承SE的Run方法
}
2.3抽象方法的特点:
  1. 在不同的类中
  2. 有相同的方法名
  3. 相同的参数
  4. 没有方法体
  5. 抽象方法只能位于抽象类中
  6. 父类里面的抽象方法子类必须实现,用关键字 override(除非子类也是抽象类)
2.4抽象类特点
  1. 不能new对象
  2. 不能用sealed和static修饰
  3. 可以有抽象方法,也可以有普通方法
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值