第九天复习程序员
class Person { //类和对象,类中包含对象 /* 字段:存储数据,不跟类外的打交道 属性:保护字段,对字段的取值和设值进行限定 方法:描述对象的行为 构造函数:初始化对象(给对象的每一个属性依次赋值) 类中的成员,若是不加访问修饰符,默认都是private */ string _name; /// <summary> /// 属性的本质就是两个方法 /// </summary> public string Name { get { return _name; } set { _name = value; } } char _gender; public char Gender { get { return _gender; } set { if(value != '男'&&value != '女') { value = '男'; } _gender = value; } } int _age; public int Age { get { if (_age < 0 || _age > 100) { return _age = 0; } return _age; } set { _age = value; } } //this:1.当前类的对象 public void SayHello() { Console.WriteLine("{0},{1},{2}", this.Name, this.Gender, this.Age); } //静态方法只能访问静态对象,不能有实例对象,实例对象则能够都有 public static void SayHelloTwo() { Console.WriteLine("我是静态方法"); } /* 构造函数 1.没有返回值,连void也没有 2.构造函数名称跟类型如出一辙 */ public Person(string name,char gender,int age) { this.Name = name; this.Gender = gender; this.Age = age; } //this的第二个做用:调用当前类的构造函数 public Person(string name,char gender) : this(name,gender,0) { } } 调用 static void Main(string[] args) { ////new:1.在内存中开辟一块空间 2.在开辟的空间建立对象 3.调用对象的构造函数 //Person zsPerson = new Person("张三",'男',18); //zsPerson.SayHello(); //Person zsPerson = new Person("张三", '中', -18); //zsPerson.SayHello(); //静态对象的调用 类名.对象名 Person.SayHelloTwo(); Console.ReadKey(); }
第十天新内容
1、命名空间(namespace)
用于解决类重名问题,能够看作“类的文件夹”
若是当前项目中没有这个类的命名空间,须要咱们手动的导入这个类所在的命名空间
1.鼠标点
2.alt+shift+F10
3.记住命名空间,手动引用c#
在一个项目中引用另外一个项目的类
1.添加引用 2.引用命名空间
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using _01第九天复习;数组
namespace _02命名空间 { class Program { static void Main(string[] args) { // List<int> list = new List<int>(); Person zsPerson = new Person("张三",'中',-18); //zsPerson.Name = "张三"; zsPerson.SayHello(); Console.WriteLine(zsPerson.Name); Console.ReadKey(); } } }
2、值类型和引用类型
区别
1.值类型和引用类型在内存上存储的地方不同
2.在传递值类型和引用类型的时候,传递的方式不同
值类型称之为值传递,引用类型称之为引用传递
值类型:int、double、bool、char、decimal、struct、enum
引用类型:string、自定义类、数组
存储
值类型的值存储在内存的栈当中
引用类型的值存储在内存的堆当中,引用类型一样在栈上开辟一个空间,存的是堆中的地址,经过栈存的地址来和堆拉上关系ide
3、字符串
1.字符串的不可变性
当你给一个字符串从新赋值后,旧值并无被销毁,而是从新再堆当中开辟一个空间用来存新值,这时候栈上的地址也换成了新开辟空间的地址。
当程序结束时,GC扫描整个内存,发现没有指向的内存,GC就释放该内存的资源。函数
2。咱们能够将字符串看作是char类型的一个只读数组
ToCharArray(); 将字符串转换为char数组
new string(char[] chs):将char数组转换为stringui
static void Main(string[] args) { //能够将string类型看作是char类型的只读数组 string s = "abcdefg"; // s[0] = b; 不能这样作,由于是只读的 //首先将字符串转换为char类型的数组 char[] chs = s.ToCharArray(); chs[0] = 'b'; //将字符数组转回字符串 s = new string(chs); Console.WriteLine(s); //既然能够将string看作char烈性的只读数组,因此能够经过索引去访问字符串中的某一个元素 Console.WriteLine(s[1]); Console.ReadKey(); }
关键字:StringBuilder() 不从新开辟空间this
static void Main(string[] args) { StringBuilder sb = new StringBuilder(); string str = null; //建立一个计时器,用来记录程序运行的时间 Stopwatch sw = new Stopwatch(); sw.Start();//开始计时 for (int i = 0; i < 1000; i++) { //00:00:00.0017008 //str += i; //00:00:00.0002480 sb.Append(i); } sw.Stop();//结束计时 Console.WriteLine(sb.ToString()); Console.WriteLine(sw.Elapsed); Console.ReadKey(); }
字符串提供的各类方法
Length:得到字符串的长度
ToUpper() :将字符串转换为大写
ToLower():将字符串转换为小写
Equals(Equals(Two,StringComparison.OrdinalIgnoreCase)):比较字符串,忽略大小写spa
static void Main(string[] args) { ////练习1:随机输入一个名字,而后输出他的字符串长度 Length:能够获得字符串的长度 //Console.WriteLine("输入名字"); //string name = Console.ReadLine(); //Console.WriteLine("{0}的长度是{1}", name, name.Length); //Console.ReadKey(); ////练习2:两个学员输入各自最喜欢的课程名称,判断是否一致,若是相等,则输出大家两喜欢相同的课程, //// 若是不相同,则输出大家两喜欢不相同的课程 //Console.WriteLine("请输入你喜欢的课程"); //string One = Console.ReadLine(); //Console.WriteLine("请输入你喜欢的课程"); //string Two = Console.ReadLine(); //if (One == Two) //{ // Console.WriteLine("大家喜欢的课程相同"); //} //else //{ // Console.WriteLine("大家喜欢的课程不相同"); //} //Console.ReadKey(); //练习3:上题中两位同窗输入C#和c#表明同一门课,怎么办 Console.WriteLine("请输入你喜欢的课程"); string One = Console.ReadLine(); // One = One.ToUpper();//将字符串转换为大写 // One = One.ToLower();//将字符串转换为小写 Console.WriteLine("请输入你喜欢的课程"); string Two = Console.ReadLine(); // Two = Two.ToUpper();//将字符串转换为大写 // Two = Two.ToLower();//将字符串转换为小写 if (One.Equals(Two,StringComparison.OrdinalIgnoreCase)) { Console.WriteLine("大家喜欢的课程相同"); } else { Console.WriteLine("大家喜欢的课程不相同"); } Console.ReadKey(); }
5.Split():分割字符串,返回字符串类型的数组pwa
////字符串的分割Split //string s = "a b c sdf _ + = , asd"; //char[] chs = { ' ', '_', '+', '=' }; //string[] str = s.Split(chs,StringSplitOptions.RemoveEmptyEntries); //Console.ReadKey(); /* 练习:从日期字符串{"2020-08-08"}中分析出年,月,日;2020年08月08日 让用户输入一个日期格式如:2020-01-02,你输入你输入的日期为2020年1月2日 */ string time = "2020-08-08"; char[] chs = { '-' }; string[] date = time.Split(new char[] { '-' }, StringSplitOptions.RemoveEmptyEntries); Console.WriteLine("{0}年{1}月{2}日", date[0], date[1], date[2]); Console.ReadKey();
6.Replace() :替换字符code
string str = "关键人物杨老"; if (str.Contains("杨老")) { //将杨老替换为** str = str.Replace("杨老", "**"); } Console.WriteLine(str); Console.ReadKey();
7.Substring():截取字符串
//字符串截取 string str = "今每天空晴朗,到处好风光"; //只截取前面两个字符 //str = str.Substring(0,1); //截掉第一个字符 str = str.Substring(1); Console.WriteLine(str); Console.ReadKey();
8.StartsWith()和EndsWith():以什么开头和以什么结尾,返回值都是bool类型
string str = "今每天空晴朗,到处好风光"; if (str.StartsWith("每天")) { Console.WriteLine("是的"); } else { Console.WriteLine("不是的"); } Console.ReadKey();
9.IndexOf和LastIndexOf:查找字符所在字符串中的位置。返回值都是Int类型
//string str = "今每天空晴朗,到处每天好风光"; ////从什么位置开始找 //int index = str.IndexOf('天',2); //Console.WriteLine(index); //Console.ReadKey(); //string str = "今每天空晴朗,到处每天好风光"; //int index = str.LastIndexOf('天'); //Console.WriteLine(index); //Console.ReadKey(); //LastIndexOf Substring 配合使用截取字符串 string path = @"C:\a\b\c\d\e\f\g\\hh\苍老师苍.wav"; int index = path.LastIndexOf("\\"); path = path.Substring(index+1); Console.WriteLine(path); Console.ReadKey();
10.Trim():去掉字符串中的空格
string str = " hahaha "; str = str.Trim();//去掉字符串中全部的空格 str = str.TrimStart();//只去掉前面的空格 str = str.TrimEnd();//只去掉后面的空格 Console.Write(str); Console.ReadKey();
11.IsNullOrEmpty():判断字符串是否为空
string str = null; if (string.IsNullOrEmpty(str)) { Console.WriteLine("是的"); } else { Console.WriteLine("不是的"); }
12.Join():将数组按照指定的字符串链接,返回一个字符串
string[] names = { "张三", "李四", "王五", "赵六" }; //string str = string.Join("|", names); string str = string.Join("|", "张三", "李四", "王五", "赵六"); Console.WriteLine(str); Console.ReadKey();
字符串的练习(这个必定要练熟)
static void Main(string[] args) { ////练习1.接收用户输入的字符串,将其中的字符以与输入相反的顺序输出 //Console.WriteLine("请输入一个字符串"); //string str = Console.ReadLine(); //char[] chs = str.ToCharArray(); //char temp = 'a'; //for (int i = 0; i < chs.Length/2; i++) //{ // temp = chs[i]; // chs[i] = chs[chs.Length - 1 - i]; // chs[chs.Length - 1 - i] = temp; //} //str = new string(chs); //Console.WriteLine(str); //Console.ReadKey(); ////练习2.接收用户输入的依据英文,将其中的单词以反序输出。 //Console.WriteLine("请输入一个字符串"); //string strOne = Console.ReadLine(); //string[] strNew = strOne.Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries); //for (int i = 0; i < strNew.Length/2; i++) //{ // string temp = strNew[i]; // strNew[i] = strNew[strNew.Length - 1 - i]; // strNew[strNew.Length - 1 - i] = temp; //} ////for (int i = 0; i < strNew.Length; i++) ////{ //// Console.Write("{0} ",strNew[i]); ////} //strOne = string.Join(" ", strNew); //Console.WriteLine(strOne); //Console.ReadKey(); ////练习3.从Eemail中提取用户名和域名:abc@163.com //string email = "abc@163.Com"; //int index = email.IndexOf('@'); //string name = email.Substring(0, index); //string yuMing = email.Substring(index+1); //Console.WriteLine("用户名:{0},域名:{1}", name, yuMing); //Console.ReadKey(); /* 文本文件中存储多个文章标题、做者、标题和做者之间用若干空格(数量不定) 隔开,每行一个,标题有长有短,输出到控制台的时候最多标题长度10,若是 超过10,则截取长度8的子串而且最后添加"....",加一个竖线后输出做者的名字 */ ////1.拿到文本文件里面的数据 //string path = @"C:\Users\Administrator\Desktop\1.txt"; //string[] contents = File.ReadAllLines(path, Encoding.Default); //for (int i = 0; i < contents.Length; i++) //{ // string[] ss = contents[i].Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries); // Console.WriteLine((ss[0].Length>10?ss[0].Substring(0,8)+"......":ss[0]) + "|" + ss[1]); //} //Console.ReadKey(); ////练习4.让用户输入一句话,找出全部e的位置 //Console.WriteLine("请输入一句话"); //string strTwo = Console.ReadLine(); //int index = strTwo.IndexOf('e'); //Console.WriteLine("第一次出现e的位置是{0}", index); ////循环体:从上一次出现e的位置加1的位置找下一次e出现的位置 ////循环条件:index != -1 //int count = 1; //while (index != -1) //{ // count++; // index = strTwo.IndexOf("e", index + 1); // if (index == -1) // { // break; // } // Console.WriteLine("第{0}此出现e的位置是{1}", count, index); //} //Console.ReadKey(); ////练习5.让用户输入一句话,判断这句话有没有邪恶,若有鞋子就替换成** //Console.WriteLine("请输入一句话"); //string strThere = Console.ReadLine(); //if (strThere.Contains("邪恶")) //{ // strThere = strThere.Replace("邪恶", "****"); //} //Console.WriteLine(strThere); //Console.ReadKey(); ////练习6.把{"诸葛亮","卡卡西","鸟叔","卡哇伊"}变成诸葛亮|卡卡西|鸟叔|卡哇伊,而后再把|切割掉 //string[] strs = { "诸葛亮", "卡卡西", "鸟叔", "卡哇伊" }; //string strFor = string.Join("|", strs); //char[] chs = { '|' }; //strs = strFor.Split(new char[] { '|' }, StringSplitOptions.RemoveEmptyEntries); //for (int i = 0; i < strs.Length; i++) //{ // Console.WriteLine(strs[i]); //} //Console.WriteLine(strFor); //Console.ReadKey(); }
4、面向对象(继承)
把多个类中重复的成员单独拿出来封装成一个类,做为这几个类的父类,从而解决多个类中出现重复的成员形成代码冗余
Student、teacher、driver 子类 派生类
Person 父类 基类
子类继承父类的:属性、方法。不能继承父类的私有字段
继承的特性
一、继承的单根性(子类只能继承一个父类)
二、继承的传递性(父类让一个子类继承后,其余子类在继承这个子类时,同样能够访问到父类。多个子类传递继承,则均可以访问到所传递继承的类)
子类不会继承父类的构造函数,可是,子类会默认的调用父类无参数的构造函数。让子类可使用父类中的成员。
因此,若是在父类中从新写了一个有参数的构造函数以后,那个无参数的就被干掉了,子类就调用不到,因此子类会报错。
解决办法
1.在父类中在写一个无参数的构造函数(通常不这么作)
2.使用关键字:base调用父类中的构造函数
object是全部类的基类。
关键字:new隐藏父类成员
子类有成员跟父类成员重名,父类的会被默认隐藏
继承相关代码
父类
class Person { private string _name; public string Name { get { return _name; } set { _name = value; } } private char _gender; public char Gender { get { return _gender; } set { _gender = value; } } private int _age; public int Age { get { return _age; } set { _age = value; } } public Person(string name,int age,char gender) { this.Name = name; this.Age = age; this.Gender = gender; } public void SayHello() { Console.WriteLine("我是父类的SayHello"); } }
司机类
class Driver:Person { public Driver(string name,int age,char gender,int driverTime):base(name,age,gender) { this.DriverTime = driverTime; } private int _driverTime; public int DriverTime { get { return _driverTime; } set { _driverTime = value; } } public void DriverSay() { Console.WriteLine("我是一名{0},我有{1}岁,我是{2}人,个人驾龄是{3}", this.Name, this.Age, this.Gender, this.DriverTime); } public new void SayHello() { Console.WriteLine("我是司机类的SayHello"); } }
记者类
class Reporter:Person { public Reporter(string name,int age,char gender,string hobby):base(name,age,gender) { this.Hobby = hobby; } private string _hobby; public string Hobby { get { return _hobby; } set { _hobby = value; } } public void ReporterSay() { Console.WriteLine("我是一名{0},我有{1}岁,我是{2}人,个人爱好是{3}",this.Name,this.Age,this.Gender,this.Hobby); } //使用new关键字将从父类中继承的重名方法隐藏 public new void SayHello() { Console.WriteLine("我是记者类的SayHello"); } }
程序员类
class Programmer:Person { public Programmer(string name,int age,char gender,int time):base(name,age,gender) { this.Time = time; } private int _time; public int Time { get { return _time; } set { _time = value; } } public void ProgrammerSay() { Console.WriteLine("我是一名{0},我有{1}岁,我是{2}人,个人工龄是{3}", this.Name, this.Age, this.Gender, this.Time); } public new void SayHello() { Console.WriteLine("我是程序员的SayHello"); } }
在MAIN函数中调用
static void Main(string[] args) { //记者:我是一个狗仔,我爱好是偷拍,个人年龄是34,我是一个男狗仔 //司机:我叫舒马赫 个人年龄是43 我是男人 个人驾龄是23年 //程序员:我叫孙权 个人年龄是23 我是男生 个人工做年限是3年 Reporter reporter = new Reporter("记者",34,'男',"偷拍"); reporter.ReporterSay(); Driver driver = new Driver("司机", 43, '男', 20); driver.DriverSay(); Programmer programmer = new Programmer("程序员", 25, '男', 3); programmer.ProgrammerSay(); programmer.SayHello(); Console.ReadKey(); }