A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 郭繁森 黑马帝   /  2012-2-10 11:58  /  3008 人查看  /  8 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

本帖最后由 郭繁森 于 2012-2-10 19:44 编辑

            Map<String,String> map = new HashMap<String,String>();

疑问:创建HashMap时为何左边类型是父类 Map 而不是 HashMap ?

评分

参与人数 1技术分 +1 收起 理由
admin + 1

查看全部评分

8 个回复

倒序浏览
本帖最后由 寻找幸福的13狼 于 2012-2-10 12:44 编辑

HashMap 是实现了Map 接口。我们编程一般尽量面象接口、或父类。
接口提供给用户统一的操作界面和使用方式
子类只能继承一个父类却可以继承多个接口..功能区分清晰,改起来方便
接口和实现分离了,适于团队的协作开发。
易扩展:一个接口可以从三方面去考察:
制 定者(或者叫协调者),实现者(或者叫生产者),调用者(或者叫消费者)。
接口本质上就是由制定者来协调实现者和调用者之间的关系。
所以通常说的 “面向接口编程”可以理解为:
只有实现者和调用者都遵循“面向接口 编程”这个准则,制定者的协调目的才能达到。
在项目中的意义:
在传统的项目开发过程中,由于客户的需求经常变化,如果不采用面向接口编程,那么我们必须不停改写现有的业务代码。改写代码可能产生新的BUG,而且改写代码还会影响到调用该业务的类,可能全都需要修改,影响系统本身的稳定性。而且为了将改写代码带来的影响最小,我们不得不屈服当前的系统状况来完成设计,代码质量和稳定性更低。当这种情况积累到一定程度时,系统就会出现不可预计的错误,代码凌乱,不易读懂,后接手的人无法读懂代码,系统的维护工作越来越重,最终可能导致项目失败。
接口在项目就是一个业务逻辑,面向接口编程就是先把客户的业务提取出来,作为接口。业务具体实现通过该接口的实现类来完成。当客户需求变化时,只需编写该业务逻辑的新的实现类,通过更改配置文件(例如Spring框架)中该接口的实现类就可以完成需求,不需要改写现有代码,减少对系统的影响。
采用基于接口编程的项目,业务逻辑清晰,代码易懂,方便扩展,可维护性强。即使更换一批人员,新来的人依然可以快速上手。对于公司来说,意义更大。
在Java中的意义:
Java本身也是一个不断完善的语言,他也在频繁的改动他的系统API来完善,他的API是一个庞大的体系,互相关联,如果不采用接口,而都是用实现类的话,那么API的改动就会给整个体系带来不稳定。而且如果改动API,那么就会有大量采用旧API的项目因无法正常运行,会损失大量客户。换句话说,JDK已经发布的API是一种承诺,一经发布就不能更改,即使原来API存在各种各样的问题(例如java.util.Properties类就是一个失败的例子)也必须保留,于是在Java里就出现了不建议使用的方法,但JDK依然提供该方法。而且Java语言本身是一个跨平台的语言,为了满足在各个平台下运行,就必须把各种操作做成接口,在编写各个平台下的实现类。
设计模式的体现:
在设计模式的原则里的开闭原则,其实就是要使用接口来实现对扩展开放,对修改关闭。在设计模式的其他原则里也有关于基于接口编程的原则,即依赖倒转的设计原则(DIP)----高层模块不应该依赖于底层模块。二者都应该依赖于抽象;抽象不应该依赖于细节,细节应该依赖于抽象(注:来自《敏捷软件开发--原则、模式与实践》Robert C.Martin著)。在使用面向接口的编程过程中,将具体逻辑与实现分开,减少了各个类之间的相互依赖,当各个类变化时,不需要对已经编写的系统进行改动,添加新的实现类就可以了,不在担心新改动的类对系统的其他模块造成影响。

评分

参与人数 1技术分 +1 收起 理由
admin + 1 辛苦了!

查看全部评分

回复 使用道具 举报
用父类的引用指向子类的实例,,这种方式被称为向上转型,向上转型在很多地方都经常用到,再比如:List<String> list = new ArrayList<String>();
这样创建对象更具有灵活性。
首先,Map是一个借口,他有很多子类,所以它有很多种实现方式。在实际开发中,如果需要定义很多HashMap、TreeMap等Map的子类对象,这样定义,只需将map指向另一个子类实例就可以切换,增加了开发的灵活性和实用性。

评分

参与人数 2技术分 +1 黑马币 +1 收起 理由
唐秀启 + 1
Akm + 1 很给力!

查看全部评分

回复 使用道具 举报
Akm 黑马帝 2012-2-10 12:49:10
板凳
Map是接口,hashMap是Map的一种实现。接口不能被实例化。
Map map=new HashMap(); 就是将map实例化成一个hashMap。这样做的好处是调用者不需要知道map具体的实现,map接口与具体实现的映射java帮你做了。打个比方,你是一个头头,手下有几个人:张三,李四等等。你需要手下做一件事情,你关心的是有没有人做,而不关心到底是谁去做,你只需要喊一声:“来人!”具体的是哪个人进来帮你做事无所谓。
如果说这样写: HashMap map = new HashMap();就相当于你指定要张三做事:“来张三!”
就是这样。

评分

参与人数 1技术分 +1 收起 理由
唐秀启 + 1

查看全部评分

回复 使用道具 举报
这个和List list = new ArrayList() ;的实例化雷同,虽然说用ArrayList list = new ArrayList();也同样可以完成目的,但是
在java开发中,一般父类的引用会用子类去实例化,自动向上转型,方便以后的代码维护。比如以后要用List的其他子类
去实例的话修改就很方便了。所以Map集合也是如此。
回复 使用道具 举报
补充:视频里的哪一节第几个讲这方面的知识点能否告知下?
回复 使用道具 举报
袁野 黑马帝 2012-2-10 15:01:08
7#
多态中 有你要的答案
回复 使用道具 举报
彭坤 中级黑马 2012-2-10 17:31:12
8#
这个问题属于java面向对象的内容,父类引用指向子类对象
可以这样理解:
根据面向对象的思想,用接口定义变量,具有一定的灵活性,比如你想定义一个map,你可以写成以下这种常见的方式,
Map<String,String> map = new HashMap<String,String>();
当然你也可以写成HashMap<String,String> map = new HashMap<String,String>();但是这样写的结果是不够灵活,
用第一种方式定义的变量map可以重新赋值,即map=new TreeMap<String,String>();实现变量的重用。
但是如果采用第二种方式定义的话,那map就只能赋值HashMap类的对象,如果程序需要一个TreeMap对象,那只能重新new一个TreeMap了。

评分

参与人数 1技术分 +1 收起 理由
admin + 1

查看全部评分

回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马