• 面向对象六大原则(上)


    单一职责原则

    单一职责原则(Single Responsibility Principle, SRP)简而言之就是对于一个类或者接口, 引起其改变的应该只能有一个原因. 比如要将负责属性和行为的类分开.

    里氏替换原则

    定义:所有引用基类的地方必须能透明地使用其子类的对象. 只要父类出现的地方, 子类就可以出现, 而且替换为子类不会产生任何错误或者一场. 但是反过来不一定可行.

    1. 子类中可以增加自己特有的方法。
    2. 当子类的方法重载父类的方法时,方法的前置条件(即方法的形参)要比父类方法的输入参数更宽松。
    3. 当子类的方法实现父类的抽象方法时,方法的后置条件(即方法的返回值)要比父类更严格。

    前置条件

    当子类的方法重载父类的方法时,方法的前置条件(即方法的形参)要比父类方法的输入参数更宽松。

    class Father {
    
        public Collection doSomething(HashMap map){
            StdOut.println("父类被执行...");
            return map.values();
        }
    }
    
    class Son extends Father{
    
        public Collection doSomething(Map map) {
            StdOut.println("子类被执行");
            return map.values();
        }
    }

    子类方法和父类方法, 方法名相同, 返回类型相同, 但是参数不同, 所以不是Override, 而是Overload. 在这种情况下, 如果传入HashMap, 子类的doSomething()不会被执行.
    这是正确的, 因为子类并没有重写父类方法, 而是重载父类方法, 所以如果父类的前置条件(形参) 范围宽于子类则不正确.

    public static void main(String[] args){
        Father f=new Father();
        HashMap map=new HashMap();
        f.doSomething(map);
    }
    
    父类被执行
    public static void main(String[] args){
        //父类出现的地方都可以被子类代替, 且不会改变逻辑
        Son f=new Son();
        HashMap map=new HashMap();
        f.doSomething(map);
    }
    
    父类被执行
    public static void main(String[] args){
       //子类出现的地方, 父类不一定可以代替
        Son f=new Son();
        Map map=new HashMap();
        f.doSomething(map);
    }
    
    子类被执行
    class Father {
    
        public Collection doSomething(Map map){
            StdOut.println("父类被执行...");
            return map.values();
        }
    }
    
    class Son extends Father{
    
        public Collection doSomething(HashMap map) {
            StdOut.println("子类被执行");
            return map.values();
        }
    }
    public static void main(String[] args){
        Father f=new Father();
        HashMap map=new HashMap();
        f.doSomething(map);
    }
    
    父类被执行
    public static void main(String[] args){
        //父类出现的地方都可以用子类代替
        Son f=new Son();
        HashMap map=new HashMap();
        f.doSomething(map);
    }
    
    子类被执行

    可以注意到, 此时子类方法被执行了, 而子类并没有重写父类的相应的方法, 而是重载了父类的方法.

    public static void main(String[] args){
        Son f=new Son();
        Map map=new HashMap();
        f.doSomething(map);
    }
    
    父类被执行

    后置条件

    当子类的方法实现或覆写父类的抽象方法时,方法的后置条件(即方法的返回值)要比父类更严格或相同。

    注意点

    1. 在类中调用其他类时务必使用其父类或者接口, 如果不能使用父类或者接口, 则说明类的设计已经违背了LSP原则.
    2. 如果子类不能完整地实现父类的方法, 或者父类的一些方法在子类中完全和父类业务逻辑不同, 则建议不使用继承关系, 而是用依赖, 聚集, 组合等关系代替.

    依赖倒置原则

    Dependence Inversion Principle

    1. 高层模块不应该依赖低层模块
    2. 抽象不应该依赖细节
    3. 细节应依赖抽象
    名称 含义
    高层模块 原子逻辑再组装就是高层模块
    低层模块 每一个逻辑的实现都由院子逻辑组成,不分割的原子逻辑就是低层模块

    对于Java来说.

    1. 模块间的依赖通过抽象产生,实现类之间不发生直接依赖关系, 其依赖关系是通过接口或者抽象类产生的
    2. 接口或这抽象类不依赖于实现类
    3. 实现类依赖接口或抽象类

    这样也有利于并行开发, 即使只完成了一部分工作, 仍可以进行单元测试.

    这也符合现代开发的流程, 先写好单元测试类, 再写实现类.

    规则

    1. 每个类尽量都有接口或抽象类, 或者抽象类和接口都具备
    2. 变量的表面类型尽量是接口或者是抽象类(如果使用类的clone方法, 就必须使用实现类)
    3. 任何类都不应该从具体类中派生(如果实在需要继承自具体类, 尽量不要超过两层的继承)
    4. 尽量不要覆写基类的方法

    总体而言, 依赖倒置原则是六大原则中最难实现的, 也是实现开闭原则的重要途径. 总体而言, 把握住面向接口编程即可.

  • 相关阅读:
    C#使用Xamarin开发Android应用程序 -- 系列文章
    stealwatch里的安全功能——ETA结果会显示加密套件以及key长度,还有流量大小(例如41MB)
    钟平---逻辑英语的语法讲解
    python dpkt 解析 pcap 文件
    TOR的十个最好的替代工具
    tf.expand_dims 来增加维度
    安天透过北美DDoS事件解读IoT设备安全——Mirai的主要感染对象是linux物联网设备,包括:路由器、网络摄像头、DVR设备,入侵主要通过telnet端口进行流行密码档暴力破解,或默认密码登陆,下载DDoS功能的bot,运行控制物联网设备
    使用深度学习检测TOR流量——本质上是在利用报文的时序信息、传输速率建模
    利用神经网络进行网络流量识别——特征提取的方法是(1)直接原始报文提取前24字节,24个报文组成596像素图像CNN识别;或者直接去掉header后payload的前1024字节(2)传输报文的大小分布特征;也有加入时序结合LSTM后的CNN综合模型
    算法培训
  • 原文地址:https://www.cnblogs.com/fei-hsueh/p/6106301.html
Copyright © 2020-2023  润新知