日期:2014-05-20  浏览次数:20706 次

关于面向对象原则里氏替换的疑问
里氏替换原则里面有“一个软件实体如果使用的是一个基类的话,那么一定适用于其子类。而且它觉察不出基类对象和子类对象的区别。也就是说,在软件里面,把基类都替换成它的子类,程序的行为没有变化。”
我暂时理解为在父类作为参数或类型使用时他的子类将替换父类进行操作。

然后我看到的一个例子却让我迷惑了
Java code
import java.util.Collection;
import java.util.Map;
/**
 * 父类
 * @author LZG
 *
 */
public  class Father {
    public Collection doTo(Map map)
    {
        System.out.println("父类被执行。。。");
        return map.values(); 
    }
}

Java code

import java.util.Collection;

import java.util.HashMap;


public class Son extends Father{
    public Collection doTo(HashMap map)
    {
        System.out.println("子类被执行。。。");
        return map.values(); 
    }

}


Java code

import java.util.*;
public class Test {

    /**
     * @param args
     */
    public static void main(String[] args) {
        // TODO 自动生成方法存根
        Father f=new Son();
        HashMap map=new HashMap();
        f.doTo(map);
    }

}




最后输出的结果却是 “父类被执行。。。”
子类里面 没有重写了父类的doTo(Map map)的方法 ,然后自己又定义了一个自己的方法doTo(HashMap map) 相当方法重载
经过调试 我看到 虽然子类的方法的参数是HashMap map 在Main入口调用方法时传进去参数也是 HashMap map
但是运行的时候跑得却是调用了父类的方法
我知道 Map map 是 HashMap map 的父类
其他的里面到底又有什么样的关系还请给位高手帮小弟解答呀!

------解决方案--------------------
向上就近匹配原则 
方法的参数表中的数据类型和调用时给出的参数类型不尽相同时(类型不尽相同是指兼容类型),会根据向上匹配的就近原则。(参数类型就近向上转化匹配)http://tangy.iteye.com/blog/652688
------解决方案--------------------
f是一个父类的引用,指向一个子类的实例,只能调用父类声明的方法,不会调用子类的方法。
------解决方案--------------------
doTo(HashMap map), doTo(HashMap map)这俩方法不构成重写@Override关系。

不信加@Override到doTo(HashMap map)上试试,会报错的。