c#基础

1.C#中类(class)与结构(struct)的异同

1>.值类型与引用类型

结构Struct是值类型:值类型在堆栈上分配地址,所有的基类型都是结构类型,例如:int   对应System.int32   结构,string   对应   system.string   结构   ,通过使用结构可以创建更多的值类型

类Class是引用类型:引用类型在堆上分配地址

堆栈的执行效率要比堆的执行效率高,可是堆栈的资源有限,不适合处理大的逻辑复杂的对象。所以结构处理作为基类型对待的小对象,而类处理某个商业逻辑

因为结构是值类型所以结构之间的赋值可以创建新的结构,而类是引用类型,类之间的赋值只是复制引用

1.)虽然结构与类的类型不一样,可是他们的基类型都是对象(object),c#中所有类型的基类型都是object

2.)虽然结构的初始化也使用了New   操作符可是结构对象依然分配在堆栈上而不是堆上,如果不使用“新建”(new),那么在初始化所有字段之前,字段将保持未赋值状态,且对象不可用

2>继承性

结构:不能从另外一个结构或者类继承,本身也不能被继承,虽然结构没有明确的用sealed声明,可是结构是隐式的sealed   .

类:完全可扩展的,除非显示的声明sealed   否则类可以继承其他类和接口,自身也能被继承

3.>内部结构:

结构:

没有默认的构造函数,但是可以添加构造函数

没有析构函数

没有   abstract   和   sealed(因为不能继承)

不能有protected   修饰符

可以不使用new   初始化

在结构中初始化实例字段是错误的

类:

有默认的构造函数

有析构函数

可以使用   abstract   和   sealed

有protected   修饰符

必须使用new   初始化

 

2.虚函数(Virtual),抽象函数(abstract)和接口的区别

 

 

 

