zoukankan      html  css  js  c++  java
  • C#基础笔记(第十三天)

    1.复习
    泛型集合
    List<T>
    Dictionary<Tkey,Tvalue>
    装箱和拆箱
    装箱:把值类型转换为引用类型
    拆箱:把引用类型转换为值类型
    我们应该尽量避免在代码中发生装箱或者拆箱
    文件流
    FileStream StreamReader和StreamWriter
    多态:虚方法、抽象类、接口
    虚方法:
    抽象类:

    集合:空间名Collections.Generic
    List<int> list=new List<int>();
    和ArrayList集合的区别:确定了元素的类型,在使用集合的时候不会放生装箱和拆箱
    Dictionary<int,string> dic=new Dictionary<int,string>(); 键值对集合
    dic.Add(1,"张三"); 添加相同的键用这种方式会抛异常
    dic[2]="李四" 添加相同的键用这种方式会覆盖原来键的值
    辨定键值对集合用foreach循环
    foreach(var item in collection)
    {

    }
    foreach(KeyValuePair<int,string> kv in dic)
    {
    console.writeline("{0}------{1}",kv.key,kv.value);
    }
    console.readkey();

    文件流
    File FileStream 操作字节的 StreamReader StreamWriter 操作字符的
    文本和数据最好放在相对路径下(debug内)
    代码要写在using()里面,因为它的资源不会自动的释放,必须我们自己手动释放,写在using里面可以帮我们自动的回收资源。
    using (FileStream fsRead = new FileStream("zucema.txt", FileMode.OpenOrCreate, FileAccess.Read))
    {
    byte[] buffer = new byte[1024 * 1024 * 5];
    //本次读取实际读取到的字节数
    int r=fsRead.Read(buffer, 0, buffer.Length);
    //将字节数组中的每个元素按照我们制定的编码格式解析成字符串
    string s=Encoding.Default.GetString(buffer, 0, r);
    Console.WriteLine(s);
    }
    Console.ReadKey();
    如果是大数据的话,必须循环的去读

    写入
    using (FileStream fsWrite = new FileStream(@"C:UsersSJDDesktop ew.txt", FileMode.OpenOrCreate, FileAccess.Write))
    {
    string s = "ABC";
    byte[] buffer = Encoding.UTF8.GetBytes(s);
    fsWrite.Write(buffer, 0, buffer.Length);
    }
    Console.WriteLine("写入成功");
    Console.ReadKey();
    覆盖时是按字节去覆盖
    要用追加的话,把FileMode.OpenOrCreate改成FileMode.Append就是追加了。

    多态
    让一个对象表现出多种状态,类型
    写多态的好处
    1、减少代码
    2、屏蔽各个子类之间的差异,写出通用的代码,适用于每个子类的代码

    虚方法和抽象类

    声明父类去指定子类对象
    虚方法经典例子:木鸭子会叫,橡皮鸭子会叫,真鸭子会叫,只不过他们叫的方式不一样,真鸭子是父类,有意义,需要实例化
    后面用的比较多的就是抽象类

    2.C#中的访问修饰符
    public: 公开的公共的
    private: 私有的,只能在当前类的内部访问
    protected: 受保护的,只能在当前类的内部以及该类的子类中访问
    internal: 只能在当前项目中访问,在同一个项目中,internal和public的权限是一样的。
    同一个项目中,Internal的权限要大于protected。但是一旦跨了项目,protected的权限要大于internal
    protected internal:protected+internal的权限

    1)、能够修饰类的访问修饰符只有两个:public internal
    默认不手动加Public修饰符的类,那它默认就是Internal修饰

    2)、可访问性不一致。
    子类的访问权限不能高于父类的访问权限,会暴露父类的成员。
    因为继承的传递性,子类能使用父类的成员,但父类权限写低就是为了不被别的项目访问到成员。

    3.设计模式
    设计是这个项目的一种方式
    23种设计模式
    设计模式是帮我们解决在日常开发中的问题。

    4.简单工厂设计模式

    5.值类型和引用类型
    值类型:int、double、char、decimal、bool、enum、struct 存栈
    引用类型:string 、数组、自定义类、集合、object、接口 存堆

    值传递和引用传递
    值类型在复制的时候,传递的是这个值的本身
    引用类型在复制的时候,传递的是堆这个对象的引用

    6.序列化和反序列化
    序列化:就是将对象转换为二进制
    反序列化:就是将二进制转换为对象
    作用:传输数据。
    在网络中传输数据,只有二进制这个形态是可以被传输的
    序列化:
    1)、将这个类标记为可以被序列化的。
    在类上方标记一个[Serializable],只有被它标记的对象才能序列化

    例:序列化
    //要将p这个对象传输给对方电脑
    Person p = new Person();
    p.Name = "张三";
    p.Age = 19;
    p.Gender = '男';
    using (FileStream fsWrite = new FileStream(@"C:UsersSJDDesktopp.txt", FileMode.OpenOrCreate, FileAccess.Write))
    {
    //序列化对象
    BinaryFormatter bf = new BinaryFormatter();
    bf.Serialize(fsWrite, p);
    }
    Console.WriteLine("序列化成功");
    Console.ReadKey();

    反序列化
    //接收对方发送过来的二进制 反序列化成对象
    Person p;
    using (FileStream fsRead=new FileStream(@"C:UsersSJDDesktopp.txt",FileMode.Open,FileAccess.Read))
    {
    BinaryFormatter bf = new BinaryFormatter();
    //object强制转换为person
    p=(Person)bf.Deserialize(fsRead);
    }
    Console.WriteLine(p.Name);
    Console.WriteLine(p.Age);
    Console.WriteLine(p.Gender);
    Console.ReadKey();

    7.partial部分类
    三个人一起同时做一个项目,每个人都要开发一个person类。不能你写我就不能写
    在每个类前面加个partial,表示部分类
    public partial class Person
    {
    }
    public partial class Person
    {
    }
    表示这两个类共同组成person类,可以同时写。
    还有个好处,不论公有还是私有,都可以相互读取
    部分类里面不能有同样的方法,但可以用重载,相当一个类写在不同的地方

    8.sealed密封类
    sealed用来标记一个类是密封类
    public sealed class Person
    特征:密封类是不能够被其他类继承的,但是可以继承于其它类

    9.重写ToString方法
    Person p=new Person();
    console.writeline(p.tostring());
    console.readkey();
    打印机出来的会是这个对象的命名空间。

    ****为什么所有类型都可以ToString?
    因为所有的类型的父类都是Object
    object里面提供的一些方法,子类都可以调用
    tostring 都可以调用
    ToString是object的虚方法
    所以所有的对象所有的变量都可以调用ToString

    10.接口
    继承的特性是单根性,一个子类只允许有一个父类
    一个子类想要继承2个父类,可以写成接口
    声明接口的关键字是interface
    英语中I开头 able结尾都是表示有能力

    接口就是一个规范、能力
    只有符合这个规范才能生存
    能力:能够实在某一个功能。

    接口的语法和特征
    格式:
    [public] interface I..able
    {
    成员;
    }

    Public interface IFlayable
    {
    void Fly();
    String Test();
    }
    1.可以有返回值,使用string等。
    2.接口中的成员不允许添加访问修饰符,默认就是Public
    3.接口成员不能有定义,不允许写具有方法体的函数
    4.接口不能存数据(字段),存数据用类去存
    5.可以写没有方法体的方法(自动属性)
    6.方法、自动属性

    为什么叫自动属性
    虽然我们不写字段,但是在进行编译的时候会自动给我们生成一个私有的字段
    要限定它只能有构造函数
    public int Age
    {
    get;
    set;
    }

    自动属性本质上还是两个函数,一个叫get一个叫set

    接口中一般就放方法和属性(本质上只有方法)

    接口中不添加访问修饰符,默认就是public
    类中不添加访问修饰符,默认就是private
    例:
    生产笔记本的厂商,不管你是什么厂家。最后都要做出USB接口。可以插鼠标键盘。都要符合USB的规范。各个厂家都要按照规范来。也有特殊的,比如苹果,没有网线口。手机也在趋向一个规范。
    ***什么时候会用到接口?
    1、类需要多继承的时候

    ****接口是一种规范。
    只要一个类继承了一个接口,这个类就必须实现这个接口中所有的成员

    为了多态。
    接口不能被实例化。
    也就是说,接口不能new(不能创建对象)

    接口中的成员不能加“访问修饰符”,接口中的成员访问修饰符为public,不能修改。


    (默认为public)
    接口中的成员不能有任何实现(“光说不做”,只是定义了一组未实现的成员,和抽象类一样,只是继承他们的子类去做)。

    接口中只能有方法、属性、索引器、事件,不能有“字段”和构造函数。

    接口与接口之间可以继承,并且可以多继承。

    接口并不能去继承一个类,而类可以继承接口 (接口只能继承于接口,而类既可以继承接口,也可以继承类)


    实现接口的子类必须实现该接口的全部成员。


    一个类可以同时继承一个类并实现多个接口,如果一个子类同时继承了父类A,并实现了接口IA,那么语法上A必须写在IA的前面。


    class MyClass:A,IA{},因为类是单继承的。


    显示实现接口的目的:解决方法的重名问题
    什么时候显示的去实现接口:
    当继承的接口中的方法和参数一摸一样的时候,要是用显示的实现接口

    当一个抽象类实现接口的时候,需要子类去实现接口。


    面向对象(接口)编程

    11.显示实现接口
    显示实现接口就是为了解决方法的重名问题

    例:
    public class Bird:IFlyable
    {
    public void Fly()
    {
    Console.WriteLine("鸟会飞");
    }
    void IFlyable.Fly()
    {
    Console.WriteLine("我是接口的飞");
    }
    }

    IFlyable fly=new Bird();
    fly.Fly();//调用的是接口的Fly

    Bird bird=new Bird();
    bird.Fly();//这样才是调用自己的Fly

    12.总结
    //什么时候用虚方法来实现多态?
    //什么时候用抽象类来实现多态?
    //什么时候用接口来实现多态?

    在我提供给你的几个类当中,如果说你能抽象出来一个父类,并且这个父类必须写上这几个子类共有的方法,然后你还不知道怎么去写这个方法,就用抽象类来写这个多态。
    反之,抽象出来的父类,方法可以写,并且我还要创建这个父类的对象,就用虚方法。
    这几个类里面根本就找不出来父类,但它们都有一个共同的行为,共同的能力。这个时候就用接口来实现多态(比喻:鸟类和飞机没有什么父类,但是都会飞,没办法写个父类让它去继承)

    真的鸭子会游泳,木头鸭子不会游泳,橡皮鸭子会游泳
    没办法提取一个父类 会游泳,因为木头鸭子不会游泳,没办法用虚方法
    没办法写抽象方法,因为真的鸭子需要被创建对象,真鸭子是有意义的。
    所以接口是最合适的


    13.超市收银系统
    Guid能帮我们产生一个全世界独一无二的编号。//不会重复
    Guid.NewGuid() 可以ToString()


    //用父类来做集合,屏蔽差异,但是不好找,所有的货物都混合到一起了。
    //List<ProductFather> list = new List<ProductFather>();
    //存储货物、集合去存(因为会增加货物)
    //List<SumSung> listSum = new List<SumSung>();
    //List<Acer> listAcer = new List<Acer>();
    //List<JiangYou> listJiangYou = new List<JiangYou>();
    //List<Banana> listBanana = new List<Banana>();
    List<List<ProductFather>> list = new List<List<ProductFather>>();
    我在一个集合里面又放一个集合
    list<>里面的内容应该是这个集合的类型
    List<ProductFather> list2 = new List<ProductFather>();
    两者区别:
    给list2添加数据的时候,可以直接把货物对象添加进来,比如三星,手机,笔记本,酱油,可以直接扔在这个集合里面。
    缺点就是取的时候很麻烦。存进去了,不知道哪个下标是谁,得通过调试去看。看这个下标对应的数据是哪个对象,很麻烦

    于是我们用2个集合,2个集合什么意思
    给list添加数据的时候
    list.Add() 添加一个集合进去。其实这个集合就是货架
    给他添加数据,添加的并不是商品,而是货架
    不管list还是List2都代表整个仓库

    用list2添加仓库就是把这个数据拿回来直接扔进去仓库了。
    list是添加一个数组的集合进来,给这仓库添加一个数据的集合,而仓库的货物都集中到货架
    货架就是一个货物的集合(货架都是放货物的),添加货架,有四个货架,所以添加四个元素进来。

    List<List<父类>>list=new List<List<父类>>();
    list[0]=货架
    商品的父类什么类型都可以往里放
    给仓库添加货物,其实是给list[0],list[1],list[2]....
    通过这个方式可以直接拿到这个货物所在的货架

    在仓库中,除了商品还有货架也是集合
    以上只创建出了仓库,还没有货架

    什么时候创建货架?
    在创建CangKu对象的时候,向仓库添加货架

    例:
    //用父类来做集合,屏蔽差异,但是不好找,所有的货物都混合到一起了。
    //List<ProductFather> list = new List<ProductFather>();
    //存储货物、集合去存(因为会增加货物)
    //List<SumSung> listSum = new List<SumSung>();
    //List<Acer> listAcer = new List<Acer>();
    //List<JiangYou> listJiangYou = new List<JiangYou>();
    //List<Banana> listBanana = new List<Banana>();
    List<List<ProductFather>> list = new List<List<ProductFather>>();
    //list[0]存储Acer电脑
    //list[1]存储三星手机
    //list[2]存储酱油
    //list[3]存储香蕉
    /// <summary>
    /// 在仓库中创建对象的时候,向仓库中添加货架
    /// </summary>
    public CangKu()
    {
    //list.Add(new List<ProductFather>());
    //list.Add(new List<ProductFather>());
    //list.Add(new List<ProductFather>());
    //list.Add(new List<ProductFather>());
    //使用父类就可以屏蔽各个货架的差异
    //货架很多就用for循环
    for (int i = 0; i < 4; i++)
    {
    list.Add(new List<ProductFather>());
    }
    }
    /// <summary>
    /// 进货
    /// </summary>
    /// <param name="strType">货物的类型</param>
    /// <param name="count">货物的数量</param>
    public void GetPros(string strType,int count)
    {
    //货物很多,一次加不完,通过for循环去加
    for (int i = 0; i < count; i++)
    {
    //strType货物类型有四种可能,所以对它做一个多条件的判断
    switch(strType)
    {
    case "Acer":list[0].Add(new Acer(Guid.NewGuid().ToString(), 1000, "宏基笔记本"));
    break;
    case "SumSung":list[1].Add(new SumSung(Guid.NewGuid().ToString(), 2000, "棒子手机"));
    break;
    case "JiangYou":list[2].Add(new JiangYou(Guid.NewGuid().ToString(), 10, "老抽酱油"));
    break;
    case "Banana":list[3].Add(new Banana(Guid.NewGuid().ToString(), 50, "大香蕉"));
    break;
    }


    }


    提取货物的方法
    /// <summary>
    /// 从仓库中提取货物
    /// </summary>
    /// <param name="strType"></param>
    /// <param name="count"></param>
    /// <returns></returns>
    //返回一个父类集合或数组
    public ProductFather[] QuPros(string strType, int count)
    {
    //提货物放到数组里面去返回
    ProductFather[] pros = new ProductFather[count];
    //进货是一个一个往里放,取货也是一个一个往外取
    for (int i = 0; i < count; i++)
    {
    switch(strType)
    {
    //货架上那第一个[0],拿走后,第二个就顶上来变成第一个[0]
    //这只是一个赋值操作,货架上的数目并没有发生改变
    //list[0]是宏基笔记本的那个货架,list[0][0]是货架上第一个笔记本,拿完之后放在pros数组里
    case "Acer":
    //判断货架是不是空的
    if(list[0].Count == 0)
    {
    break;
    }
    pros[i] = list[0][0];
    //移除第一个,拿一个删一个
    list[0].RemoveAt(0);
    break;
    case "SumSung":
    if(list[1].Count==0)
    {
    break;
    }
    pros[i] = list[1][0];
    list[1].RemoveAt(0);
    break;
    case "JiangYou":
    if(list[2].Count==0)
    {
    break;
    }
    pros[i] = list[2][0];
    list[2].RemoveAt(0);
    break;
    case "Banana":
    if(list[3].Count==0)
    {
    break;
    }
    pros[i] = list[3][0];
    list[3].RemoveAt(0);
    break;
    }
    //把集合返回

    }
    return pros;
    }

    还需要一个展示货物的方法


    13.总结
    值传递和引用传递 值传递传递的是值的本身
    引用传递传递的是对对象的引用
    ref:将值传递改变为引用传递(不一定对)
    接口 接口的语法特点
    显示实现接口
    什么时候使用接口?
    部分类(partial)
    密封类(sealed)
    序列化和反序列化 目的:传输数据
    简单工厂设计模式
    访问修饰符 5个访问修饰符

  • 相关阅读:
    模板jinja2常用方法
    简单实用的日志类CLog (Python版)
    Databus架构分析与初步实践
    AWS API 2.0签名规范
    django学习——通过get_FOO_display 查找模型中的choice值
    Twitter如何在数千台服务器上快速部署代码?
    mysql 添加索引 mysql 如何创建索引
    sql中的like和正则的区别
    python2.7运行出现的Warning: UnicodeWarning: Unicode equal comparison failed to convert both arguments to Unicode
    Python命令模块argparse学习笔记(四)
  • 原文地址:https://www.cnblogs.com/lizhenlin/p/7687657.html
Copyright © 2011-2022 走看看