静态方法。
静态修饰符可以修饰方法使之变为静态方法。静态方法和静态数据成员特性差不多,可以由类名直接调用。要注意的是,在静态方法中不能访问非静态的类成员,包括非静态的方法成员和数据成员,但非静态成员方法中可以任意访问静态成员。
示例:
using System;
namespace Test
{
class Student
{
static int studentCounter=0;
public static Student GetStudent()
{
return new Student();
}
public static int AddStudent()
{
return ++studentCounter;
}
public void AddStudentEx()
{
AddStudent();
++studentCounter;
}
}
class Test
{
public static void Main()
{
Student.studentCounter++;
Student e=Student.GetStudent();
Console.Write("输出现在的学生数:{0}",Student.studentCounter);
Student.AddStudent();
Console.Write("输出现在的学生数:{0}",Student.studentCounter);
e.AddStudentEx();
Console.Write("输出现在的学生数:{0}",Student.studentCounter);
}
}
}
仔细检查一下这个例子和我们在上一节举的例子有何不同?是了,这个例子中在Main方法里我们没有用new操作符创建对象(当然我们在GetStudent里使用了new,没有new是不可能创建对象的)。另外,我们在AddStudentEx里使用了AddStudent方法,你可以尝试一下在AddStudent方法里使用AddStudentEx可不可以,当然后者不可以,我们说在静态方法里只能使用类的静态成员,但在非静态方法里却可以使用静态成员,很绕口吧,事实上就是如此。
方法重载及其意义所在
到现在为止我们已经介绍过类、对象、类的数据成员、类的方法,我们知道类分为自定义类和系统类。系统类为我们提供了通用的算法和解决办法。我们在这里列举几个常用的系统方法。一个是最常用的Console.WriteLine方法,一个是类型转换方法Convert.ToInt32方法。
Console.WriteLine方法:
[C#] public static void WriteLine(bool);
[C#] public static void WriteLine(char);
[C#] public static void writeLine(char[]);
[C#] public static void WriteLine(string);
……
Convert.ToInt32方法:
public static int ToInt32(bool);
[C#] public static int ToInt32(byte);
[C#] public static int ToInt32(char);
[C#] public static int ToInt32(DateTime);
……
这种定义方式就是我们现在要讨论的方法重载。在C#中,语法规定同一个类中两个或两个以上的方法可以用同一个名字,如果出现此情况,那么该方法就被称为重载方法。当一个重载方法被调用时,C#会根据调用该方法的参数自动调用具体的方法来执行。对于方法的使用者来讲,这种技术是非常有用的,比如对于Console.WriteLine方法而言,我们几乎可以调用它实现任何数据类型数据的输出,如:
Console.WriteLine(2);
Console.WriteLine(true);
Console.WriteLine("hello world");
这种便利就是重载方法提供的,重载方法的定义规则如下:
必须是同一个类中的方法。
满足方法名字相同、参数不同(指参数个数不同或参数个数相同而参数类型不同)。
与方法的访问修饰符和返回值无关。
另外,还要注意重载方法的调用,如果C#根据调用参数没有找到对应的方法,那么C#将调用带有“最近”类型参数的方法。“最近”的规则和我们前面提到的类型隐式转换有关,具体的调用规则我们将在下面示例中演示。
示例:
using System;
namespace TestAdd
{
public class TestAdd
{
public int Add(int a,int b)
{
return a+b;
}
public double Add(double a,double b)
{
return a+b;
}
public decimal Add(decimal a,decimal b)
{
return a+b;
}
public int Add(string a,string b)
{
return Convert.ToInt32(a)+Convert.ToInt32(b);
}
}
class Test
{
public static void Main(String [] args)
{
TestAdd t=new TestAdd();
t.Add(1,2); //调用Add(int a,int b)
t.Add(2.0,3.0); //调用Add(double a,double b)
t.Add("3","4"); //调用Add(string a,string b)
t.Add("3","4"); //调用Add(string a,string b)
t.Add(2,3.0); //编译器处理,调用Add(double a,double b)
}
}
}
至于重载方法调用时类型不匹配的特殊情况,如上面的t.Add(2,3.0),第一个参数是整型,第二个参数是double型,类中无此方法定义,编译器会根据实际情况进行转换,如果不能转,比如上面如果用t.Add("2",3.0)调用,就会报错。转换的规则是尽量不丢失数据,我们知道只有隐式类型转换才不会丢失数据(数字的隐式转换方向short→int→float→double),所以调用规则偏向隐式转换链上靠近调用类型的那个方法,比如我们调用Add(2.0f,3.0f)方法,将调用double为参数的方法。不过我们建议尽量不要用非定义数据类型调用,避免出现不必要的错误。