其实方法这节课感觉跟C语言里面的函数差不多,故我就不写太多了。
一、变量
1.值类型的变量
值类型的变量没有实例,所谓的实例与变量合二为一。
值类型按类型的实际大小分配内存,其中高位存储在高地址。
2.引用类型的变量
引用类型的变量在栈中,以四个字节,储存,存储在堆中的对象,的地址。
一看到是引用类型便会分配四个字节,且会帮你初始化为NULL。
3.变量的默认值
如果是成员变量(声明在类中),会由构造器帮你赋值刷成0;
如果是局部变量,不初始化会编译错误。
二、方法
1、方法的由来
前身是函数。方法永远都是结构体或类中的成员,不能像C那样独立在全局之中。
类或结构体最基本的组成成员是方法和字段(成员方法与成员变量),本质上还是数据+算法。
方法表示类或结构体能做的事情。
使用方法,是为了(1)隐藏复杂的逻辑,具有封装性(2)重复调用
2、方法的声明与调用
极限缝合:可以在主函数里定义并调用方法、可以在类里面定义类,并调用类中类
namespace ConsoleAppPractice
{
class Program
{
static void Main()
{
int a = 1;
int b = 10;
Console.WriteLine(Program.Add(a,b));//二进制输出s
Console.WriteLine(Student.haha.Add(3.0,4.0));
}
public static int Add(int a,int b)
{
return a + b;
}
}
class Student
{
public static class haha
{
public static double Add(double a,double b)
{
return a + b;
}
}
}
}
3、构造器
用法:
1.规定构造对象时一定要说明到的东西
2.规定构造出实例时应该执行的操作
class Student
{
public static int amount;
public Student()
{
Student.amount += 1;
}
//创建一个学生实例时,让数字加一。
}
(1)什么是构造器
构造器跟属性、方法、事件、字段等一样,是类型的成员之一。
构造器事实上是一种特殊的函数。构造函数是构造器,成员函数是方法,这两个本质上都是函数。
狭义的构造器指的是实例构造器,构造实例在内存中的结构。
调用构造器,事实上就是我们new操作符后面那东西。那个括号像不像调用函数捏?
(2)构造器的声明方法
其实构造器是要在类里边声明的。声明一个类,如果没有自己声明构造器,编译器会默认帮你声明一个。默认构造器会将成员变量刷成0。
//留个问题,在构造函数里声明变量会发生什么?我试了一下,发现不能加public,也不能通过实例访问到这个声明的变量。但是这样编译器又能给过,非常神奇。
要自己声明构造器的话:
public int id;
public Student()
{
this.id = 200;
}
其中注意,构造器必须是public,且没用返回值,构造器的名字必须与类名相同。
那个this指的是实例自己。意思是给你创建的那个实例他自己里边的那个实例变量赋值。
由于必须是实例,所以此处id这个变量前面不能加static喔。
如果有时候需要给实例变量附上特定的值,可以给构造函数加参数:
namespace ConsoleAppPractice
{
class Program
{
static void Main()
{
Student haha = new Student(10, "hello world!");
Console.WriteLine(haha.str);
Console.WriteLine(haha.id);
}
}
class Student
{
public int id;
public string str;
public Student(int a,string b)
{
this.id = a;
this.str = b;
}
}
}
如果你这时候事情比较多,又不想要带参的构造器,此时系统默认给的已经无了,你可以自己再定义一个:
namespace ConsoleAppPractice
{
class Program
{
static void Main()
{
Student haha = new Student(10, "hello world!");
Student lala = new Student();
}
}
class Student
{
public Student()
{
}
public int id;
public string str;
public Student(int a,string b)
{
this.id = a;
this.str = b;
}
}
}
注:(1)一个小技巧:ctor+2*tab就可以自动补全一个构造器的框架。
(2)如果删去构造器里边那个实例变量的public(如定义int id),此时不会报错,只是在外面访问不到id这个变量。由此联想,这个的用处应该是用户可以在外面初始化类中实例变量的值。咦但是,这个不加public的实例成员要怎么用啊?先把疑惑放在这里了。
(3)构造器的内存操作
在声明一个引用变量并且牵着实例时,内存分配工作如下:
先在栈中开辟四个字节来存放这个引用变量,然后new操作符再在堆中开辟出实例的空间,并且把这个地址写回引用变量中去。构造器将堆中的实例那坨空间切割分配好给实例变量,并且进行初始化。
4、方法的重载
意思就是有一堆同名的方法,但他们的参数个数和类型不一样,履行相似的功能。
如,cw这个方法,你会发现它有足足三十多种,每个都叫cw,但是参数不一样,比如可以打印double类型打印string类型什么的。
方法能够重载要求方法签名不一致。
所谓方法签名,是由方法名称、类型形参的个数和形参的类型和种类组成的。它不包括返回值。
其中,构造函数跟方法一样,也是由参数决定的。
注:一个值得注意的点,参数的类型顺序不一样,签名居然也不一样。如下图这两个是可以重载得起来的。
class Student
{
public static int Add(double a,int b)
{
return 0;
}
public static int Add(int a, double b)
{
return 0;
}
}
系统调用重载时是有重载决策这一机制的。会帮你选择一个匹配的最佳函数成员来调用。
比如说调用cw的时候,你乱写就行,不用你选。
个人感言:方法与重载实际上打通了函数与方法,因为我一直疑惑C#不是强类型吗,怎么cw这个方法的参数这么随意啥都可以,原来是有重载。感觉这个机制确实非常人性化。
三、一些小知识
1、二进制转化输出一个数。
static void Main()
{
short s;
s = 100;
string str = Convert.ToString(s, 2);
Console.WriteLine(str);//二进制输出s
}