C#学习之步步高(一)同名方法之间的关系

大家好,这将是一个系列文章,都是有关于学习C#的,今天我就给大家带来这个些列的第一章:同名方法之间的关系。

开讲之前我得先简单介绍下C#这门语言,C#是微软于2000年6月推出的一门纯粹的面向对象,是一门安全的,稳定的,简单而优雅的由C,C++衍生出来的一门运行于.Net Framework之上

下面开始本章的内容(内容有点多,但是写的很详细,很值得一看)。

同名方法之间有几种关系呢?答案是四种。

1:方法重载,方法重载是从方法体之间的参数(和方法返回值无关)来决定,对于类方法(静态方法static method)和成员方法都适用。

2:方法重写,方法重写是建立在虚函数(virtual或abstract)和继承之上,重写函数在派生类和基类的原型是一模一样的。

3:方法覆盖,方法覆盖也是建立在继承之上,覆盖函数在派生类和基类的原型是一模一样的。和重写不同的点是方法覆盖它不是虚函数。

4:方法实现,这个比较特别,是专门针对接口而言的。

首先来来介绍一下方法重载吧:

先看下面例子:

public class SomeClass{// 方法ipublic void Method(int a){Console.WriteLine("这个是方法,参数是System.Int32类型");}// 方法iipublic void Method(float a){Console.WriteLine("这个方法,参数是System.Single类型");}}下面是调用方: class Program{static void Main(string[] args){SomeClass a = new SomeClass();// 这个调用的是方法i 代码段[1]a.Method(3.0f);// 这个调用的方法ii 代码段[2]a.Method(3);// ※注:方法重载是面向对象中多态的一个体现,属于静态连篇,// 也就是说重载的话,编译器是找到你要调用的具体是哪个函数的// 例如上面代码段[1]在编译的时候编译器会自动帮你找到方法i并调用它// 这种性质在方法重写不存在,后面的例子会给大家介绍方法重写}}

那么有人就会问了,如果我使用泛型或者params参数或者ref及out能进行方法重载吗?答案是能!请看下面几个例子:

class Program{static void Main(string[] args){SomeClass a = new SomeClass();// 这个调用的是方法i 代码段[1]a.Method(3.0f);// 这个调用的方法ii 代码段[2]a.Method(3);// ※注:方法重载是面向对象中多态的一个体现,属于静态连篇,// 也就是说重载的话,编译器是找到你要调用的具体是哪个函数的// 例如上面代码段[1]在编译的时候编译器会自动帮你找到方法i并调用它// 这种性质在方法重写不存在,后面的例子会给大家介绍方法重写/*↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓这个区间之间是新加内容↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓*/// 这个是调用的方法iiia.Method(5, 1);// 这个是调用的方法iva.Method<int>(4);// 这个调用的方法vvar s = 0;a.Method(ref s);/*↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑*/}}public class SomeClass{// 方法ipublic void Method(int a){Console.WriteLine("这个方法,参数是System.Int32类型");}// 方法iipublic void Method(float a){Console.WriteLine("这个方法,参数是System.Single类型");}/*↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓这个区间之间是新加内容↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓*/// 方法iiipublic void Method(int a, params int[] array){Console.WriteLine("这个方法,参数是System.Int32和一个可选参数");}// 方法ivpublic void Method<T>(T param){Console.WriteLine("这个方法,参数是一个泛型类型,其类型为:" + typeof(T).FullName);}// 方法vpublic void Method(ref int a){Console.WriteLine("这个方法,参数是按引用传值的System.Int32类型");}/*↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑*/}

那么其实上面代码是存在问题的,上面问题呢?看下面代码:

class Program{static void Main(string[] args){SomeClass a = new SomeClass();// 这个调用的是方法i 代码段[1]a.Method(3.0f);// 这个调用的方法ii 代码段[2]a.Method(3);// ※注:方法重载是面向对象中多态的一个体现,属于静态连篇,// 也就是说重载的话,编译器是找到你要调用的具体是哪个函数的// 例如上面代码段[1]在编译的时候编译器会自动帮你找到方法①并调用它// 这种性质在方法重写不存在,后面的例子会给大家介绍方法重写// 这个是调用的方法iiia.Method(5, 1);// 这个是调用的方法iva.Method<int>(4);// 这个调用的方法vvar s = 0;a.Method(ref s);/*↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓这个区间之间是新加内容↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓*/// 请看下面这个方法,其实它是符合3个方法原型的// 它符合方法i,因为方法i:public void Method(int a)的原型参数就是一个int类型// 其实它也符合方法iii,因为下面这个相当于在方法iii: public void Method(int a, params int[] array)中的可选参数不填// 它也符合方法iv,因为它符合方法iv:public void Method<T>(T param)这个原型// 那么问题来了,它到底调用的是方法i,方法iii,还是方法iv呢?// 答案是:方法i// 因为当重载冲突的时候,是最先考虑参数原型最简单的,也就是方法i// 其次才是考虑可选参数方法,也就是方法iii// 最后才是考虑泛型方法,也就是方法iva.Method(6);// 如果想显示调用方法iii,你得这么写:a.Method(6, new int[0]);// 如果你想显示调用方法iv,你得这么写a.Method<int>(6);// 好了,方法重载就先介绍到这里了,大家先慢慢体验吧。/*↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑*/}}空虚无聊的时候就读书,但一定得有自己的生活目标和计划。

C#学习之步步高(一)同名方法之间的关系

相关文章:

你感兴趣的文章:

标签云: