深入.NET框架以及面向对象的特性

.NET框架

1、简介

由微软公司由2000年发布,.NET框架是开发.NET应用程序的核心基础,.NET框架经历了1.0、1.1、2.0、3.0、3.5、4.0、4.5七个版本,我这里介绍的是4.0以上的版本。

2、功能性

.NET框架提供了一个面向对象的编程环境,完全支持面向对象编程。.NET框架提高了软件的可复用性、可扩展性、可维护性和灵活性。对Web应用的强大支持。

3、结构组成

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

3.1、CLR

CLR可以看成一个在执行是管理代码的代理,管理代码是CLR的基本功能,能够被其管理的代码称为托管代码,反之称为非托管代码。CLR包含两个重要的组成部分:CLS(公共语言规范)和CTS(通用类型系统)。

3.1.1、.NET的编译技术

所有在.NET编写的代码都会通过他们各自的编译器编译成MSIL:俗称中间语言,可被平台(操作系统)识别,从而进行编译。这种编译方法不但实现了代码托管,还提高了程序的运行效率。

3.1.2、CLS(公共语言规范)

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

3.1.3、CTS(通用类型系统)

用来解决不同语言数据类型的不同的问题。

3.2、框架类库

FCL提供了对系统功能的调用,是建立.NET应用程序、组件和控件的基础。在使用FCL时会导入自己所需要的命名空间

C#语言的基本

一、C#的面向对象

1、类和对象

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

2、类的成员

C#中类有三个成员,分别为:字段、属性和方法

字段:字段是类的私有成员变量

属性:就是私有字段进行公有化

  1. 只写属性:只包含set访问器
  2. 只读属性:只包含get访问器
  3. 读写属性:同时包含set访问器和get访问器
private  string _name; //私有字段
public string Name
{
 		get {return _name;} //获取值
		set {_name=value;} //赋值
}

方法:

语法:

访问修饰符 返回值类型 方法名(有参/无参)
{
    return 返回值;
}

有参方法的参数传递

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

总结

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

3、深入C#的数据类型

3.1、结构

关键字:struct

1、结构的语法

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

2、结构的定义有以下的特点

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

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

  • 可以不用new,直接定义结构的对象即可
  • 声明结构后,必须给结构的成员赋初值
  • 并且不能手写无参构造函数

4、结构是值类型,用的越多系统的存储空间消耗的也越多

3.2、值类型

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

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

3.3、引用类型

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

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

4、装箱和拆箱

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

  • 装箱:将值类型转换为引用类型的过程叫装箱。
  • 拆箱:将引用类型转换为值类型叫拆箱。
static void Main(string [] args)
{
	int i=123; 
	object o=i;  //装箱
	int j=(int)o;  //拆箱
}

二、集合

集合的概念:大小可变的动态数组。

以下介绍的都是集合。

泛型的概念

泛型限定了数据类型非泛型没有限定数据类型

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);
}
2、泛型集合

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

2.1、 List< T >
List<T> 对象名=new List<T>();

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

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

​ List与ArrayList的区别:

List< T >ArrayList
不同点对所保存元素进行类型约束可以增加任何类型
添加/读取值类型元素无须拆箱和装箱添加/读取值类型元素需要拆箱和装箱
相同点通过索引访问集合中的元素
添加元素方法相同
删除元素方法相同
2.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. 实现代码的重用性

三、深入类的方法

构造函数

构造函数的用处:用于new对象、可以给成员变量赋值

兼职:用于给成员变量赋值

构造函数具有以下特点:

  • 方法名和类名相同
  • 没有返回值类型
  • 主要完成对象的初始化工作
1、无参构造函数

定义无参构造函数的语法:

访问修饰符 类名()
{
	//方法体
}
2、带参构造函数

一般来讲,给方法设置参数可以调整方法的行为,使方法多样化。构造函数的参数列表一般用于给属性赋值。

定义有参构造函数的语法如下:

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

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

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

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

