一、关于java中的--类单继承多实现,接口多继承问题
继承的表现形式:
单继承:一个类只能继承一个类
多继承:一个接口可以继承多个类,一个类可以实现(implements)多个接口。
类为什么只能单继承?
1、java只支持单继承,如果子类继承的多个父类里面有相同的方法或者属性,子类将不知道具体继承哪一个,会产生歧义。
举例说明:如果类A同时继承了B,C,类B和C有相同的方法d,那么类A该继承哪个类的d方法呢,这是不明确的。
2、如果父类中的方法同名,子类中没有覆盖,同样会产生上面的错误。
3、类是单继承,多实现。通俗的讲,子类只能有一个亲身父亲,但是一个父类可以有多个孩子。
因此java中就没有设计类的多继承。
接口为什么可以多继承?
接口设计成多继承,是因为接口可以避免上述问题。
1、接口里定义的都是静态常量,方法都是抽象方法,没有逻辑实现。具体的方法必须由实现接口的类覆盖实现,在调用时始终只会调用实现类(也就是子类覆盖的方法)的方法,不会出现歧义(上面多继承的第二个缺点)。
2、接口中的变量都是静态成员常量(public static final),会在编译期就感知到错误,即使存在一定的引用不明确冲突也会在编译时提示错误,因此也不会导致歧义。
3、如果子接口继承的多个父接口中有相同的属性a,那么类在实现接口时是不能调用接口里面的属性a的,与类不能多继承原因一致,造成引用不明确。如果是不同的属性,实现类是可以调用的。
4、总结一下,接口可以继承多个父接口的相同的方法,不同的属性,不能继承多个父接口中相同的属性。
5、示例:
Interface1:
Interface2:
子接口:
实现类:
1、可以调用接口中不同的属性
2、调用接口中相同的属性会报错,引用不明确
二、哈希表到底是个啥?和数组有什么关系?
哈希表的本质其实是个数组:
哈希表就是通过将关键值也就是key通过一个散列函数(hash函数)加工处理之后得到一个值,这个值就是数据存放的位置。
哈希表是 一个数组和单向链表的结合体。 -数组:在查询方面效率很高 ,随机增删方面效率很低。 -单向链表:在随机增删方面效率较高,在查询方面效率很低。 因此,哈希表将以上两种 结构融合在一起,充分发挥它们各自的优点。
请看这张图来理解哈希函数的作用:
虽然说哈希表就是个数组,但是他不像数组那样存储一个值,哈希表存储的是键值对,就比如学号:101000,姓名:张三,简单点说就是一个值对应另外一个值。比如a对应b,那a就是key,b就是value;哈希表存放的就是这样的键值对。
在哈希表中是通过哈希函数将一个值映射到另外一个值的,所以在哈希表中a映射到b,a就是键值,而b呢叫做a的哈希值,也就是hash值。
哈希表的扩容:
--HashMap的初始化容量 以及扩容 机制:
- 默认初始值:16
- 加载因子0.75.(底层数组容量达到75%时,数组开始扩容)
- 扩容为原来的2倍.
- 初始化容量建议为2的倍数
--HashMap集合key部分的元素特点:(无序+不可重复)
--最主要掌握的是:(面试会问的问题)
- map.put(k,v);
- v=map.get(k);
以上这两个方法的底层实现原理 是 必须 掌握的!
--对于HashMap集合put方法的理解:
终极结论:
放在HashMap集合key部分的元素,以及放在HashSet集合中的元素,需要同时hashCode()和equals()方法!