• 设计模式平时记录


    1. 里式替换原则

    1.1 参考文章

    1. 2自己理解记录如下:

    1.2.※,当子类覆盖或实现父类的方法时,方法的前置条件(即方法的形参)要比父类方法的输入参数更宽松。

    class Parent {
        public Map m1(CharSequence cs) {
             System.out.println("父类方法被调用");
        }
    }
    
    class Child {
        public HashMap m1(String str) {
            System.out.println("子类方法被调用")
        }
    }
    
    class Test {
        public static void main(String[] args) {
            Parent p = new Parent();
            p.m1("Tonus");//使用String类型参数调用父类,父类方法m1中的参数最接近String,所以被调用
           //根据里式替换原则,父类一定要可以被子类无条件替换
           Child c = new Child();
           c.m1("Tonus");//此时子类相当于有两个重载的方法,因为子类参数类型就是String,所以子类会被调用,和原来的“父类被调用”不一致了!!!这就违反了里式替换原则。
    如果将父类和子类的参数类型反过来,子类替换父类后,调用的依然是更具体的String类型的父类,所以和原来一直的,符合里式替换原则。
    } }

    1.2.※,当子类的方法实现父类的抽象方法时,方法的后置条件(即方法的返回值)要比父类更严格。

    这个规则不止是里式替换原则中的规则,更是Java本身就规定必须符合的规则。子类返回值类型必须小于等于父类返回值类型(同父类返回值类型相同或是其子类)。如果不符合这条规则编译器会报错。原因是:向上转型在Java中是被允许的,但是向下转型只有被转型的父类本身是子类类型时才被允许,否则运行时报错(编译不报错)。比如 Map map = new HashMap(); //向上转型默认是可以的。但是 HashMap hashMap = new Map(){...};//向下转型默认是不允许的,必须强转(可能会报错)。

    继续用上面的代码示例:假如有如下使用场景
    class Test {
        public static void main(String[] args) {
             Parent p = new Child();
             Map map = p.m1("Tonus");//此时p.m1()实际上是HashMap,但是编译时被视为Map类型,这里向上转型在Java中是被允许的,无论编译还是运行都不会报错。
    如果父类返回HashMap,子类返回Map,那么就会出现向下转型的情况:p.m1();是个Map类型,但是被编译器视为HashMap类型,就出现了Map向下转型为HashMap的场景,
    而且这个Map实际并不是HashMap类型,所以使用强转后在运行时会报错(ClassCastException)!
    } }

    1.2.※,子类方法不能降低父类方法的可见性,特别地,如果父类是public,那么子类也必须是public。

    这个规则符合里式替换原则,同时也是Java本身就规定必须符合的规则。如果降低了父类方法可见性,父类可以访问的方法子类不能访问就不符合“父类出现的地方一定要被子类无条件替换”的里式替换规则了。

    1.3,

  • 相关阅读:
    HDU1007
    DFA
    netstat
    Sangfor
    JS 基础逻辑关系
    正则表达式
    JS中的DOM
    HTML、CSS、JS面试题
    JS作用域和作用域链
    JS String与正则表达式
  • 原文地址:https://www.cnblogs.com/everest33Tong/p/15608361.html
Copyright © 2020-2023  润新知