构造函数在每次实例化类的时候通过new关键字调用

四、类的三大特性

1、封装

封装:使内部结构私有化

封装的魅力:

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

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

2、继承

子类具有父类的属性和方法,被继承的类称为父类或基类,继承其他类的被称为子类或者派生类

继承是使用已经存在的类的定义作为基础建立新类的技术,新类的定义可以增加新的数据或新的功能,也可以用已存在的类的功能

在有继承关系的两个类中,子类不仅具有自己独有的成员,还具有父类的非private成员

2.1、base关键字

创建子类时会先调用父类的构造函数,默认会调用父类的无参构造函数。

使用base关键字就可以显示的调用父类的构造函数。只要在子类的构造函数后添加":base(参数列表)",就可以指定子类调用父类的哪一个构造函数了。

2.2、继承的特性:

传递性:

继承具有传递性,就相当于遗传,一个类可以有很多代。

单根性:

一个子类只能存在一个父类,这就是继承的单根性。

C#中还有一个特殊的关键字:sealed,使用它修饰的类不能够被继承,我们称这种类为继承类。

2.3、is a 和as a

is a:

用来判断对象是否属于给定的类型,是就返回true,不是就返回false。例如:

string str = "";
if(str is string)   //会返回true
{
	Console.WriteLine("str是string类型的")   //会输出
}
else
{
	Console.WriteLine("str不是string类型的")  //不会输出
}

as a:

用来强制转换数据类型,转换失败会返回null,并不会报异常。使用的时候需要注意,用法与is a相仿。

2.4、里氏替换原则

概念:里氏替换原则是软件设计应该遵守的重要原则之一,指所有引用父类的地方,都可以透明的使用子类对象

通过is a和as a可以体现里氏替换原则。

2.5、继承的价值

1、继承模拟了现实世界的关系 ,符合面向对象的思想

2、继承提高了代码的重用性,子类拥有父类的属性和方法

3、提高了代码的可扩展性,子类形似父类,也异于父类,保留自我个性。

3、多态

一个对象的多种形态,实现方式:重载+重写

3.1、重载

在面向对象的语言中,允许我们在同一个类中定义多个方法名相同,参数列表(参数个数,参数类型)不同的方法,称为方法重载。调用时会根据实际传入参数的形式,选择与其匹配的方法执行。

重载的特点

  1. 在同一个类中;
  2. 方法名相同;
  3. 方法参数类型不同或者参数个数不同;

注意:方法名以及参数列表相同的方法,仅是返回值类型不同,不能称为方法重载

方法重载示例:

public void Show()
{
    Console.WriteLine("Hello World");
}
public void Show(string name)
{
    Console.WriteLine("我的名字是:{0}"+name)
}

以上示例就是方法重载的使用

3.2、重写

特点:

不同的类中、相同的方法名、相同的参数、在有继承关系的两个类中

实现方式:

3.2.1、虚方法

父类的方法使用virtual关键字修饰,语法如下:

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

子类重写的方法使用override关键字修饰,语法如下:

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

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

3.2.2、抽象方法

父类的方法使用abstract关键字修饰,语法如下:

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

子类重写的方法使用override关键字修饰,语法如下:

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

抽象方法必须位于抽象类中,并且没有方法体。规定子类必须重写父类的抽象方法(除非子类也是抽象类)。

**虚方法和抽象方法的区别:**如下表所示

虚方法抽象方法
用virtual修饰用abstract修饰
要有方法体,即使是一个分号不允许有方法体
可以被子类override必须被子类override
除了密封类外都可以定义只能在抽象类中定义
3.2.3、抽象类

语法如下:

访问修饰符 abstract class 类名{}

**注意:**抽象类不能被实例化,并且不能是密封的或者静态的。

4、总结

封装:保证对象自身数据的完整性和安全性

继承:建立类之间的关系,实现代码复用,方便系统的扩展

多态:相同的方法调用可实现不同的实现方式

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值