第8章方法 ,,2 8.1实例方法和静态方法 个类的方法代码只有一份,它们的生命期和类是一致的,所谓的实例方法 是指通过对象名调用的方法,静态方法与类关联,而不是与对象关联,定义 静态方法时要使用 static关键字,调用静态方法时要使用类名,而不是对象名 静态方法不能直接访问非静态的字段,静态字段可以被所有方法所访问。 方法由方法头和方法体两部分组成。 实例方法的定义格式为: 修饰符返回类型方法名(参数列表) 方法体 定义静态方法的格式为 修饰符 static返回类型方法名(参数列表) 方法体
第8章 方法 一个类的方法代码只有一份,它们的生命期和类是一致的,所谓的实例方法 是指通过对象名调用的方法,静态方法与类关联,而不是与对象关联,定义 静态方法时要使用static关键字,调用静态方法时要使用类名,而不是对象名。 静态方法不能直接访问非静态的字段,静态字段可以被所有方法所访问。 方法由方法头和方法体两部分组成。 实例方法的定义格式为: 修饰符 返回类型 方法名 (参数列表) { 方法体 } 定义静态方法的格式为: 修饰符 static 返回类型 方法名 (参数列表) { 方法体 } ◼ 8.1 实例方法和静态方法
82值传递、引用传递和ref参数 参数传递 值传递:实参将值拷贝给形参,系统要为形参开设存储空间,以接受 传递的值,此时形参成为一个实在的局部变量,从此实参和形参脱离关系, 形参在方法中参与运算,在运算中的发生的任何变化都不会影响实参 ●引用传递:实参将自己的引用,也就是自己数据在存储器中的地址拷 贝给形参,这时形参如同实参的别名,系统不必为形参开设存储空间,形 参在方法中的任何改变就是实参的改变,所以引用参数既是方法的输入, 又是方法的输出,引用传递的形参需要用ref关键字声明,调用方法时的实 参也要添加ref关键字 ●对于属性、事件、索引器和用户定义的运算符来说,它们的参数总是 作为值参数传递的。这些成员类别不支持引用参数和输出参数(out)。 C#的数据类型有值类型和引用类型两种,所以参数传递时,在形式上有四 种情况:值类型参数进行值传递、引用类型参数进行值传递、值类型参数 进行引用传递、引用类型参数进行引用传递
8.2 值传递、引用传递和ref参数 参数传递: ◼l 值传递:实参将值拷贝给形参,系统要为形参开设存储空间,以接受 传递的值,此时形参成为一个实在的局部变量,从此实参和形参脱离关系, 形参在方法中参与运算,在运算中的发生的任何变化都不会影响实参; ◼l 引用传递:实参将自己的引用,也就是自己数据在存储器中的地址拷 贝给形参,这时形参如同实参的别名,系统不必为形参开设存储空间,形 参在方法中的任何改变就是实参的改变,所以引用参数既是方法的输入, 又是方法的输出,引用传递的形参需要用ref关键字声明,调用方法时的实 参也要添加ref关键字。 ◼l 对于属性、事件、索引器和用户定义的运算符来说,它们的参数总是 作为值参数传递的。这些成员类别不支持引用参数和输出参数(out)。 C#的数据类型有值类型和引用类型两种,所以参数传递时,在形式上有四 种情况:值类型参数进行值传递、引用类型参数进行值传递、值类型参数 进行引用传递、引用类型参数进行引用传递
83out参数和 params参数(1) 831 params参数 般情况下,方法的输入是通过参数列表规定的,输入参数的个数不能随 着实际调用的需要而改变, params参数则提供了这样一种方便,例如, 有n组数据,每一组数据个数都不一样,但都要求平均数,在C#中,借助 params参数,只要定义一个方法就可以完成这样的灵活功能。 params参数也称为参数数组。 params参数是具有一维数组性质的数组类 型的参数,例如一维数组,或者交错数组,但不能是多维数组; params参数实际上是不定长的数组,定义形参时要使用 params关键字 不需要指定长度,在调用时,实参不需要用 params关键字,实参可以是 任意个数的元素,也可以是一个同类型的数组。 params参数只能作为参数列表的最后一个参数。 params参数不能再用ref或out修饰
8.3 out参数和params参数 (1) ◼ 8.3.1 params参数 一般情况下,方法的输入是通过参数列表规定的,输入参数的个数不能随 着实际调用的需要而改变,params参数则提供了这样一种方便,例如, 有n组数据,每一组数据个数都不一样,但都要求平均数,在C#中,借助 params参数,只要定义一个方法就可以完成这样的灵活功能。 params参数也称为参数数组。params参数是具有一维数组性质的数组类 型的参数,例如一维数组,或者交错数组,但不能是多维数组; params参数实际上是不定长的数组,定义形参时要使用params关键字, 不需要指定长度,在调用时,实参不需要用params关键字,实参可以是 任意个数的元素,也可以是一个同类型的数组。 params参数只能作为参数列表的最后一个参数。 params参数不能再用ref或out修饰
83out参数和 params参数(2) ■832out参数 般情况下,一个方法只有一个返回值,返回数据是一种输出的方式, ref修饰的参数,或者是引用类型参数,它们既是输入,又是输出,out参 数提供了更灵活的输出方式。 out参数也称为输出参数。和ref参数类似,用out修饰的参数,直接将引 用传递给方法,不在存储器中为参数开设新的空间,但是,和ref参数不 样,调用方法前并不需要对参数作初始化,正因为如此,在out参数没 有被显式赋值之前,不能使用,在方法结束前应该对out参数赋值。 调用方法时,也要用out修饰实参,并且实参必须是变量,不能是属性 表达式。 ou参数可以用在实例方法、静态方法和实例构造函数中,不能用在属性 和索引器中
8.3 out参数和params参数 (2) ◼ 8.3.2 out参数 一般情况下,一个方法只有一个返回值,返回数据是一种输出的方式, ref修饰的参数,或者是引用类型参数,它们既是输入,又是输出,out参 数提供了更灵活的输出方式。 out参数也称为输出参数。和ref参数类似,用out修饰的参数,直接将引 用传递给方法,不在存储器中为参数开设新的空间,但是,和ref参数不 一样,调用方法前并不需要对参数作初始化,正因为如此,在out参数没 有被显式赋值之前,不能使用,在方法结束前应该对out参数赋值。 调用方法时,也要用out修饰实参,并且实参必须是变量,不能是属性、 表达式。 out参数可以用在实例方法、静态方法和实例构造函数中,不能用在属性 和索引器中
84局部变量 在程序中,任何变量都有生命期、作用域和可见性的变化。C#中 没有在类外的全局变量的概念,所有的变量都在类中定义。局部 变量是在局部语法区域中被产生、起作用和终止的临时变量,C# 的局部的语法区域是指方法或方法内的代码块。 变量在类中,称为字段,局部变量的声明、赋值和字段没有差别, 但是局部变量的生命期和作用域开始于被声明的那一点,只有在 被赋值后,才能使用,当定义变量的方法,或者代码块结束时 局部变量也结束了生命。在同一个作用域中不能有同名的变量
8.4 局部变量 在程序中,任何变量都有生命期、作用域和可见性的变化。C#中 没有在类外的全局变量的概念,所有的变量都在类中定义。局部 变量是在局部语法区域中被产生、起作用和终止的临时变量,C# 的局部的语法区域是指方法或方法内的代码块。 变量在类中,称为字段,局部变量的声明、赋值和字段没有差别, 但是局部变量的生命期和作用域开始于被声明的那一点,只有在 被赋值后,才能使用,当定义变量的方法,或者代码块结束时, 局部变量也结束了生命。在同一个作用域中不能有同名的变量
8.5签名和重载 方法的签名是方法之间互相区别的标记,方法的签名由方法名和参数 列表共同组成。 两个参数列表相同的条件是:参数的个数相同,否则参数列表不同 如果参数个数相同,再从左到右依次判别每一对形参的类型和种类 (ref或out)。只要有一对形参不同,两个参数列表就是不同的。返 回类型和 par ams参数不是签名的一部分 两个签名相等的条件是方法名和参数列表都相等,否则就是不同的签 用相同的方法名但是不同的参数列表来定义一组方法,称为重载。这 组方法称为重载方法 除了方法以外,构造函数、索引器、运算符都可以重载,索引器的签 名不包含元素类型。运算符的签名不包括结果类型。 合法重载的依据是签名不同,或者说,在它们所在的类、接口或者结 构中是唯一的
8.5 签名和重载 方法的签名是方法之间互相区别的标记,方法的签名由方法名和参数 列表共同组成。 两个参数列表相同的条件是:参数的个数相同,否则参数列表不同; 如果参数个数相同,再从左到右依次判别每一对形参的类型和种类 (ref或out)。只要有一对形参不同,两个参数列表就是不同的。返 回类型和params参数不是签名的一部分。 两个签名相等的条件是方法名和参数列表都相等,否则就是不同的签 名。 用相同的方法名但是不同的参数列表来定义一组方法,称为重载。这 组方法称为重载方法。 除了方法以外,构造函数、索引器、运算符都可以重载,索引器的签 名不包含元素类型。运算符的签名不包括结果类型。 合法重载的依据是签名不同,或者说,在它们所在的类、接口或者结 构中是唯一的
8.6Main方法 Main方法是C#程序的入口,根据C#的语法,Main方法也必须 定义在某一个类中,正如前面看到的,通常,我们定义一个 专门管理Main方法的类,虽然原则上也可以把Main方法定义 在其它类中,并且不影响编译时的程序逻辑。作为程序入口 的Main方法,必须是 public和 static的 在以前的程序中,Main方法使用了两种形式: public static void Mainot public static void Main(string[] args)I 第二种形式种的参数,称为命令行参数,命令行参数是一个 字符串数组,使用命令行参数可以增加运行程序的灵活性
8.6 Main方法 Main方法是C#程序的入口,根据C#的语法,Main方法也必须 定义在某一个类中,正如前面看到的,通常,我们定义一个 专门管理Main方法的类,虽然原则上也可以把Main方法定义 在其它类中,并且不影响编译时的程序逻辑。作为程序入口 的Main方法,必须是public和static的。 在以前的程序中,Main方法使用了两种形式: public static void Main(){… … } public static void Main(string [ ] args){ … … } 第二种形式种的参数,称为命令行参数,命令行参数是一个 字符串数组,使用命令行参数可以增加运行程序的灵活性
8.7运算符重载(1) C#允许用户自定义运算符的方法,或者说,允许用户添加新 的运算符方法,这就是运算符重载 ■87.1声明运算符方法 运算符方法和其它方法一样是类或者结构的成员,运算符可分为一元运算符 符、二元运算符,用于把其它类型的数转换为32位整型数。声明运算符方法 要使用关键字 operator 运算符重载的声明应该用 public static修饰。返回类型并没有强制的规定, 可以根据实际需要来定义,通常与参数的类型一致。 运算符方法的参数不能用re和out修饰。 871.1一元运算符方法的声明格式 public static类型 operator一元运算符(类型参数名) 8712二元运算符方法的声明格式 public static类型 operator二元运算符(类型参数名,类型参数名)
8.7 运算符重载(1) C#允许用户自定义运算符的方法,或者说,允许用户添加新 的运算符方法,这就是运算符重载。 ◼ 8.7.1 声明运算符方法 运算符方法和其它方法一样是类或者结构的成员,运算符可分为一元运算符 符、二元运算符,用于把其它类型的数转换为32位整型数。声明运算符方法 要使用关键字operator。 运算符重载的声明应该用public static修饰。返回类型并没有强制的规定, 可以根据实际需要来定义,通常与参数的类型一致。 运算符方法的参数不能用ref和out修饰。 8.7.1.1 一元运算符方法的声明格式 public static 类型 operator 一元运算符 (类型 参数名) { … … } 8.7.1.2 二元运算符方法的声明格式 public static 类型 operator 二元运算符 (类型 参数名, 类型 参数名) { … … }
8.7运算符重载(2) 8.7.1声明运算符方法 8.7.1.3类型转换运算符方法的声明格式 public static implicit operator类型(类型参数名) }或 public static explicit operator类型(类型参数名) 其中,关键字 implici和 explicit分别表示隐式转换和显式转换。 8.7.1.4运算符的可重载性限制 由于运算符的作用不同于一般的方法,所以运算符重载有些特殊的限制 ⑩●运算符重载不能改变运算符的操作数的个数 ⑩●运算符重载不能改变运算符的优先级 ⑩0●运算符重载不能改变运算符顺序关联性 ⑩●执行运算符方法时,优先执行用户定义的运算符方法 有些运算符不能重载
8.7 运算符重载(2) ◼ 8.7.1 声明运算符方法 8.7.1.3 类型转换运算符方法的声明格式 public static implicit operator 类型 (类型 参数名) { … … } 或: public static explicit operator 类型 (类型 参数名) { … … } 其中,关键字implicit和explicit分别表示隐式转换和显式转换。 8.7.1.4 运算符的可重载性限制 由于运算符的作用不同于一般的方法,所以运算符重载有些特殊的限制。 l 运算符重载不能改变运算符的操作数的个数 l 运算符重载不能改变运算符的优先级 l 运算符重载不能改变运算符顺序关联性 l 执行运算符方法时,优先执行用户定义的运算符方法 •有些运算符不能重载
8.7运算符重载(3) 872一元运算符的重载 可重载的一元运算符有: true false 87.3二元运算符的重载 可重载的二元运算符”有: 不可重载的运算符包括:成员访问、方法调用以及=、&&、‖、?: checked、 unchecked、new、 typeof、as和is运算符 个二元运算符必须有两个参数参与运算,其中至少有一个参数和声明时 类型一致,二元运算符方法返回的类型没有限制
8.7 运算符重载(3) ◼ 8.7.2 一元运算符的重载 可重载的一元运算符有: + - ! ~ ++ -- true false 可重载的二元运算符”有: + - * / % & | ^ > == != > = <= 不可重载的运算符包括:成员访问、方法调用以及=、&&、||、?:、 checked、unchecked、new、typeof、as和is运算符。 一个二元运算符必须有两个参数参与运算,其中至少有一个参数和声明时 类型一致,二元运算符方法返回的类型没有限制。 ◼ 8.7.3 二元运算符的重载