C#的函数&方法
解释:
函数就是讲一堆代码进行重用的一种机制,函数就是一堆代码,这段代码可能有输入的值(参数),可能会返回值,一个函数就像一个专门做这件事的人,我们调用他来做一些事情,他可能需要我们提供一些数据给他,他执行完后可能会有一些执行结果给我们。要求的数据就叫参数,返回值的执行结果就是返回值。
函数的语法
访问修饰符 修饰符 返回值类型 方法名(参数列表)
{
语句块;
}
[public] static 返回值类型 方法名([参数列表])
{
方法体;
}
Public:访问修饰符,公开的,公共的,那都可以访问
public
成员可以被任何代码访问。
2) private
成员仅能被同一个类中的代码访问,如果在类成员前未使用任何访问修饰 符,则默认为private。
3) internal
成员仅能被同一个项目中的代码访问。
4) protected
受保护的明知呢个在当前类的内部以及该类的子类中访问
Static:静态的(修饰符)
返回值类型:如果不需要写返回值,写void
方法名:Pascal 每个单词的首字母大写,其余字母小写
参数列表:完成这个方法必须提供给这个方法的条件。如果没有参数小括号也不能省略
方法写好之后,如果想执行,必须要在Main函数里进行调用。
方法的调用语法:
关键字 变量名 = 类名.方法名(参数);
在某些情况下,类名是可以省略的,如果你写的方法跟Main()函数在同一个类中,这个时候,类名可以省略。
Return
1、 在方法中返回要返回的值
2、 立即结束本次方法
例如:
namespace ConsoleApp29
{
internal class Program
{
static void Main(string[] args)
{
//计算两个整数之间的最大值
int max = Program.GetMax(1, 3);
Console .WriteLine (max);
Console.ReadKey();
}
/// <summary>
/// 计算两个整数之的最大值并且将最大值返回
/// </summary>
/// <param name=”n1″>第一个整数</param>
/// <param name=”n2″>第二个整数</param>
/// <returns>将最大值返回</returns>
public static int GetMax(int n1,int n2 )
{
return n1>n2 ? n1 : n2;
}
}
}
函数&方法的调用
我们在在Main()函数中,调用Test()函数,我们管Main()函数称之为调用者,管Test()函数称之为被调用者。
如果被调用者想要得到调用者的值
1, 传递参数
2, 使用静态字段来模拟全局变量(C#当中没有全局变量)public static int _number = 10;(声明到类当中)
3, 返回值
2,不管是实参或是形参都是在内存里开辟了一块空间的
static void Main(string[] args)
{
//比较两个数字的大小
int n1 = 10;
int n2 = 20;
GetMax(n1,n2);//实参
}
/// <summary>
/// 计算两个整数之间的最大值 并返回最大值
/// </summary>
/// <param name=”n1″>第一个数</param>
/// <param name=”n2″>第二个数</param>
/// <returns>返回ide最大值</returns>
public static int GetMax(int n1,int n2)//形参
{
int max =n1 > n2 ? n1 : n2;
return max;
}
方法功能一定要单一!!!
不要提示用户输入在函数和方法中
特殊参数
Out参数
释义:如果你在一个方法里,返回了多个相同类型的值的时候,可以考虑返沪一个数组。但是,如果返回多个不同类型的值的时候,返回数组就不行了。,那么这个时候数组就不行了,那么这个时候,我们可以考虑使用out参数。
Out参数就侧重于在一个方法中可以返回多个,要求方法内部变量赋值
不同类型的值
Out的应用
public static void Test(int[] nums,out int max,out int min,out int sum,out int avg)在行参列表之中协商要多余返回的那几个值(out参数要求在方法内部必须对其进行赋值)
{
}
用数组:
namespace Out参数
{
internal class Program
{
static void Main(string[] args)
{
int[] numbers = {1,2,3,4,5,6,7,8,9};
//将要返回的四个值,放到一个数组中返回
int[] res=GetMaxMinSunAvg (numbers);
Console.WriteLine(“最大值是{0},最小值{1},总和{2},平均值{3}”, res[0], res[1], res[2], res[3]);
Console.ReadKey();
}
/// <summary>
/// 计算一个数组的最大值,最小值,总和,平均值
/// </summary>
/// <param name=”nums”></param>
/// <returns></returns>
public static int[] GetMaxMinSunAvg(int[]nums)
{
int[] res = new int[4];
//假设 res[0]最大值 res[1]最小值 res[2]总和 res[3]平均值
res[0] =nums[0];//max最大值
res[1] =nums[0];//min最小值
res[2] = 0;//sum总和
for (int i = 1; i < nums.Length; i++)
{
//如果当前循环的元素比我假定的还大
if(nums[i]>res[0])
{
//将当前循环的元素赋值给我的最大值
res[0] = nums[i];
}
if(nums[i]>res[1])
{
//最小值
res[1] = nums[i];
}
res[2]+=nums [i];
}
res[3] = res[2] / nums.Length;
return res;
}
}
}
用Out参数
namespace Out
{
internal class Program
{
static void Main(string[] args)
{
int[] number = { 0,1,2,3,4,5,6,7,8,9};
int max = 0;
int min = 0;
int sum = 0;
int avg = 0;
Test(number, out max, out min, out sum, out avg);
Console.WriteLine(max );
Console.WriteLine(min );
Console.WriteLine(sum );
Console.WriteLine(avg );
Console.ReadKey();
}
/// <summary>
/// 计算一个数组的最大值,最小值,平均值,总和
/// </summary>
/// <param name=”nums”>要求值得数组</param>
/// <param name=”max”>多余返回的最大值</param>
/// <param name=”min”>多月返回的最小值</param>
/// <param name=”sum”>多月返回的总和</param>
/// <param name=”avg”>多于返回的平均值</param>
public static void Test(int[] nums,out int max,out int min,out int sum,out int avg)
{
max = nums[0];
min = nums[0];
sum = 0;
for (int i=0; i < nums.Length; i++)
{
//最大值
if (nums[i] > max)
{
max = nums[i];
}
//最小值
if (nums[i] < min)
{
min = nums[i];
}
//总和
sum += nums[i];
}
//平均值
avg = sum / nums.Length;
}
}
}
Out 2
namespace ConsoleApp2
{
internal class Program
{
static void Main(string[] args)
{
Console.WriteLine(“请输入用户名”);
string userName = Console.ReadLine ();
Console.WriteLine(“请输入密码”);
string userPwd = Console.ReadLine();
string msg;
bool b= IsLogin(userName, userPwd, out msg);
Console.WriteLine(“登录结果{0}”, b);
Console.WriteLine(“登录信息{0}”, msg);
Console.ReadKey();
}
/// <summary>
/// 判断用户是否登陆成功
/// </summary>
/// <param name=”name”>用户名</param>
/// <param name=”pwd”>密码</param>
/// <param name=”msg”>多余返回的登录信息</param>
/// <returns>返回登陆结果</returns>
public static bool IsLogin(string name,string pwd,out string msg)
{
if (name == “admin”&&pwd == “123456”)
{
msg = “登陆成功”;
return true;
}
else if (name == “admin”)
{
msg = “密码错误”;
return false;
}
else if( pwd ==”123456″)
{
msg = “用户名错误”;
return false;
}
else
{
msg = “未知错误”;
return false;
}
Ref参数
释义:能够让几个变量带入一个方法中进行改变,改变完成后,再讲改变之后的值带出方法,ref参数要求在方法外必须赋值,而方法内可以不赋值。
(可以不用写返回值只写一个void)
实例:
static void Main(string[] args)
{
//工资5000
double salary = 5000;
//调用JiangJin方法
JiangJin(ref salary);
Console.WriteLine(salary );
Console.ReadKey();
}
//获得奖金之后工资+500
public static void JiangJin(ref double s)
{
s += 500;
}
实例
static void Main(string[] args)
{
int n1 = 10;
int n2 = 20;
Test(ref n1,ref n2);
Console.WriteLine(n1);
Console.WriteLine(n2);
Console.ReadKey();
}
public static void Test(ref int n1,ref int n2)
{
int temp = n1;
n1 = n2;
n2 = temp;
}
Params可变参数
释义:将实参列表中跟可变参数数组类型一致的元素都当做数组的元素,params可变参数必须是形参列表中的最后一个元素。
实例1
static void Main(string[] args)
{
Test(“张三”, 99,88,77);
Console.ReadKey();
}
public static void Test(string name ,params int[] score)
{
int sum = 0;
for (int i=0;i<score.Length; i++)
{
sum += score[i];
}
Console .WriteLine (“{0}这次考试的总成绩是{1}”,name ,sum );
}
方法的重载
概念:方法的重载指的就是方法的名称相同,但是参数不同
参数不同,分为两种情况
1, 如果参数的个数形同,那么参数的类型就不能相同。
2, 如果参数的类型相同,那么参数的个数就不能相同。
***发方法的重载跟返回值没有关系。
public static void M(int n1, int n2)
{
int result = n1 + n2;
}
public static double M(double d1, double n2)
{
return d1 + n2;
}
public static void M(int n1, int n2, int n3)
{
int result = n1 + n2 + n3;
}
public static string M(string s1, string s2)
{
return s1 + s2;
}
方法的递归
方法自己调用用自己
找出文件夹中所有文件
面向对象
面向过程>>>>面向对象
面向对象:面向的是完成这件事的过程,强调是完成这件事的动作。
如果我们用面向过程的思想来解决这件事,当执行这件事的人的不同的时候,我们需要位每个不同的人量身定做解决事情的方法。
面向对象:找个对象帮你做事(通用的代码)
把大象放进冰箱里
我们把冰箱作为对象:
1, 冰箱门可以被打开
2, 大象可以被塞进冰箱里
3, 冰箱门可以被关闭
A 调用 函数1
A 调用 函数2——通用,谁都可以使用方法(同理B,C,D都可以使用方法完成把大象放进冰箱)
A 调用 函数3
面向对象:意在写出一个通用的代码,屏蔽差异
面向过程:关门
张三 一脚踹开门
李四 轻轻的·关门
王五 们没关严,留了个尾巴
面向对象:门(对象一般都是被动的)
门可以被关闭 张三,李四,王五都可以关闭门
我们在代码中描述一个对象,通过描述这个对象的属性和方法
对象是看得见摸得着的
我们把这些具有相同属性和相同方法的对象进行进一步的封装,抽象出来,类这个概念。类就是个模子,去定了对象应该具有的属性和方法。对象是根据类创建出来的类是抽象的,对象是实在的
类
类:类是模子,确定对象将会拥有的特这个(属性)和行为(方法)
类:类就是一个盖大楼的图纸 对象:就是改出来的大楼。
语法:
public class 类名
{
字段;(存储数据的)
属性;(属性的作用是保护字段,对字段的复制和取值进行限定)
方法;(函数)
}
写好一个类之后,我们需要创建这个类的对象,那么,我们管创建这个类的对象的过程称之为类的实例化。
使用关键字new
This:表示这个类的对象。
类是不占内存的,而对象是占内存的
属性的·本质就是两个方法,一个get{ }一个set{ }
Field字段
Method方法
Property属性
当你输出属性的值的时候,会执行get方法
get { return _name;}
当你给属性赋值的时候,首先会执行set方法
set { _name = value;}
Value是参数,外边传的参数赋值给字段
Person类:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ConsoleApp46
{
internal class person
{
private string _name;
public string Name
{
get {
if (_name !=”孙全”)
{
return _name=”孙全”;
}
return _name; }
set { _name = value; }
}
private int _age;
public int Age
{
get { return _age; }
set {
if (value <0||value >100)
{
value = 0;
}
_age = value; }
}
char _gender;
public char Gender
{
get {
if (_gender !=’男’&&_gender !=’女’)
{
return _gender;
}
return _gender; }
set { _gender = value; }
}
public void SayHello()
{
Console.WriteLine(“我叫{0},我今年{1}岁了,是{2}生”,this.Name ,this.Age ,this.Gender);
}
}
}
调用
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ConsoleApp46
{
internal class Program
{
static void Main(string[] args)
{
person p = new person();
p.Age = 10;
p.Name = “张三”;
p.Gender = ‘男’;
p.SayHello();
person p2=new person();
p2.Name = “李四”;
p2.Age = 88;
p2.Gender =’女’;
p2.SayHello();
}
}
}
静态和非静态的区别-面向对象初级
1,非静态类中,既可以有实列成员,也可以有静态成员
2在调用实例成员的时候,需要使用对象名,实例成员
在调用静态成员的时候,需要使用类名.静态成员名
4, 静态成员必须使用类名去调用,而实例成员使用对象名去调用
静态:
private static string _name;
public static string Name
{
get { return Person._name; } 2
set { Person._name = value; }
}
非静态
private char _gender;
public char Gender
{
get { return _gender; }
set { _gender = value; }
}
5,静态函数中,只能访问静态成员,不允许访问实例成员。
6,实例函数中,既可以使用静态成员,也可以使用实例成员
7,静态类中只允许有静态成员,不允许出现实列成员
使用:
1, 如果你想要你的类当作一个“工具类”去使用,这个时候可以考虑将类写成静态类
工具类:典型CONSOLE类,经常会用到的东西写成一个类就是工具类
2, 静态类在整个项目中资源共享
构造函数
作用帮助我们初始化对象(给对象的每个属性一次的赋值)
构造函数是一个特殊的方法
1, 构造函数没有返回值,连void也不能写
2, 构造函数名称必须跟类名一样
类当中会有一个默认的无参数的构造函数,当你写一个新的构造函数之后,不管是有参数的或是无参数的,那个默认的无参数的构造函数都被干掉了。
创建对象的时候会执行构造函数
3, new关键字
Person zsPerson=new Person();
1,在内存中开辟一块内存
2,在开辟的空间中创建对象
4, 调用对象的构造函数进行初始化对象
类:
public Student (string name,int age,char gender,int chinese,int math,int english)
{
this .Name = name;
this.Age = age;
this.Gender = gender;
this.Chinese = chinese;
this.Math = math;
this.English = english;
}
private string _name;
public string Name
{
get { return _name; }
set { _name = value; }
}
private int _age;
public int Age
{
get { return _age; }
set
{
if (value < 0 || value > 100)
{
value = 0;
}
_age = value;
}
}
private char _gender;
public char Gender
{
get
{
if (_gender != ‘男’ && _gender != ‘女’)
{
return _gender = ‘男’;
}
return _gender;
}
set { _gender = value; }
}
private int _chinese;
public int Chinese
{
get { return _chinese; }
set { _chinese = value; }
}
private int _math;
public int Math
{
get { return _math; }
set { _math = value; }
}
private int _english;
public int English
{
get { return _math; }
set { _math = value; }
}
public void SayHello()
{
Console.WriteLine(“我叫{0},我今年{1}岁了,我是{2}生”, this.Name, this.Age, this.Gender);
}
public void ShowScore()
{
Console.WriteLine(“我叫{0},我的总成绩是{1},平均分是{2}”, this.Name, this.Chinese + this.English + this.Math, (this.Chinese + this.English + this.Math) / 3);
}
Main函数
Student zsStudent=new Student(“张三”, ‘男’, 100, 100, 100);
zsStudent.SayHello();
zsStudent.ShowScore();
Student xlStudent = new Student(“小兰”,16,’女’,50,50,50);
xlStudent.ShowScore();
xlStudent.SayHello();
this
1, 代表当前类的对象
2, 在类中显示的调用本类的构造函数 :this()
析构函数
当程序结束时,析构函数执行,帮助我们释放资源
语法
~ 类名()
{
}
~ student()
{
}
命名空间
可以认为类是属于命名空间的
如果在当前项目中没有这个类的命名空间,需要我们手动导入这个类所在的命名空间
一
1),用鼠标去点
2),alt+shift+F10
3),记住命名空间,手动引用
二,在一个项目中去引用另一个项目的类
1, 添加引用 Using 类名;
2, 引用命名空间
值类型和引用类型
区别
1, 值类型和引用类型你在内存上存储的地方不一样
2, 在传递值类型和传递引用类型的时候,传递的方法不一样
值类型我们称之为值传递,引用类型我们称之为引用传递
值类型:int,double,bool,char,decimal,struct,enum
引用类型:string,自定义类
值类型的值是存储在内存的栈中
引用类型存储在内存的堆中
字符串的不可变性
1,当你给一个字符串重新赋值后,老值并没有销毁,而是重新开辟一块空间存储
当程序结束后,GC(垃圾内存回收器)扫描整个内存,如果发现有的空间没有被只想,则立即把他销毁
3, 我们可以将字符串看作是char类型的一个只读(只能读取不能更改)数组,既然可以将string看作char类的只读数组,所以我可通过下表去访问字符串中的摸一个元素
4, 字符串提供的个种方法
1)length:获得当前字符串中字符的个数
2,ToUpper():将字符串转换为大写形式
3),ToLower():将字符串转换为小写形式,
4),Equals(lesstwo,StringComparison.CurrentCultureIgnoreCase):比较两个字符串是否相同,忽略大小写
5),Split():分割字符串没返回字符串类型的数组
6),Substring():解决字符串,在截取的时候包含要截取的那个位置。
7),IndexOf():判断某个字符串在字符串中第一次出现的位置,若没有返回一个-1
8),LastIndexOf():判断某个字符串在字符串中最后一次出现的位置,如果没有返回-1
9),StartWith():判断以什么 什么开始
10),EndsWith():判断以什么 什么结束
11),Replace():判断字符串中是否包含指定的字符串
12),Contains():判断某个字符串是否包含指定的字符串
13),Trim():去掉字符串中的前后的空格
14),TrimEnd():去掉字符串中结尾的空格
15),TrimStart():去掉字符串中前面的空格
16),IsNullOrEmpty():判断一个字符串是否为空或者位null
17),String.Join():将数组按照指定的字符串连接,返回一个字符串
练习:
Console.WriteLine(“请输入你喜欢的课程”);
string lessone = Console.ReadLine();
//lessone = lessone.ToUpper();
Console.WriteLine(“请输入你喜欢的课程”);
string lesstwo=Console .ReadLine();
//lesstwo = lesstwo.ToUpper();
if (lessone.Equals (lesstwo,StringComparison.CurrentCultureIgnoreCase))
{
Console.WriteLine(“你们俩喜欢的课程相同”);
}
else
{
Console .WriteLine(“你们俩喜欢的课程不同”);
}
Console.ReadKey();
string s = “abcdefg”;
Console.WriteLine(s[0]);
Console .ReadKey ();
5),Split()分割字符串,返回字符串类型的数组
5, 如果要改变数组,首先将字符串转换为char类型的数组
char[] chs = s.ToCharArray();
chs[0] = ‘b’;
TO转向,char类型,Array数组
将字符数转换位我们的字符串
s = new string (chs)能够将char数组转换为字符串
String Bulider(内存垃圾回收器,优化程序运行速度)
StringBuilder sb= new StringBuilder();
String str = null;//null是空的意思
Stopwatch sw = new Stopwatch();
//创建一个计时器
sw.Start();
for (int i = 0; i < 10; i++)
{
//str += i;
sb.Append(i);
}
sw.Stop();
Console.WriteLine(sw.Elapsed);
Console.ReadKey();
继承
我们可能会在一些类中,写一些重复的成员,我们可以将这些重复的成员。
单独的封装到一个类中,作为这些类的父类
Student,teacher,Drive,子类 派生类
Person 父类 基类
子类继承了父类,那么子类从父类那里继承过来了什么?
子类能访问到的属性和方法,但是子类并没继承父类的私有字段
子类没有 继承 父类的构造函数,但是,子类会默认调用父类无参数的·构造函数。
创建 父类 对象,让子类可以使用父类中的成员。
所以,如果在父类中重现写了一个有参数的构造函数之后,那个无参数的具备干掉了。
子类调用不到了,所以子类会报错
解决方法
1),在父类中重新写一个无参数的构造函数
2),在子类中显示的调用 父类 的构造函数函数,使用关键字 :base():
继承的特性
1, 继承的单根性,一个子类只能有一个父类
2, 传递性
3, 子类没有继承构造函数
Object是所有类的基类
NEW关键字
1, 创建对象
2, 隐藏从父类那里继承过来的同名成员 隐藏的后果就是子类调用不到父类的成
里氏转换
1, 子类可以赋值给父类,如果有一个地方血药一个父类作为参数,我们可以给一个子类代替
2, 如果父类重装的是子类对象,那么可以将个父类强转为子类
子类对象可以调用父类中的成员,但是父类对象永远都之呢个调用自己的成员
Is:表示类型转换,如果能够转换成功,则返回一个true,否则返回一个false
as:表示类型转换,如果能够转换则返回对应的对象,都则返回一个null
ArrayList集合
集合,有很多数据的一个集合
集合的好处:长度可以任意改变,类型随便
ArrayList list = new ArrayList();
list.Add(1);
list.Add(3.14);
list.Add(true);
list.Add(“张三”);
list.Add(‘男’);
list.Add(5000m);
list.Add(new int[] { 1, 2, 3, 4, 5, 6, 7, 8, 9 });
Perosn p = new Perosn();
list.Add(p);
list.Add(list);
list .AddRange ();可以直接输出数组,集合
list.Clear();清空所有元素
list.Remove(true);删除单个元素
list.RemoveAt(0);根据下标删除元素
list.RemoveRange(0,3);根据下标删除一定范围的元素
list.Sort();升序排列
list.Reverse();反转
list.insert(1,”插入的”);在指定的位置插入一个元素
list.InsertRange(0,new string []”张三”,“李四“});在指定的位置插入一个集合
bool b =list.Contains(1);判断是某个指定的元素
ArrayList集合的长度问题
每次集合中实际包含的元素个数(count超过了可以包含的元素的个数(capcity)的时候
集合就会像内存中盛情多开辟已被的控件,来保证集合的长度一直够用。
List泛型集合
List <int > list=new List<int>();
list.Add(1);
list.Add(2);
list.Add(3);
list.AddRange(new int[] { 1, 2, 3, 4, 5, 6, });
list.AddRange(list);
int [] nums=list.ToArray();
for (int i = 0; i < list .Count ; i++)
{
Console.WriteLine(list[i]);
}
Console.ReadKey();
Foreach循环
foreach (var item in collection)
{
}
Var:推断集合中项的类型
Item:集合中的每一项
In:在什么里
Collection:集合
Hastable键值对集合
在键值对集合当中,我们是根据键去找值的。
键值对对象[键]=值
****键值对集合当中,键必须是唯一的,而值是可以重复的
Hashtable ht=new Hashtable();
ht.Add(1, “张三”);
ht.Add(2, true);
ht.Add(3, ‘男’);
ht.Add(false, “错误的”);
ht[6]= “新来的”;
Dictionary字典集合
Dictionary <int ,string >dic=new Dictionary<int ,string>();
dic.Add(1, “张三”);
dic.Add(2, “李四”);
dic.Add(3, “王五”);
dic[1] = “新来的”;
foreach (KeyValuePair <int ,string >kv in dic )
{
Console.WriteLine(“{0}—{1}”,kv.Key, kv.Value);
}
foreach (var item in dic .Keys )
{
Console.WriteLine(“{0}—-{1}”, item, dic[item]);
}
Console.ReadKey();
Path类
string str = @”C:\3000soft\Red Spider\Data\Message\老赵 . wav”;
//获得文件名
Console.Writeline(Path.GetFileName(str));
// 获得文件名但是不包含扩展名
Console.WriteLine(Path.GetF ileNameWithoutExtension(str));
//获得文件的扩展名
Console.Writeline(Path.GetExtension(str));
//获得文件所在的文件夹的名称
Console.WriteL ine(Path.GetDirectoryName(str));
//获得文件所在的全路径
Console.WriteLine(Path.GetFullPath(str));
//连接两个字符串作为路圣
Console.WriteLine(Path.Combine(@”c:\a\”,”b.txt”));
File类
绝对路径:通过给定的这个路径直接能在我的电脑中找到这个文件
相对路径:文件相对于应用程序的路径
绝对路径:string str = File.ReadAllText(@”E:\qwer.txt”);
相对路径:string str = File.ReadAllText(“Ewer.txt”);
开发中使用相对路径
1,创建文件
File.Create(@”E:\new.mp4″);
Console.WriteLine(“创建成功”);
Console.ReadKey();
2,删除文件
File.Delete(@”E:\new.mp4″);
Console.WriteLine(“删除成功”);
Console.ReadKey();
3,复制文件
File.Copy(@”E:\大自然.MP4″,@”E:\A”);
Console.WriteLine(“复制成功”);
Console.ReadKey();
4,判断文件是否存在
bool b = File.Exists(@”E:\大自然.mp4″);
Console.WriteLine(b);
Console.ReadKey();
5,剪切
File.Move(@”E:\大自然.mp4″, @”E:\A”);
Console.WriteLine(“剪切成功”);
Console.ReadKey();
6, 读取文件信息
读取字节(读取音乐图像视频这些文件用这个)
byte[] buffer = File.ReadAllBytes(@”E:\qwer.txt”);
Encoding采取编码读取方式 Default自己选找编码格式 GetString获得字符串
string str = System.Text.Encoding.Default.GetString(buffer);
Console.WriteLine(str);
Console.ReadKey();
数组一行一行的读取(精确的操纵每一行数据)
string[] str = File.ReadAllLines(@”E:\qwer.txt”,Encoding.Default );
for (int i = 0; i < str.Length; i++)
{
Console.WriteLine(str[i]);
}
Console.ReadKey();
String形式读取
string str = File.ReadAllText(@”E:\qwer.txt”,Encoding.Default);
Console.WriteLine(str);
Console.ReadKey();
写入
以字符串数组形势写入信息
File.WriteAllLines(@”E:\qwer.txt”, new string[] { “bpmof”, “detenele” });
Console.WriteLine(“OK”);
Console.ReadKey();
字符串形势写入
File.WriteAllText(@”E:\qwer.txt”, “张三李四王五”);
Console.WriteLine(“OK”);
Console.ReadKey();
不覆盖写入
File.AppendAllText(@”E:\qwer.txt”, “输入滚动发”);
装箱和拆箱
装箱:将值类型转换为引用类型
拆箱:将引用类型转换为值类型
看两种类型是否发生了装箱和拆箱,要看这两种而类型是否发生了继承关系
装箱
int n = 10;
object o = n;//装箱
拆箱
int nn = (int)o;
文件流 FileStream StreamReader和StreamWrite
文件流和File最大的不同是一点一点的读取文件,适用于大型文件
FileStream:操作字节
StreamReader和StreamWrite操作字符的
FileStream怎么用
将创建文件流对象的过程写在using当中,会自动的帮助我们释放流所占用的资源
using()
{
}
读取数据
创建文件流
传参需要三个参数:1,文件路径2,针对这个文件做什么操作3,对数据进行操作
Filemode指定操作系统打开文件的方式(枚举类型)
调用OpenOrCreate有打开没有就创建
FileStream fsRead = new FileStream(@”E:\sss.txt”, FileMode.OpenOrCreate, FileAccess.Read);
创建一个字节数组来限定每次读多少1024KB*1024KB*5=5MB
byte[] buffer = new byte[1024*1024*5];
返回int类型来接收=让这个对象去读取(字节数组限定每次读取的数组,0最开始读数据,最多读5MB)
返回本次实际读取到的有效字节数
int r = fsRead.Read(buffer, 0, buffer.Length);
将字节数组中每一个元素读取按照指定的编码格式解码成字符串Encoding编码,Default是自己选择编码格式
string s =Encoding.Default.GetString(buffer,0,r);
关闭流
fsRead.Close();
释放流所占用的资源
fsRead.Dispose();
Console.WriteLine(s);
Console.ReadKey();
写入数据
using(FileStream fsWrirte=new FileStream(@”E:\abc.txt”,FileMode.OpenOrCreate,FileAccess.Write ))
{
string str = “我叫鹿共禾”;
byte[] buffer = Encoding.Default.GetBytes(str);
fsWrirte.Write(buffer, 0, buffer.Length);
}
Console.WriteLine(“创建成功”);
Console.ReadKey();
复制多媒体文件
static void Main(string[] args)
{
//思路:就是将复制的多媒体文件读出来,然后再写入到你指定的位置
string source = @”E:\sss.mp4″;
string target = @”E:\asb”;
CopyFile(source, target);
Console .WriteLine (“成功”);
Console.ReadKey();
}
public static void CopyFile(string source,string target)
{
//创建一个负责读取的流
using (FileStream fsRead =new FileStream (source ,FileMode.Open,FileAccess.Read))
{
//创建一个负责写入的流
using (FileStream fsWrite = new FileStream (target ,FileMode.OpenOrCreate,FileAccess.Write ))
{
//字节数组限定一次读取5mb
byte[] buffer = new byte[1024 * 1024 * 5];
//因为文件可能比较大,所以我们在读取的时候,应当通过一个循环去读
while (true )
{
//返回本次读取实际读取到的字节数
int r = fsRead.Read(buffer, 0, buffer.Length);
//如果返回一个0,也就意味着什么都没有读取到,读取完了
if (r==0)
{
break;
}
//写入调用
fsWrite.Write(buffer, 0, r);
}
}
}
StreamReader
using (StreamReader sr =new StreamReader (@”E:\abc.txt”,Encoding .Default ))
{
while (!sr.EndOfStream)
{
Console.WriteLine(sr.ReadLine());
}
}
Console.ReadKey();
StreamWrite
using (StreamWriter sw=new StreamWriter (@”E:\abc.txt”))
{
sw.Write(“今天天气好晴朗,处处好风光”,true);
}
Console.WriteLine(“OK”);
Console.ReadKey();
多态
概念:让一个对象能够表现出多种的状态(类型)
实现多态有三种
虚方法,抽象,接口
虚方法
步骤
1, 将父类的方法标记成虚方法,使用关键字 virtual,这个函数可以被子类重新写一遍
子类函数用override
namespace ConsoleApp62
{
internal class Program
{
static void Main(string[] args)
{
Chinese cn1 = new Chinese(“韩梅梅”);
Chinese cn2 = new Chinese(“李雷”);
Jb j1 = new Jb(“田所浩二”);
Jb j2 = new Jb(“114514”);
Kb k1 = new Kb(“朴珍希”);
Kb k2 = new Kb(“金线绣”);
Am A1 = new Am(“科比布莱恩特”);
Am A2 = new Am(“川建国”);
Person[] pers = { cn1, cn2, j1, j2, k1, k2, A1, A2 };
for (int i = 0; i < pers.Length; i++)
{
pers[i].SayHello ();
}
Console.ReadKey ();
}
}
public class Person
{
private string _name;
public string Name
{
get { return _name; }
set { _name = value; }
}
public Person(string name)
{
this.Name = name;
}
public virtual void SayHello()
{
Console.WriteLine(“我是人类”);
}
}
public class Chinese : Person
{
public Chinese(string name) : base(name)
{
}
public override void SayHello()
{
Console.WriteLine(“我是中国人,我叫{0}”, this.Name);
}
}
public class Jb : Person
{
public Jb(string name) : base(name)
{
}
public override void SayHello()
{
Console.WriteLine(“我是日本人,我叫{0}”, this.Name);
}
}
public class Kb : Person
{
public Kb(string name) : base(name)
{
}
public override void SayHello()
{
Console.WriteLine(“我是韩国人,我叫{0}”, this.Name);
}
}
public class Am : Person
{
public Am(string name) : base(name)
{
}
public override void SayHello()
{
Console.WriteLine(“我是美国人,我叫{0}”, this.Name);
}
}
}
抽象类
当父类中的方法不知道如何去实现的时候,可以考虑将父类写成抽象类,将方法写成抽象方法。
1,抽象成员必须标记为abstract,并且不能有任何实现
2, 抽象成员必须在抽象类里
3, 抽象类不能实例化
4, 子类继承抽象类后,必须把父类中的所有抽象成员都重写。(除非子类也是抽象类)
5, 可以包含实例成员
6, 抽象类有构造函数,但是不能被实例化
7、如果父类的抽象方法中有参数,那么。继承这个抽象父类的子类在重写父类的方法的时候必须传入对应的参数。如果抽象父类的抽象方法中有返回值,那么子类在重写这个抽象方法的时候也必须要传入返回值。
8,如果父类中的方法有默认的实现,并且父类需要被实例化,这时可以考虑将父类定义成一个普通类,用虚方法来实现多态。如果父类中的方法没有默认实现,父类也不需要被实例化,则可以将该类定义为抽象类。
namespace ConsoleApp2
{
internal class Program
{
static void Main(string[] args)
{
MoblieStorage ms = new Udisk();
coumputer cpu = new coumputer();
cpu.CPUWrite(ms);
cpu.CPURead(ms);
Console.ReadKey();
}
}
/// <summary>
/// 抽象的父类
/// </summary>
public abstract class MoblieStorage
{
public abstract void Read();
public abstract void Wite();
}
public class MobliedISK : MoblieStorage
{
public override void Read()
{
Console.WriteLine(“移动硬盘在读取数据”);
}
public override void Wite()
{
Console.WriteLine(“移动硬盘再写入数据”);
}
}
public class Udisk : MoblieStorage
{
public override void Read()
{
Console.WriteLine(“U盘在读取数据”);
}
public override void Wite()
{
Console.WriteLine(“U盘在写入数据”);
}
}
public class MP3 : MoblieStorage
{
public override void Read()
{
Console.WriteLine(“MP3在读取数据”);
}
public override void Wite()
{
Console.WriteLine(“MP3在写入数据”);
}
public void palyMusic()
{
Console.WriteLine(“播放音乐”);
}
}
public class coumputer
{
public void CPURead(MoblieStorage ms)
{
ms.Read();
}
public void CPUWrite(MoblieStorage ms)
{
ms.Wite();
}
}
}
接口
接口就是一个规范能力
接口不允许添加访问修饰符,默认是Public
不允许写具有方法体的函数
可以写自动属性
接口是
一种规范。
只要一个类继承了一个接口,这个类就必须实现这个接口中所有的成员
能被实例化。
也就是说,接口的访问修饰符成员(不能创建对象)
接口中的成员不能加“访问修饰符”,接口中的成员访问修饰符为public,不能修改。
(默认为public)接口中的成员不能有任何实现(“光说不做”,只是定义了一组未实现的成员)。
接口中只能有方法、属性、索引器、事件,不能有“字段”和构造函数。
接口与接口之间可以继承,并且可以多继承。
接口并不能去继承一-个类, 而类可以继承接口 (接口只能继承于接口,而类既可以继承接口,也可以继承类)
实现接口的子类必须实现该接口的全部成员。
– -个类可以同时继承-一个类并实现多口,如果-个子类同时继承了父类A,并实现了接口IA,那么语法上A必须写在IA的前面。
class IyClass:A, IA0,因为类是单继承的。
显示实现接口的县的。解决方法的重名问题
在么时候显示的丢实现接口:
当继承的倍口中的方法和參数-摸-样的时候,要是用显示的实现接口
当-个抽象类实现接口的时候,需要子类去实现接口。
Public interface I…able
{
成员;方法和属性,索引器
}
访问修饰符
1,能够修饰类的访问修饰符只有两个:public,internal
2,可访问性不一致
子类的访问权限不能高于父类的访问权限,会暴露父类的访问权限
简单工厂设计模式
设计模式:设计这个项目的一种方式
namespace 访问修饰符
{
internal class Program
{
static void Main(string[] args)
{
Console.WriteLine(“输入你要的笔记本品牌”);
string User = Console.ReadLine();
NoteBook nb = GetNoteBook(User);
nb.SayHello();
Console.ReadKey();
}
/// <summary>
/// 简单工厂核心根据用户的输入创建对象复制给父类
/// </summary>
/// <param name=”user”></param>
/// <returns></returns>
public static NoteBook GetNoteBook (string user)
{
NoteBook nb = null;
switch (user )
{
case “lenovo”:nb = new lenovo ();
break;
case “IBM”:nb = new IBM();
break;
case “Acer”:nb = new Acer();
break;
case “Dell”:nb = new Dell();
break;
}
return nb;
}
}
public abstract class NoteBook
{
public abstract void SayHello();
}
public class lenovo:NoteBook
{
public override void SayHello()
{
Console.WriteLine(“我是联想笔记本”);
}
}
public class Acer : NoteBook
{
public override void SayHello()
{
Console.WriteLine(“我是宏基笔记本”);
}
}
public class Dell : NoteBook
{
public override void SayHello()
{
Console.WriteLine(“我是戴尔笔记本”);
}
}
public class IBM : NoteBook
{
public override void SayHello()
{
Console.WriteLine(“我是IBM笔记本”);
}
}
}
值传递和引用传递
值类型在复制的时候,传递的是这个值的本身
引用类型在复制的时候,传递的是对这个对象的引用
序列化和反序列化
序列化:就是将对象转换为二进制
反序列化:就是将二进制转换为对象
作用:传输数据
把这类标记为序列化[Serializable]
反序列化:
person p;
using (FileStream fsRead = new FileStream(@”E:\aaaa.txr”, FileMode.OpenOrCreate, FileAccess.Read))
{
BinaryReader br = new BinaryReader();
p = (person)br.Deserialize (fsRead );
}
Console.WriteLine(“反序列化成功”);
Console.ReadKey();
序列化
person p = new person();
p.Name = “张三”;
p.Age = 19;
p.Gender = ‘男’;
using (FileStream fsWrite=new FileStream (@”E:\aaaa.txr”,FileMode.OpenOrCreate,FileAccess.Write ))
{
BinaryReader br = new BinaryReader ();
br.Serialize(fsWrite, p);
}
Console.WriteLine(“序列化成功”);
Console.ReadKey();
部分类和密封类
部分类:解决名字重复问题使用partial,两个或多个类组成一个类
public partial class Person
密封类:使用关键字sealed,,不能够被继承 作者:鹿共禾Gonghe https://www.bilibili.com/read/cv21406565/ 出处:bilibili