C#学习笔记 13.01

C#多态与设计模式

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. 嗯……就酱……
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值