java 里面里氏替换原则的疑惑?

发布于 2022-09-11 18:41:29 字数 993 浏览 37 评论 0

刚开始学习 java, 接触到里氏替换原则这个概念的时候查阅了一下资料, 其中有一条如下:

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

但是本人自己写了一个小demo测试了一下, 当子类方法形参比父类方法形参输出严格时, 貌似使用子类替换父类也不影响程序逻辑, 代码如下:

import java.util.HashMap;
import java.util.LinkedHashMap;

public class Test {
    public static void main(String[] args){      
        HashMap map = new HashMap();
        A a = new A();
        a.f(map); // 父类
        
        B b = new B();
        b.f(map); // 父类
    }
}

class A {
    public void f(HashMap map) {
        System.out.println("父类");
    }
}

class B extends A {
    public void f(LinkedHashMap map) {
        System.out.println("子类");
    }
}

可以看到当我使用子类B替换掉父类A, 同时子类的参数类型LinkedHashMap比父类参数类型HashMap更严谨(与里氏替换原则要求相反), 但是结果似乎并不影响(还是输出"父类", 而不是"子类").

个人觉得这个相当于在子类里面重载了父类的方法(不同的参数类型), 所以不是很理解到底该如何实践这一原则, 如果哪位前辈可以指点一下(有具体代码更好), 不胜感激!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

旧人哭 2022-09-18 18:41:29

里氏替换原则中说,任何基类可以出现的地方,子类一定可以出现.
如一个方法接受 Map 做为参数, 那一定可能接受 Map 的子类或实现类, 如 HashMap, LinkedHashMap 等等.
如果一个方法以 LinkedHashMap 为参数, 那么不能用HashMap 给他传参.

里氏替换原则是为了更好的实现继承和多态, 你这个是函数重载


class B extends A {
    @Override //报错
    public void f(LinkedHashMap map)
    {
        System.out.println("子类");
    }

    @Override //报错
    public void f(Map map)
    {
        super.f(map); //报错
        super.f((HashMap)map); //正常, 但可能在运行时报错, 因为 map 可能不是 HashMap
        System.out.println("子类");
    }

    @Override //正常
    public void f( HashMap map)
    {
        super.f(map); //正常
        System.out.println("子类");
    }
}

正确的继承是可以用@Override注解, 可以调用super.parentClassMathod.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文