本文主要是介绍C#面向对象程序设计基础知识精细概括,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
基本概念
- 面向过程(如C):对于一个问题,分析出解决这个问题所需的步骤,然后用函数把这些步骤一步一步实现,使用的时候一个一个依次调用就可以了。
- 面向对象(如C#):把构成问题事务分解成各个对象,建立对象的目的不是为了完成一个步骤,而是为了描述某个事务在整个解决问题的步骤中的行为。
对象
- 对象是构成系统的基本单位。
- 对象=属性+行为(方法、操作)
事件与方法
- 事件:又称消息,表示一个对象A向另一个对象B发出的服务请求。当某个事件发生(即对象B接收到对象A的消息或服务请求)时,对象B开始执行操作,操作结束后将执行的结果返回给对象A。
- 方法:表示一个对象能完成的服务或执行的操作功能。
- 在一个系统中,对象之间通过发送和接收消息(事件)互相联系,相互配合,保证整个系统的正常运行。
- 注意:方法和服务是不会自动执行的,只有在事件发生或接收到消息时才会执行。
- 在面向对象中的系统就是依靠事件来驱动其运转的,新的事件一旦发生,系统中相关对象的操作开始执行,结果是系统的状态就会发生改变。
类和对象
- 类和对象关系:1.在面向对象的概念中,类(Class)表示具有相同属性(定义的形式,不是属性值)和行为的一组对象的集合,为该类的所有对象提供统一的抽象描述。2.就是说类是抽象,对象是具体实例。3.在C#中,类是一种自定义数据类型,对象就是根据“类”类型而定义的一个变量。存储上,类是抽象的,不占用诸如计算机内存之类的系统资源,而对象是具体的,占用内存空间。
面向对象最基本的特征
- 抽象:抽象就是只关注当前目标有关的方面,而忽略与当前目标无关的那些方面,是将有关事物的共性归纳、集中的过程。
- 在面向对象中,类其实就是通过那些相似对象的共同特征抽取出来而形成的一种数据类型。
封装和信息隐藏
- 封装:是将有关的数据和操作代码封装在一个对象中,形成一个基本单位,各个对象之间相互独立,互不干扰。
- 信息隐藏:将对象中某些部分对外部隐藏,只留下少量接口,以便与外部联系,接收外界的信息。有利于数据安全,防止无关的代码了解和修改数据。
继承
- 继承父类:就是在一个已存在的类A的基础上添加一些新的代码,而创建一个新类B,这个新类继承了父类的全部属性和方法。
- 继承在C#中称派生,其中A类称基类或父类,B类称派生类或子类。
多态
- 多态:在基类中定义的属性或方法被派生类继承后,可以表现出不同的行为特征,对同一消息会做出不同的响应。
- 实现多态性:从派生类中更改从基类中自动继承来的方法(覆盖)。
类的定义和使用
类的声明
class 类名
{
类的成员;
}
对象的定义和创建(实例化)
- 定义(声明)对象:就和定义一个普通变量一样。如:Student a;//定义一个Student型的对象a。
- 实例化:对象只有实例化之后才表示它在系统中真实存在。
Student a;//声明
a=new Student();//声明后的实例化
Student b=new Stdent();//声明同时创建(实例化)对象
- 类成员的访问:1.内部访问:this.类成员名//this表示当前对象。2.外部访问:对象名.类成员名
类的可访问性(访问修饰符)
public //公共的(类和成员)
internal //内部的(类和成员),类默认为internal
protected //受保护的(成员)
private //私有的(成员),类的成员默认为private
protected internal //仅限于在当前程序集中使用(成员)
- 注意:命名空间上不容许使用访问修饰符,命名空间没有访问限制。在类的内部可以访问所有的类成员。
值类型和引用类型
- 值类型用于存储数据的值,引用类型用于存储对实际数据的引用。
- 引用类型:引用类型变量本身并不包含数据,只是存储对数据的引用,数据保存在其他位置,数组、字符串、类、接口、委托都属于引用类型。引用型变量在定义时系统并不会为它分配空间,只有当它实例化之后才获得真正的存储空间。
- 引用型变量在对象赋值上的注意点:一个类型为Cir,若Cir b=a;这里是用对象a为对象b赋值,这一系统将a的引用赋给b,也就是这时两个对象最终指向同一个引用,若改变一个对象的值,另一个对象的值也会发生改变。
装箱和拆箱
- C#中引用类型也可进行数据转换,C#允许将任何类型的数据转换为对象,或者将任何类型的对象转换为与之兼容的值类型。
- 装箱:值类型转换为对象,隐式转换。
int i=9;
object x=i;//object类是所有类中的最终基类,可以将任何一个值类型变量直接赋给object变量。
- 拆箱:对象转换为兼容的值类型,必须是显式转换。拆箱时先检查对象所引用的数据的类型,确保拆箱前后的数据类型相同,再复制数据值。
int i=9;
object x=i;
int k=(int)x;
类的成员及其定义
类的常量
- 符号常量的定义:[访问修饰符 ]const 符号常量的数据类型 常量名=常量的值;
- 如:public const double pi = 3.14,e=2.71;
类的字段成员
- 字段表示类的成员变量,变量的值代表一个对象的数据状态。
- 声明字段格式:**[访问修饰符] 数据类型 字段名;**如:public double r;//r为字段。
- 在面向对象时,对象的所有信息在定义类时被声明为一个个字段。
- 在C#中,类的字段成员通过readonly关键字可设置为只读字段。
- 常量和只读字段的区别:声明方面:常量只能在声明时初始化,而只读字段可以在声明时或在构造函数中初始化。确定值方面:常量在编译时将确定其值,而只读字段在程序运行时才会确定其值。
类的属性成员
- C#中的属性——读取、修改、计算字段的值。
- 定义属性的形式:(get,set)
访问修饰符 数据类型 属性名 { get { //获取属性的代码,用return返回值,*读* } set { //设置属性的代码,用value赋值(value代表外部赋给本属性的值),*写* } }
可以省略其中一个
类的方法成员
- 方法——把一些相关语句组织在一起,用于解决某一特定问题的语句块。
- 类的方法的使用:
声明:(对数据的加工逻辑预先进行设计)
C#中的方法必须放在类定义中声明。
形式:[访问修饰符] 返回值类型 方法名 ([参数列表]){语句;return 返回值;}
注意:如果不需要返回一个值,则用void。参数可省略,当参数多时,需要用逗号分开,同时每一个参数都必须声明数据类型。
如:public int Sum(int a,int b) { int c=a+b; return c;}
调用:可在同一类或其它类中的方法中定义。
同一类的方法中调用,直接调用;格式:方法名(参数列表)
其他类的方法中调用,需通过类的实例;格式:对象名.方法名(参数列表)
但静态方法中,通过类名直接调用。
被调用时:可作为独立的一条语句;可作为表达式的一部分;可作为另一种方法的参数。
类的构造函数
- 各字段的值在实例化时自动调用构造函数来完成初始化工作(也可在声明时赋值,但构造函数更可靠)。必须保证类的字段成员在被引用前完成初始化工作。
- 形式:public 构造函数名(参数){语句;}
- 构造函数要求:其名称必须与类名相同;不容许有返回值。
- 如果没有定义构造函数,编译器将会自动生成默认构造函数,默认构造函数没有任何参数和语句,这时在创建对象时,系统将不同类型的数据成员初始化为相应的默认值(int =0,bool=false)。C#也可重新定义默认构造函数。
- 带参数的构造函数:在初始化对象时,可由外部传入数据并完成对象的初始化。如:public Student(string name,int age){ this.name=name;this.age=age;}
- 这样看来:如Student a=new Student(“二狗”,20),后面的new Student(“二狗”,20)实际是对构造函数的调用。
方法的参数传递
声明方法时,参数列表里面的参数就是形式参数,在调用方法时,调用方传递的参数就是实际参数。调用方法时,将实参传递给形参就是参数传递。
按值传参
- 按值传参——传参过程中,系统会将实参值单向传递给形参变量,这时,实参值和形参值是两个不同的变量,各自拥有各自的内存地址和数据值,被调用的方法接收到的只是实参值的一个副本(形参值)。所以更改形参值,不会影响实参值。(值类型的参数在传递时默认为按值传参),注意:string\object虽然是引用型数据,但从表现形式来看,具有按值传参的效果。
- 例子:lblShow.Text=x.Swap(a,b);//调用方法并传递参数,a和b是实参变量。
按引用传参
- 按引用传参——传参过程中,调用方将把实参变量的引用(实参数据值的内存地址)赋给相对应的形参,这时实参变量和形参变量(按引用传参时实参必须为变量)指向同一个地址。所以更改形参变量的值就会同时更改了实参变量的值。
- 实现:无论实参/形参,都必须用ref关键字。
- 例子:Swap方法:public string Swap(ref int x,ref int y)//方法声明时引用型形参
lblShow.Text=x.Swap(ref a,ref b);//引用型传参,要求在传参前先初始化形参
输出参数
- 输出参数——专门用于把方法中的数据通过形参传递给实参,不需对实参进行初始化,一个方法中可允许有多个输出参数。
- 实现:无论实参/形参,都必须用out关键字。
- 例子:public void string Swap(out int x,out int y)//被调用方
x.Swap(out a,out b);//调用方法,x,y为输出参数
引用类型的参数
- 引用类型参数的传递——实际上是将实参变量对数据的引用(内存地址)复制给了形参变量,所以两者指向同一个内存地址。
数组型参数
- 数组作为参数传递——数组为引用型数据,引用传参。
- 数组作为参数:1.形参数组前添加params修饰符时,所对应的所对应实参可为数组名、可为数组元素值的列表(这时系统将自动把各元素值组织到形参数组中)。2.不添加params,所对应实参必须是一个数组名。(形参数组都不能定义数组的长度)
- params修饰符:可修饰任何类型的参数,只能修饰一维数组,不能对它使用ref或out,每个方法只能有一个params数组。
方法的重载
方法的重载
-
方法的重载——用同一方法名定义多个方法,这些方法的参数个数或参数类型不同,以实现同一方法名可实现很多相似的功能。
-
方法重载要求:方法名同,参数个数或类型不同。
-
例子:1.public int Max(int a ,int b)2.public double Max(double a,double b)3.public int Max(int a,int b,int c)
-
实现:在调用经过重载的方法时,系统会自动根据参数类型或个数调用最匹配的方法。
构造函数的重载
- 构造函数重载——在一个类中,可以定义多个构造函数,提供不同的初始化方法,以满足创建对象时的不同需要。
- 例子:1.public Student():this(“无名”,20){}//无参构造函数(默认构造函数)2.public Student(string name):this(name,20){}//有一个参数的构造函数3.public Student(string name,int age){}//两个
- 可使用this从一个构造函数中调用另一个构造函数:public Student(string name):this(name,20){}
对象的生命周期
- 对象生命周期——就是从对象的创建到释放对象回收内存之间的期限
- 一个对象的生命周期经历的阶段:
1.使用new运算符创建对象并要求获得内存;
2.自动调用构造函数完成对象初始化;
3.使用对象;
4.释放对象所占用的资源(如关闭磁盘文件、网络连接、数据库服务的连接);析构函数
5.释放对象,回收内存(由垃圾回收器自动完成);
值类型变量和引用型变量的管理
- 值类型变量:使用栈来管理。栈是一种“先进后出”方式存取的内存区域。当方法被调用时,方法内的值类型变量自动获得内存,当方法调用结束时,这些变量所占用的内存将自动释放。
- 引用型变量:使用堆来管理。堆是分配对象时所使用的内存区域。在方法调用过程中,一旦使用new创建了对象,.NET的公共语言运行时立即为该对象从堆中分配内存,当方法调用结束时,对象所占用的内存并不会自动从堆中释放,在.NET中,对象所占用的内存只能由.NET的公共语言运行时的垃圾回收器来回收(垃圾回收器没有预定的工作模式,其工作时间间隔是不可预知的,垃圾回收器的优化引擎能根据分配情况确定回收的最佳时机)。
析构函数
- 析构函数——回收类的实例所占用的资源
- 实现:在类名前加“”的方式命名:函数名(){}
- 特点:
1.一个类只能由一个;
2.不能继承或重载;
3.无修饰符和参数;
4.在析构函数被调用时,.NET的公共语言运行时自动添加对基类Object.Finalize方法的调用来清理现场,所以在析构函数中不能包含对其方法的调用。
6.编译器会自动生成空的析构函数,C#不允许定义空的析构函数。
7.性能差,可使用close()或Dispose()强制回收方法来尽快关闭和释放所占用的资源。
参考书籍和网站:
-
https://blog.csdn.net/jerry11112/article/details/79027834
-
C#程序设计经典教程》罗福强等主编
这篇关于C#面向对象程序设计基础知识精细概括的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!