C#学习笔记 13.01

C#学习笔记 13.01

(学习视频来自bilibili的传智播客赵老师基础教学视频)

接口,上一篇剩下的最后一个多态

如果一个程序要求有扩展性,那么就要提取一个父类,这样在扩展的时候让新的类去击沉父类,父类中要提供子类都有的功能。
从一个例子来讲,U盘,移动硬盘,MP3,这三个东西都同时有被读写的功能,MP3又有一个播放的功能,这一堆东西中又可能增加上,手机,MP4等等,所以这就要求有扩展性。
当这些东西插在电脑上的时候,可以被电脑读写数据。

那么如果我们不用多态这个概念,那么我们从电脑的角度讲,读写不同设备的数据的时候就要调用不同对象的方法,而一旦我们用了多态这个思想,那么电脑上只需要抽象一个父类(移动存储设备),那么只需要调用这个父类的读写方法就可以解决了。

抽象类不能被实例化,但是抽象类可以作为传入参数,就像我们前面的 ArrayList.Add()一样,这个传入参数就是一个父类 object 由于里氏转换,子类可以赋值给父类,所以我们可以在这里输入各种类型的参数。

访问修饰符

public 公开的
private 私有的,只能在当前类内部访问
protected 受保护的,除了在当前类中访问外,在其子类中也可以访问。
internal 只能在当前程序集(项目)中访问

修饰类的是 public internal
这些都能用来修饰类的成员。。。。。。

设计模式 : 简单工厂设计模式

这是一个思维方式,视频推荐了一本书《大话设计模式》

父类中有这么一个构造函数,他可以通过参数来判断实例化何种子类对象,由于里氏转换,实例化的子类对象可以赋值给父类,由于抽象方法在子类实现,父类实际上又可以调用到子类的方法,这样一来就让一个类可以实现其多种子类的功能,表现在外的就是我们的代码具有极强的扩展性。

举个栗子

超市有三种打折方式,后面还可能会有更多的打折方式所以就应该有拓展性。
在这个例子中,我们把上一章提出又解决的问题也融入了代码。
但是又有了一个新的问题,如果想要接收价格并赋值给 _jiaGe 字段这个只在父类中写一次,应该怎么实现呢? 求教。。。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace _18_ChaoShiJieZhang
{
    class Program
    {
        static void Main(string[] args)
        {
            JieZhang(502, JieZhangFangShi.满减结账);
            Console.ReadKey();
        }

        public static void JieZhang(double jiaGe, JieZhangFangShi jzfs)
        {
            JieZhang jz = null;//尽管抽象类不能实例化,但是声明变量赋值为空是没问题的
            switch ((int)jzfs)
            {
                case 0:
                    jz = new YuanJia(jiaGe);
                    break;
                case 1:
                    jz = new ManJian(jiaGe);
                    break;
                case 2:
                    jz = new DaZhe(jiaGe);
                    break;
                default:
                    break;
            }
            jz.ZuiZhongJia();
        }
    }


    public enum JieZhangFangShi
    {
        原价结账,
        满减结账,
        打折结账
    }
    public abstract class JieZhang
    {
        protected double _jiaGe, _shiFu;
        public double JiaGe
        {
            get { return _jiaGe; }
        }
        public double ShiFu
        {
            get { return _shiFu; }
        }
        public abstract void ZuiZhongJia();
    }

    public class YuanJia : JieZhang
    {
        public YuanJia(double jiaGe)
        {
            this._jiaGe = jiaGe;
        }
        public override void ZuiZhongJia()
        {
            Console.WriteLine("原价付款{0}元", this._jiaGe);
        }
    }
    public class DaZhe : JieZhang
    {
        public DaZhe(double jiaGe) 
        {
            this._jiaGe = jiaGe;

        }
        public override void ZuiZhongJia()
        {
            this._shiFu = this._jiaGe * 0.9;
            Console.WriteLine("打9折结账,原价{0}元,实付{1}元", this._jiaGe, this._shiFu);
        }
    }
    public class ManJian : JieZhang
    {
        public ManJian(double jiaGe) 
        {
            this._jiaGe = jiaGe;
        }
        public override void ZuiZhongJia()
        {
            this._shiFu = this._jiaGe - ((int)(this._jiaGe / 100) * 10.5);
            Console.WriteLine("满100减10.5,原价{0}元,实付{1}元", this._jiaGe, this._shiFu);
        }
    }
}

思考一下

这么写的话,当我们需要增加一种结账方式的时候,我们要新加上一个类,继承 JieZhang 这个父类,并实现 ZuiZhongJia 这个方法。
而且在判断的函数中,需要加一个 case 。。我这么写的话呢,还要在枚举类中加一个枚举。
那么问题来了,这不是也乱七八糟的加了一堆代码么,优势何在?
我思前想后了一下,优势应该就体现在大项目团队协作上,比如我们身处一个超市的管理系统中,而我呢,就负责一个收银部分折扣功能的代码,那么在主函数中,给出来这么一段关于结账的语句,这就可以了,定下了,不能随便改了。。。这种写法就可以实现,因为即使新增功能,所有的东西都和主函数中的语句无关,不需要其他部门配合,只需要把自己手里的收拾好就够了。
。。。。大概,是这样吧?。。。。

序列化

……因为我不是很能用得上,视频也很糊…… 嗯 就酱……

序列化:将对象转化为二进制
反序列化:将二进制转化为对象
作用:传输数据

  1. 将要序列化的对象所在的类标记为可以被序列化(在类前面加【Serializable】)
  2. 用 using 搞一个写入文件的流
  3. 实例化一个序列化对象
  4. 把这玩意按进一个流里面
  5. 客户端接收这个流
  6. 反序列化
  7. 强转配输出
  8. 然后就。。传输完成了?
  9. 嗯……就酱……
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值