C#基础笔记(第十天)
1.字段、属性、方法、构造函数
字段:存储数据
属性:保护字段,对字段的取值和设值进行限定
方法:描述对象的行为
构造函数:初始化对象(给对象的每个属性依次的赋值)
类中成员,如果不加访问修饰符,默认都是private
给每一个私有的字段都配备一个公有的属性
属性的本质就是两个方法
当我们创建好对象后
给这个对象的属性赋值用set
打印这个属性的值的时候执行get
this:当前类的对象
this:调用当前类
this是把属性和局部变量区分开来的。
构造函数:1、没有返回值 连void也没有
2、构造函数的名称跟类名一样
构造函数可以重载
:this(name,0,0,gender)
new:1、在内存中开辟一块空间
2、在开辟的空间创建对象
3、调用对象的构造函数
限定:set get 构造函数
静态方法 类名.方法名
实例方法 对象名.方法名
静态方法只能访问到静态成员
静态类不能创建对象
2、命名空间
命名空间可以看做是类的文件夹
可以认为类是属于命名空间的。
如果在当前项目中没有这个类的命名空间,需要我们手动的导入这个类所在的
命名空间。
1)、用鼠标去点
2)、alt+shift+F10
3)、记住命名空间,手动的去引用
3、在一个项目中引用另一个项目的类
1)、在解决方案资源管理器的引用右键添加引用
2)、引用命名空间
3、值类型和引用类型
区别:
1、值类型和引用类型在内存上存储的地方不一样。
2、在传递值类型和传递引用类型的时候,传递的方式不一样。
值类型我们称之为值传递,引用类型我们称之为引用传递。
我们学的值类型和引用类型:
值类型:int、double、bool、char、decimal、struct、enum
引用类型:string、自定义类、数组
存储:
值类型的值是存储在内存的栈当中。
引用类型的值是存储在内存的堆中。
堆、栈、静态存储区域
int number=10; 在栈中开辟一个空间,在这个空间存储10,给这个空间起名叫number
string s="123"; 在堆中开辟一个空间,在这个空间存储"123",有一个地址(引用) 0x001001,
在栈中开辟一个空间,存堆中的地址0x001001,起名叫s。现在s是指向堆中的内存的
Person zsPerson=new Person();
zsPerson.Name="张三";
在堆中开辟空间,在这个空间存储 new Person(); "张三",有一个地址(引用)
在栈中开辟一个空间,存堆中的地址,起名叫zsPerson
4、字符串
1)、字符串的不可变性
当你给一个字符串重新赋值之后,老值并没有销毁,而是重新开辟一块空间存储新值。
当程序结束后,GC扫描整个内存,如果发现有的空间没有被指向,则立即把它销毁。
int 重新赋值 会在原来的栈空间覆盖原值
string 重新赋值,会在原来的堆空间重新开辟一个空间存新值。栈中存地址的空间不变
创建 string s1="张三"
string s2="张三"
只在堆中开辟一块空间 存储"张三"
在栈中开辟两块空间命名为s1和s2指向堆中的空间(存储堆中的地址)
个人解释:
①当你创建了S1和S2后,就会在栈中开辟两个空间
一个叫S1,内存地址是1000XX
一个叫S2,内存地址是2000XX
②你给S1,S2赋值的string 类型 "张三"
是存在堆中开辟的空间内
它也有个内存地址是XX0001
③你栈中的S1,S2空间存的是堆中 的内存地址XX0001,他们是同一个东西
④如果你再 S1="李四"
S2=“李四”
它们也只是把S1,S2里面的内存地址指向堆中开辟的一个叫"李四"的空间的内存地址。
原来堆中存的"张三"不会有任何改变。
⑤当你清理内存的时候,那个"张三"因为内存地址没有被引用过,就会被清理掉(垃圾回收)
窗口-即时-及时窗口-&s1 &s2 可以看s1和s2的内存地址 上面是栈中的地址,下面是堆中的地址
2)、我们可以把字符串看做是char类型的一个只读数组。
ToCharArray();将字符串转换为char数组
new string(char[] chs):能够将char数组转换为字符串
1 string s = "abcdefg"; 2 char[] chs = s.ToCharArray(); 3 chs[0] = 'b'; 4 s= new string(chs); 5 Console.WriteLine(s); 6 Console.ReadKey();
Stopwatch 计时器
Stopwatch sw=new Stopwatch();
sw.Start();开始计时
sw.Stop();停止计时
sw.elapsed 当前实例测量得出的总运行时间
StringBuilder sb=new StringBuilder();
sb.Append(i);追加
能把这个i累加到sb里面
1 StringBuilder sb = new StringBuilder(); 2 //string str = null; 3 Stopwatch sw = new Stopwatch(); 4 sw.Start(); 5 for (int i = 0; i < 100000; i++) 6 { 7 //str += i; 8 sb.Append(i); 9 } 10 sw.Stop(); 11 Console.WriteLine(sw.Elapsed); 12 Console.ReadKey();
string 为什么这么慢,因为它每次都要开空间
stringbuilder这么快是因为它在内存中开空间,用来用去都是同一块类型。
最后stringbuild还是得要tostring转为string 类型。
5、字符串提供的各种方法
//把字符串转为大写
LessonOne =LessonOne.ToUpper();
//把字符串转为小写
LessonOne=LessonOne.ToLower();
//比较两个字符串的值
LessonOne.Equals(LessonTwo,StringComparison.OrdinalIgnoreCase)
Equals同样 StringComparison.OrdinalIgnoreCase 枚举.忽略被比较的字符串的大小写
string s = "a b c 3 12 - + _ , == fdf";
//分割字符串Split
//把不想要的字符都写在char数组里
//数组虽然干掉了,但是还是留了一个空""
//后面加上,StringSplitOptions.RemoveEmptyEntries把空给干掉
char[] chs = { ' ','_','=','+',',','-'};
string[] str = s.Split(chs,StringSplitOptions.RemoveEmptyEntries);
Console.ReadKey();
练习
Console.WriteLine("请输入日期,格式如2008-08-08"); string s = Console.ReadLine(); //可以不用创建char []chs,直接把它New在里面 string [] date= s.Split(new char [] {'-' },StringSplitOptions.RemoveEmptyEntries); Console.WriteLine("你输入的日期是{0}年{1}月{2}日",date[0],date[1],date[2]); Console.ReadKey();
//contains(包括),判断字符串中是否包含指定的字符串
//Replace(替换) 将字符串中某个字符串替换成一个新的字符串,返回
练习
1 string str = "国家领导人老赵"; 2 if(str.Contains("老赵")) 3 { 4 str=str.Replace("老赵","**"); 5 } 6 Console.WriteLine(str); 7 Console.ReadKey();
1 //Substring 截取字符串 2 string str = "今天天气好晴朗,处处好风光"; 3 //把字符串当做数组,从下标0开始截取 4 str = str.Substring(1); 5 //从“天”开始截取,截取2个字 6 str = str.Substring(1,2); 7 Console.WriteLine(str); 8 Console.ReadKey();
1 //StartsWith()判断字符串中是否以子串value开始 2 //EndsWith()判断字符串中是否以子串value结束 3 //使用方式相同 4 string str = "今天天气好晴朗,处处好风光"; 5 if(str.StartsWith("今天")) 6 { 7 Console.WriteLine("是的"); 8 } 9 else 10 { 11 Console.WriteLine("不是"); 12 } 13 Console.ReadKey();
1 //判断某个字符串在字符串中第一次出现的下标位置,如果没有返回-1,由int类型接受 2 string str = "今天天气好晴朗,处处好风光"; 3 int n=str.IndexOf('天'); 4 //后面加个Int类型数字,表示找字符串中的第几个‘天’的下标 5 //int n=str.IndexOf('天',2); 6 //如果要找到所有‘天’的下标,就需要用循环来找 7 Console.WriteLine(n); 8 Console.ReadKey();
1 //LastIndexOf():判断某个字符串在字符串中最后一次出现的位置,如果没有同样返回-1 2 //LastIndexOf()经常和Substring配合使用 3 string path = @"c:\a\b\c\d\e\f\g\ff\苍\ds\fgd\d\苍老师.wav"; 4 //找最后一个斜线后出现的文字才是最准确的,一直截到最后 5 int index=path.LastIndexOf("\\"); 两个斜线表示一个斜线
练习
1 string path = @"c:\a\b\c\d\e\f\g\ff\苍\ds\fgd\d\苍老师.wav"; @代表字符串中的\都表示\ 2 int index = path.LastIndexOf("\\");字符串中\\代表一个\ 3 path=path.Substring(index+1); 截取是从\开始,所以要加1 4 Console.WriteLine(path); 5 Console.ReadKey();
1 //Trim():去掉字符串中前后的空格 2 //TrimEnd():去掉字符串中结尾的空格 3 //TrimStart():去掉字符串中前面的空格 4 string str = " hahaha "; 5 str=str.Trim(); 6 Console.Write(str); 7 Console.ReadKey();
1 //string.IsNullOrEmpty():判断一个字符串是否为空或者为null 2 string str = null; 3 if(string.IsNullOrEmpty(str)) 4 { 5 Console.WriteLine("是的"); 6 } 7 else 8 { 9 Console.WriteLine("不是"); 10 } 11 Console.ReadKey();
1 //string.Join():将数组按照指定的字符串连接,返回一个字符串。 2 string[] name = { "张三","李四","王五","赵六","田七" }; 3 string str=string.Join("|", name); params可变参数:可以放数组也可以放参数 4 Console.WriteLine(str); 5 Console.ReadKey();
1)、Length:获得当前字符串中字符的个数
2)、ToUpper():将字符转换成大写形式
3)、ToLower():将字符串转换成小写形式
4)、Equals(lessonTwo,StringComparison.OrdinalIgnoreCase):比较两个字符串,可以忽略大小写
5)、Split():分割字符串,返回字符串类型的数组。
6)、Substring():截取字符串。在截取的时候包含要截取的那个位置。
7)、IndexOf():判断某个字符串在字符串中第一次出现的位置,如果没有返回-1、值类型和引用类型在内存上存储的地方不一样。
8)、LastIndexOf():判断某个字符串在字符串中最后一次出现的位置,如果没有同样返回-1
9)、StartsWith():判断以....开始 bool类型判断
10)、EndsWith():判断以...结束 bool类型判断
11)、Replace():将字符串中某个字符串替换成一个新的字符串
12)、Contains():判断某个字符串是否包含指定的字符串 bool类型判断
13)、Trim():去掉字符串中前后的空格
14)、TrimEnd():去掉字符串中结尾的空格
15)、TrimStart():去掉字符串中前面的空格
16)、string.IsNullOrEmpty():判断一个字符串是否为空或者为null
17)、string.Join():将数组按照指定的字符串连接,返回一个字符串。
6.复习
字符串需要掌握的亮点
1)字符串不可变,每新建一个字符串都会在内存中开辟一块新的空间
2)字符串的方法
StringBuilder和String的区别
String在进行运算时(如赋值、拼接等)会产生一个新的实例,而StringBuilder则不会。
使用StringBuilder进行操作,最后再用ToString转为String类型即可。
1 string path = @"C:\Users\SJD\Desktop\22.txt"; 路径 2 string [] str= File.ReadAllLines(path,Encoding.Default); 3 //File(静态类).ReadAllLines(方法,读取所有的行)读取的全是乱码 4 //Encoding.Default 去除乱码 5 Console.ReadKey();
7.练习
char类型数组转为string类型
1 char[]chs={‘1’,‘2’,‘3’}; 2 string str=new string(chs);
求出字符串中所有出现的e的位置
@第一种方法(必须会)
1 string str = "daghdewejhadgwehhjfhajejwwe"; 2 int index = str.IndexOf('e'); 3 Console.WriteLine("第1次出现e的位置是{0}", index); 4 int count = 1; 5 while (index != -1) 6 { 7 index = str.IndexOf('e', index + 1); 8 count += 1; 9 if (index == -1) 10 { 11 break; 12 } 13 Console.WriteLine("第{0}次出现e的位置是{1}", count, index); 14 } 15 Console.ReadKey();
第二种方法
查找多个字的话就不行
1 string str = "daghdewejhadgwehhjfhajejwwe"; 2 for (int i = 0; i < str.Length; i++) 3 { 4 if(str[i]=='e') 5 { 6 Console.WriteLine(i); 7 } 8 } 9 Console.ReadKey();
8.继承
每一个类都要单独写在一个类文件里。
我们可能会在一些类中,写一些重复的成员,我们可以将这些重复的成员,
单独的封装到一个类中,作为这些类的父类。
格式 子类:父类
Student、Teacher、Driver 子类 派生类
Person 父类 基类
子类继承了父类,那么子类从父类那里继承过来了什么?
首先,子类继承了父类的属性和方法,但是子类并没有继承父类的私有字段。能看到也不能用
李一个有钱亲戚挂了,受益人是李,但是没有给他银行密码。他继承过来了却用不了。
问题:子类有没有继承父类的构造函数?
答:子类并没有继承父类的构造函数,但是。子类会默认的调用父类无参数的构造函数,
创建父类对象,让子类可以使用父类中的成员。
所以,如果在父类中重新写了一个有参数的构造函数之后,那个无参数的就被干掉了,
子类就调用不到了,所以子类会报错。
执行完父类无参构造函数,再去执行子类的
执行父类的构造函数,就相当于创建一个父类的对象
因为没有父类的对象,子类没办法用父类的属性
创建子类对象的时候,也顺便创建了他父类的对象,这样才能用到父类的属性和方法,成员
子类包含了自己的属性和父类对象(构造函数),内部的父类又包含了他的属性和方法
继承构造函数的过程可以加入子类的属性
父类默认调用无参的而不是有参的
解决办法:
1)、在父类中重新写一个无参数的构造函数。
2)、在子类中显示的调用父类的构造函数,使用关键字:base()
9.继承的特性
1、继承的单根性:一个子类只能有一个父类。
2、继承的传递性:爷爷-爸爸-儿子-孙子
10.查看类图
右键类文件-视图-查看类图 可以看类之间的继承关系
11.object是所有类的基类。
如果没有让一个类继承于另外一个类,那么这个类就继承于object
12.new关键字
1)、创建对象
2)、隐藏从父类那里继承过来的同名成员。
隐藏的后果就是子类调用不到父类的成员。
子类成员名称和父类成员名称相同,会隐藏继承的父类成员,隐藏后果就是调不到了。
添加new后只是不报错
13.复习
值类型
引用类型
字符串 不可变性
一坨方法
StringBuilder
继承 单根性
传递性
子类跟父类构造函数的关系
子类继承了父类的什么?
new关键字