C#笔记
1.C#数据类型相互转换:
隐式类型转换:小转大
值类型的隐式转换:小转大
引用类型隐式转换:子类转基类
显示类型转换:大转小
值类型: 1.Convert. 2.类型.Parse("") 3.(显示转换的类型)变量
引用类型:只有基类对象原本引用的是子类对象才可以显示将基类转换为子类对象
1 class Program 2 { 3 static void Main(string[] args) 4 { 5 //值类型转换 6 int i = 10; 7 long l = i; //隐式类型转换,小转大 8 byte b = (byte)l; //显示类型转换,大转小 9 byte b2 = System.Convert.ToByte(l);//显示类型转换 10 string s = b.ToString();//byte转为string型 11 byte b3 = byte.Parse(s);//显示类型转换 12 System.Console.WriteLine("值类型隐式转换: {0}", l); 13 System.Console.WriteLine("值类型显示转换: {0}", b3); 14 //引用类型转换 15 B ba = new B(); 16 ba._name = "张三"; 17 ba._age = 19; 18 A ab = ba; //引用类型隐式转换 19 System.Console.WriteLine(ab._name); 20 B bb = (B)ab; //显示转换 21 System.Console.WriteLine(bb._age); 22 System.Console.ReadKey(); 23 } 24 } 25 class A {public string _name;} 26 class B : A { public int _age; }
1).enum<-->int: 枚举类型默认可以跟int类型互相转换,枚举类型跟int类型是兼容的,枚举默认int值是0: 强制类型转换;
注意:当转换一个枚举中没有的值时,不会抛出异常,而直接将数字显示出来。
1 int a=3; 2 string str = ""; 3 Person ps = new Person(); 4 //int<-->enum:可相互转换:强制类型 5 //enum默认int值为0; 6 ps = (Person)a; 7 Console.WriteLine("int-->enum: {0}", ps); 8 //当转换一个枚举中没有的值时,不会抛出异常,而直接将数字显示出来。 9 a = (int)Person.女; 10 Console.WriteLine("enum-->int: {0}", a);
2).enum<-->string:
3).int<-->string:
所有类型都可以转换成string类型: .ToString();
字符串转换为枚举类型:(要转换的枚举类型)enum.Parse(typeof(要转换的枚举类型),"要转换的字符串") ;
如果转换的字符串是数字,则就算枚举中没有,不会抛出异常;
如果转换的字符串是文本,如果枚举中没有,则会抛出异常。
字符串转换为int类型: Convert.ToInt32()、int.Parse()、int.TryParse()
1 //枚举类型转换为string类型 2 //任何数据类型都可以转换为string类型: .ToString() 3 str = ps.ToString(); 4 Console.WriteLine("enum-->string: {0}", ps); 5 //string类型转换为enum类型: 6 //(枚举名称)Enum.Parse(typeof(枚举名 称),string变量); 7 str = "31"; 8 ps = (Person)Enum.Parse(typeof(Person), str); 9 a = Convert.ToInt32(ps); 10 Console.WriteLine("string-->enum: {0}", ps); 11 Console.WriteLine("string-->int: {0}", a); 12 Console.ReadKey();
2. 字段: _name 可保存多个值
变量: name 只可保存一个值
属性:set{} get{}
属性的作用就是保护字段、对字段的赋值和取值进行限定。
属性的本质就是两个方法,一个叫get()一个叫set()。
既有get()也有set()我们称之为可读可写属性。
只有get()没有set()我们称之为只读属性
没有get()只有set()我们称之为只写属性
封装:
- 字段封装:属性 get和set
- 集合封装:索引器(有参属性),也可以用get和set封装 访问修饰符 返回类型 this[索引参数] {get{} set{}}
3. 静态和非静态的区别
1)、在非静态类中,既可以有实例成员,也可以有静态成员。
2)、在调用实例成员的时候,需要使用对象名.实例成员;在调用静态成员的时候,需要使用类名.静态成员名;
总结:静态成员必须使用类名去调用,而实例成员使用对象名调用。
静态函数中,只能访问静态成员,不允许访问实例成员;
实例函数中,既可以使用静态成员,也可以使用实例成员。
静态类中只允许有静态成员,不允许出现实例成员,不能被实例化。
使用:
1)、如果你想要你的类当做一个"工具类"去使用,这个时候可以考虑将类写成静态的。调用方便
2)、静态类在整个项目中资源共享。 类不占内存,对象占内存。但静态类分布到静态存储区域。
只有在程序全部结束之后,静态类才会释放资源。
4.构造函数:初始化对象
1)、名字与类名相同;
2)、可以有多个构造函数,由不同参数区分;
3)、构造函数没有返回值,包括空值也不行;
4)、构造函数可被重载。
创建对象的时候会执行构造函数,类当中会有一个默认的无参数的构造函数,当你写一个新的构造函数之后,不管是有参数的还是无参数的,那个默认的无参数的构造函数都被替代。
new关键字
Person zsPerson=new Person();
new帮助我们做了3件事儿:
1)、在内存中开辟一块空间
2)、在开辟的空间中创建对象
3)、调用对象的构造函数进行初始化对象
this关键字
1)、代表当前类的对象
2)、在类当中显示的调用本类的构造函数 :this
5、析构函数: 帮助释放资源
1)、不能带有参数;
2)、不能带有访问修饰符;
3)、名字与类名相同,在名字前加~; 如 ~Car(){}
4)、对象被销毁时自动调用。
6、方法:
1)、静态方法:static修饰,不能对类的实例进行操作,也不能用this修饰,使用该方法时,用类名进行引用。
2)、非静态方法:可对类的实例进行操作,可用this修饰。
3)、void修饰的方法,可省略return,否之不行。
方法参数类型:
1)、值参数传递:调用后为每个值分配一个新的存储空间,所以不会影响到这个方法以外的变量;
2)、引用参数传递:不分配内存空间,ref修饰,是指向原变量的指针,引用参数与原变量保存在同一地址;
3)、输出参数传递:在传递参数前加out,用来返回一个结果,与引用参数传递区别为不必先初始化变量;
4)、参数数组传递:用params修饰。
7.继承:代码的重用
class A {...}
class B:A {...}
子类继承父类,拥有父类的所有数据成员、方法(除构造方法外)
方法重载:同一方法名,多种不同的实现方法。每个方法参数类型或个数、参数排列顺序不同。
虚方法:对于子类继承了父类,父类的方法不适合子类,可以把该方法定义为虚方法,在子类中重写这个虚方法。
父类定义这个虚方法:访问修饰符 virtual 方法返回类型 方法名(参数){return ...}
子类重写这个虚方法:访问修饰符 override 方法返回类型 方法名(参数){return ...}
抽象类 obstract:抽象类只对功能的描述,不涉及具体实现,不能被实例化,但可引用子类实例。可以有抽象属性和方法,也可有非抽象成员,非抽象成员可以被子类继承,抽象成员和方法需要子类重写override。
接口interface:可实现多继承。接口中只可以定义属性和方法,且不可以添加任何访问修饰符,子类如果实现接口的属性和方法,则此属性和方法须为public。
隐式实现接口
显示实现接口
多态:一个方法,多种实现。
8.委托:
委托是一个类,它定义了方法的类型,使得可以将方法当作另一方法的参数进行传递,这种将方法动态的赋值给参数的做法,可以避免在程序中大量使用IF-else(swith case)语句,同时使得程序具有更好的可拓展性。
使用委托可以将多个方法绑定到同一个委托变量,当调用此变量时(这里用“调用”这个词,是因为此变量代表一个方法),可以依次调用所有绑定的方法。
事件:
封装了委托类型的变量,使得:在类的内部,不管你声明它是public还是protected,它总是private的。在类的外部,注册“+=”和注销“-=”的访问限定符与你在声明事件时使用的访问符相同。
Noto:属性对字段进行封装,事件对委托进行封装。