virtual(C# 参考) 
virtual 关键字用于修饰方法、属性、索引器或事件声明,并且允许在派生类中重写这些对象。例如,此方法可被任何继承它的类重写。
Code

虚拟成员的实现可由派生类中的重写成员更改。有关使用 virtual 关键字的更多信息,请参见使用 Override 和 New 关键字控制版本(C# 编程指南)和了解何时使用 Override 和 New 关键字(C# 编程指南)。
调用虚方法时,将为重写成员检查该对象的运行时类型。将调用大部分派生类中的该重写成员,如果没有派生类重写该成员,则它可能是原始成员。
默认情况下,方法是非虚拟的。不能重写非虚方法。
virtual 修饰符不能与 static、abstract 和 override 修饰符一起使用。
除了声明和调用语法不同外,虚拟属性的行为与抽象方法一样。
在静态属性上使用 virtual 修饰符是错误的。
通过包括使用 override 修饰符的属性声明,可在派生类中重写虚拟继承属性
在该示例中,Dimensions 类包含 x 和 y 两个坐标和 Area() 虚方法。不同的形状类,如 Circle、Cylinder 和 Sphere 继承 Dimensions 类,并为每个图形计算表面积。每个派生类都有各自的 Area() 重写实现。根据与此方法关联的对象,通过调用正确的 Area() 实现,该程序为每个图形计算并显示正确的面积。
在前面的示例中,注意继承的类 Circle、Sphere 和 Cylinder 都使用了初始化基类的构造函数,例如:
Code

输出    
Area of Circle   = 28.27
Area of Sphere   = 113.10
Area of Cylinder = 150.80

 

abstract 修饰符可以和类、方法、属性、索引器及事件一起使用。在类声明中使用 abstract 修饰符以指示某个类只能是其他类的基类。标记为抽象或包含在抽象类中的成员必须通过从抽象类派生的类来实现。
在此例中,类 Square 必须提供 Area 的实现,因为它派生自 ShapesClass:

Code

有关抽象类的更多信息,请参见抽象类、密封类及类成员(C# 编程指南)。
抽象类具有以下特性:
抽象类不能实例化。
抽象类可以包含抽象方法和抽象访问器。
不能用 sealed(C# 参考)修饰符修改抽象类,这意味着抽象类不能被继承。

从抽象类派生的非抽象类必须包括继承的所有抽象方法和抽象访问器的实实现。
在方法或属性声明中使用 abstract 修饰符以指示方法或属性不包含实现。
抽象方法具有以下特性:
抽象方法是隐式的虚方法。
只允许在抽象类中使用抽象方法声明。
因为抽象方法声明不提供实际的实现,所以没有方法体;方法声明只是以一个分号结束,并且在签名后没有大括号 ({ })。例如:  
C# code
public abstract void MyMethod();
实现由一个重写方法提供,此重写方法是非抽象类的成员。
在抽象方法声明中使用 static 或 virtual 修饰符是错误的。
除了在声明和调用语法上不同外,抽象属性的行为与抽象方法一样。
在静态属性上使用 abstract 修饰符是错误的。
在派生类中,通过包括使用 override 修饰符的属性声明,可以重写抽象的继承属性。  
抽象类必须为所有接口成员提供实现。  
实现接口的抽象类可以将接口方法映射到抽象方法上。例如:

Code

在本例中,DerivedClass 类是从抽象类 BaseClass 派生的。抽象类包含一个抽象方法 AbstractMethod 和两个抽象属性 X 和 Y。

Code

输出
x = 111, y = 161
在上面的示例中,如果试图通过使用下面的语句将抽象类实例化:
C# code
BaseClass bc = new BaseClass();   // Error
将出现错误,指出编译器无法创建抽象类“BaseClass”的实例。

 

接口只包含方法、委托或事件的签名。方法的实现是在实现接口的类中完成的,如下面的示例所示: 
Code
接口可以是命名空间或类的成员,并且可以包含下列成员的签名:  
方法  
属性  
索引器  
事件  
一个接口可从一个或多个基接口继承。
当基类型列表包含基类和接口时,基类必须是列表中的第一项。
实现接口的类可以显式实现该接口的成员。显式实现的成员不能通过类实例访问,而只能通过接口实例访问,例如:
有关显式接口实现的更多详细信息和代码示例,请参见显式接口实现(C# 编程指南)。
下面的示例演示了接口实现。在此例中,接口 IPoint 包含属性声明,后者负责设置和获取字段的值。Point 类包含属性实现。
Code

输出    
My Point: x=2, y=3

 

简单来说虚函数(Virtual)已经包含了也必须包含默认的实现,所以在派生类中可以重新实现也可以不实现这些虚函数。
抽象函数(abstract)没有提供默认实现,所以在派生类中必须实现这些抽象函数。
接口中的函数类似于抽象函数,也不提供默认实现,实现接口的类也必须实现这些函数。
但接口可用于多继承,即,类只能从一个类继承,但可同时实现多个接口。

抽象方法必须由派生的子类来实现
而虚方法派生的子类不一定会重写

虚方法在基类中可以有实现,但抽象方法不能。
虚方法可以在子类中不实现,但抽象方法必须在子类中全部实现。

虚方法提供了满足基本需要的代码,一般情况下不需要客户端重新写,如果满足不了,客户端可以覆盖。
抽象方法在抽象类中,通常抽象类提供模板方法的实现,模板方法需要一些接口,但是必须由客户端提供,抽象方法就是定义这些接口。

当觉得一个方法要实现什么功能,并且知道怎么实现功能的时候,用虚方法.
当知道方法要实现的功能,但对怎么实现不清楚的时候,用抽象方法

抽象方法是需要子类去实现的
虚方法,是已经实现了,子类可以去覆盖,也可以不覆盖

抽象类用于部分实现一个类,再由用户按需求对其进行不同的扩展和完善;接口只是定义一个行为的规范或规定。
抽象类在组件的所有实现间提供通用的已实现功能;接口创建在大范围全异对象间使用的功能。
抽象类主要用于关系密切的对象;而接口适合为不相关的类提供通用功能。
抽象类主要用于设计大的功能单元;而接口用于设计小而简练的功能块。

 

 

 

 

 

posted @ 2009-08-05 17:55  doing_zzh  阅读(174)  评论(0编辑  收藏  举报