现在的位置: 首页 > 综合 > 正文

C#面向对象基础

2012年12月02日 ⁄ 综合 ⁄ 共 4876字 ⁄ 字号 评论关闭

C#面向对象基础

1、 为什么要有面向对象?

(1) 增加代码重用。

(2)降低维护负担,将具备独特性质的代码封装起来,修改程序时,相互不会影响。

2、数据封装用来解决全局变量不易维护的问题。

3、多态:为了加强继承的弹性,常常需要子类对父类的方法进行重写(函数名称不变)。

4、抽象化是为了降低程序版本更新后的维护负担。使功能的提供者和使用者分开,各自独立,彼此不受影响。

5、为了抽达到象化,提供接口用于建立功能提供者和使用者之间的规范。功能提供者和使用者按照这个规范来提供、使用这些功能。这个功用的规范就是接口。接口中定义了常量、函数名称、函数参数等。因此接口不改变的情况下,功能提供者就可以任意的改写函数中的代码,而不会影响到使用者使用这些功能。

 

抽象化的优点:

.可编写函数处理有相同接口的类

例如:员工薪水的发放:按照职位、工龄发放,只需要定义一个计算薪水的接口,然后分别实现。

.用于未来功能的扩展。

.让功能提供者和使用者相互独立。

6、通常继承应用在公司的内部开发上,以重复使用其他设计师编写好的代码;而接口多半是用于两个部门或两家以上的公司,用于分别开发自己的应用程序时建立的公用的规范。

7、类是数据封装的基本单位。是重复使用的最小单位。

类的成员:变量、方法、属性、事件、常数

对象是类在内存中的实体,类用于描述对象在内存中的数据。也就是说类用于定义对象的长相。

8、静态方法可以不建立类的对象,即不用new实例化,而用类直接调用:类名.方法名()

Static变量通常用于配置全局共用的区块

9、new实例化对象后,对象将会被配置在堆积Heap中,堆栈Stack内保存的是指向堆积Heap中对象所在位置的参考指针。实例化的那个对象用于存放的是指针。实例化的对象是放在堆栈中的,如下图:

 

9、结构和类的区别:结构主要由简单的数值类型组合而成,配置在堆栈中。类属于参考类型,配置在堆积中。结构不支持继承。

10、数据封装:使用类进行封装。

封装目的:数据和方法被封装起来,通过方法存取数据。可以控制数据的存取方式。

11、访问修饰符:

public:所有

private:类中的方法和成员只能在此类中使用,外部不能使用。

protected:类自身可以使用、子类也可以使用。protected并不是被派生类随心所欲的访问,访问是有条件的:访问必须是子类类型发生时,父类的protecte成员才能够被访问

internal:同一个.NET Assembly中可以使用

protected internal:只限定在目前的项目或继承自此类的成员才可以使用

注意:在声明方法是,默认识private

一个好的面向对象的设计,通常把所有的数据成员定义为private,然后提供方法来存取这些数据

12、数据封装的目的:易于控制数据、容易修改。

13、静态成员:

对象中的数据都是对象私有的,只有对象才能操作这些数据,其他对象不能操作。那么有时候把所有对象共用的数据保存在每一个对象中并不是很好,比如一个公司的所有员工同属于这个公司,若在员工类中定义一个存放公司名称的成员变量,那么,在实例化对象后,都需要用:对象名.方法名() 来存取公司名称信息,这样若公司名称改变了,维护起来比较麻烦,并且计算机还要分配内存、硬盘空间等,为了解决这个问题,在实现的时候会将这种数据放在全局的内存区块上,也就是说,这个数据不是对象能够操作的,而是类级别的,对象操作不了。但是,全局的数据并不是保存在类中的,因此,不能够使用封装的技巧使用全局变量,取而代之的是以静态static的方式来描述这样的数据。静态类就是用来描述类中共用信息的。

静态数据是在类中声明的,所以能够体现封装的特性。就算这个定义了静态数据的类没有被实例化,该静态数据还是存在的。所以,不用建立对象实体就可以对静态数据进行操作。

编译器会在类载入是自动初始化static变量,也就是说,若静态的成员变量没有被赋值,那么在编译时,编译器会自动给变量赋值。String类型是空字符串,int类型是0,bool类型是false,生命周期被限定在应用程序的生命周期中

14、静态方法:

对静态数据进行操作需要使用静态方法,静态方法属于类,是类级别的,不是对象能够操作的,静态方法不能用this保留字

通常,编译器Compiler在编译时会将静态数据和静态方法当做全局变量或全局函数来对待。默认的静态数据是private的

静态方法不能够存取非静态数据和非静态方法。

windows应用程序中Main()方法定义为public static,不需要实例化Runtime就可以直接运行Main().静态方法只能用类调用,非静态方法用实例调用。

15、this操作数

this操作数是指向此对象的参考指针。也就是实例化后就可以使用this来存取这一对象实体。还可以用于解决名称相同的问题:this.Name=Name(参数)。this还可以用来返回目前对象的参考: this.Name=Name ;return this。

16、类默认的访问修饰符是private

17、internal修饰符是类型和类型成员的访问修饰符。只有在同一个程序集的文件中,内部类型或者是成员才可以访问,Assembly:一个完整的.exe或者是.dll文件就是一个程序集。

18、参考类型:

实值类型:包含的是真正的数据,不能为null。堆栈。

参考类型:一个指向实际数据的参考指针。堆积。

 

封装、继承、多态

继承:

1、C#语言提供两种继承的方式:实现继承(只能单一继承)和接口继承(可以多继承)

UML中

类名

Employee

成员变量

-CompanyName:string

-EmployeeID:int

-EmployeeName:string

-EmployeeSalary:string

方法

+SetID(in ID:String):void

+GetID():string

+SetCompanyName(in CompantName:String):void

 

 

 

成员变量:-CompanyName:string字符串类型,“-”表示private访问修饰符,成员变量下方 加底线表示static

方法:+SetID(in ID:String):void in 表示输入参数 void表示不返回值,有下划线表示static

子类不能继承父类的构造函数和析构函数。

继承默认是public

2、Base:代表基类中调用父类的构造函数,注意,这个构造函数的的参数个数和类型必须和基类中某一个构造函数一样。Base的另外用法是调用基类的成员(成员方法),如:

父类:

namespace ClassTest

{

public class Employ

{

public Employ(string EmployeeNum)

{

}

private string employeeNum;//员工编号

public void SetEmployeeID(string EmployeeNum) //设置员工编号

{

employeeNum = EmployeeNum;

}

}

}

子类:

namespace ClassTest

{

public class U_base:Employ

{

public U_base(string EmployeeNum)

: base(EmployeeNum) //base指基类中的构造函数,参数类型和个数必须相同

{

base.SetEmployeeID(EmployeeNum); //这里的base是用于调用基类中的成员方法

}

}

}

3、基类重写override父类方法,这是多态的一种表现形式,是对基类中的方法进行重新定义。方法名以及参数和基类中的相同,只是方法内部代码不同。(重载是同一个类中的同一种方法的返回值可以相同,也可以不同,是一个类中多态的一种表现,参数不同)

4、虚拟方法

体现多态。一个类中默认的方法都是非虚拟的,不允许在同一个类中用相同的方法去实现不同的功能

虚拟方法不可以是静态的。因为静态方法是类级别的,而多态只能体现在对象级别。

Virtual不能用private修饰,否则没法再子类中重写。

Virtual方法可以有具体的实现,而abstract方法不能有具体的实现,abstract方法必须在子类中用override来实现。

基类中的Virtual方法被子类中的override重写是,方法的修饰符(不存在修饰符权限大小问题,必须相同)、名称、参数、返回值必须相同。

Virtual和override不能同时使用,因为override方法是隐含virtual的。

override不能和private、static一起使用,因为静态方法是类级别的,而多态只能体现在对象级别;override方法必须要改写virtual方法,若设置为private就不能改了。

virtual用来修改基类的方法或属性的定义部分。虚拟成员或虚拟函数可以在子类中改写其功能。Virtual用于基类中。Virtual方法可以被实例化成员调用。

具体用法是在基类中定义virtual方法,然后根据需要在子类中重写override功能,没有用virtual声明的方法不能用override重写,否则出错。

若基类和子类中有相同的方法,那么基类的方法被子类覆盖,基类能够调用自己的该方法,子类调用的该方法是子类自己的该方法。

注意:不管是基类中的virtual还是子类中的override方法,都能被各自的类调用。

5、final最终类不允许继承,里面的方法不允许override

6、new关键字

在子类中定义方法用以取代基类中的方法,但是基类中的该方法还是能够被基类的实例调用,而不能被子类实例使用了。子类中用new修饰的方法只能用子类的实例调用。使用new和在子类中直接定义一个和基类中的方法相同的方法的效果是一样的,不过这样会有警告。

7、sealed类(例如enum、String)和sealed方法

Sealed类防止类被继承,也就是说sealed类不能作为基类。Sealed方法不能被override重写

8、C#中允许将基类的类型指针指向子类:B:A{…} A a=new A();B b=new B();A c=b;这里的c是A的实例,若c.方法名(),则调用的是A中的方法。当然,若A中有virtual方法,那么A c=b就会先调用A,然后发现A中的方法用virtual修饰,会进一步检测B中的方法,若B类中的方法被virtual修饰,则A、B中的方法不相关,若B中的方法用new修饰,表明这是一个新的方法,,最终调用的是还是A中的方法。若B中的方法用override修饰,表明这是一个新的方法,,最终调用的是还是B中的方法。

9、接口

为了达到抽象化,需要在功能的定义和使用之间提供一种公共的规范,以便提供者和用户都能够按照规范进行操作。这样的规范就是接口。接口只是定义了规范,没有具体的实现(抽象类可以有具体的实现),接口支持多继承,类支持单继承。接口中定义的方法不能包含区块内容,也就是说不应该有大括号:public interface Job{double C(){}};这是错误的,定义在接口中的方法隐含都是public,若定义的时候再加上public就会报错啊。类一旦继承了接口,就应该实现接口中的所有方法,而且实现时要和接口中该方法完全相同(修饰符、返回值、方法名称、参数),继承自接口的方法可以用virtual关键字修饰,用于自他类继承。但是接口中的方法不能用virtual,也不能有修饰符。

10、抽象类、抽象方法

抽象类和接口一样不能实例化。抽象方法隐含是virtual的,所以不能和virtual连用。抽象方法只能定义在抽象类中。抽象方法只能由定义部分,不能有大括号,抽象方法一定要在子类中实现。和接口类似,抽象方法和virtual修饰的方法的区别是virtual可以有实现部分,即大括号。抽象类可以继承自非抽象类、抽象类。

抽象类和接口都不能使用sealed修饰,接口中不能包含抽象方法,抽象方法中可以使用ovreride、new修饰符

抱歉!评论已关闭.