接口和抽象类的不同
不同点:
- 抽象类可以定义构造函数,接口不可以
- 抽象类可以有抽象方法和具体方法,接口中只能有抽象方法(public abstact)
- 抽象类中的成员权限可以是 public、默认、protected(抽象类中抽象方法就是为了重
写,所以不能被 private 修饰),而接口中的成员只可以是 public(方法默认:public
abstrat、成员变量默认:public static final)
在 Java8 中,允许在接口中包含带有具体实现的方法,使用 default 修饰,这类方法就是默认方法。
- 抽象类中可以包含静态方法,而接口中不可以包含静态方法
抽象类中可以包含静态方法,在 JDK1.8 之前接口中不能包含静态方法,JDK1.8 以后
可以包含。之前不能包含是因为,接口不可以实现方法,只可以定义方法,所以不能
使用静态方法(因为静态方法必须实现)。现在可以包含了,只能直接用接口调用静
态方法。1.8 仍然不可以包含静态代码块。
接口的成员变量默认是 public static final,static 是为了保证变量只有一份,因为一
个类可以实现多个接口,定义为 static 后,如果出现重名,那么存储在静态存储区的
时候就会报错,因为静态存储区已经有一份了,你改名吧(成员变量可以通过接口和
实现接口的类来调用)。final 是因为接口的东西是大家共用的,不能随便修改。
相同点:
- 都不能被实例化;
- 可以将抽象类和接口作为引用类型;
- 一个类如何继承了某个抽象类或者实现了某个接口,就必须对其中所有的抽象方法全部
进行实现,否则该类仍然需要被声明为抽象类.
零碎知识点
Java 对于 [-128, 127] 之间的数会进行缓存,比如:
Integer i = 127,会将 127 进行缓存,下次再写 Integer j = 127 的时候,就会直接从缓
存中取出,而对于这个区间之外的数就需要 new 了。
try-catch-finally 中catch可以被忽略。
初始化顺序
- 父类(静态变量、静态语句块)
- 子类(静态变量、静态语句块)
- 父类(实例变量、普通语句块)
- 父类(构造函数)
- 子类(实例变量、普通语句块)
- 子类(构造函数)
this 和 super 不能同时出现在一个构造函数里面
transient 只能修饰变量,不能修饰类和方法。
为什么重写 equals() 就一定要重写 hashCode() 方法?
这个问题应该是有个前提,就是你需要用到 HashMap、HashSet 等 Java 集合。用不到哈希表的话,其实仅仅重写 equals() 方法也可以吧。而工作中的场景是常常用到 Java 集合,所以 Java 官方建议重写 equals() 就一定要重写 hashCode() 方法。
对于对象集合的判重,如果一个集合含有 10000 个对象实例,仅仅使用 equals() 方法的话,那么对于一个对象判重就需要比较 10000 次,随着集合规模的增大,时间开销是很大的。但是同时使用哈希表的话,就能快速定位到对象的大概存储位置,并且在定位到大概存储位置后,后续比较过程中,如果两个对象的 hashCode 不相同,也不再需要调用equals() 方法,从而大大减少了 equals() 比较次数。
所以从程序实现原理上来讲的话,既需要 equals() 方法,也需要 hashCode() 方法。那么既然重写了 equals(),那么也要重写 hashCode() 方法,以保证两者之间的配合关系。
hashCode()与equals()的相关规定:
- 如果两个对象相等,则 hashCode 一定也是相同的;
- 两个对象相等,对两个对象分别调用 equals 方法都返回 true;
- 两个对象有相同的 hashCode 值,它们也不一定是相等的;
- 因此,equals 方法被覆盖过,则 hashCode 方法也必须被覆盖;
- hashCode() 的默认行为是对堆上的对象产生独特值。如果没有重写 hashCode(),则该 class 的两个对象无论如何都不会相等(即使这两个对象指向相同的数据)
Array 不支持泛型,要用 List 代替 Array,因为 List 可以提供编译器的类型安全保证,而 Array却不能。
Comparable 和 Comparator 区别比较
- Comparable 相当于“内部比较器”,而 Comparator 相当于“外部比较器”;
- Comparable 和 Comparator 是用来实现集合中元素的比较、排序的;
- Comparable 是在集合内部定义的方法实现的排序,位于 java.lang 下;Comparator在集合外部实现的排序,位于 java.util 下;
- Comparable 是一个对象本身就已经支持自比较所需要实现的接口,如 String、Integer 自己就实现了 Comparable 接口,可完成比较大小操作。自定义类要在加入 list容器中后能够排序,也可以实现 Comparable 接口,在用 Collections 类的 sort 方法排序时若不指定 Comparator,那就以自然顺序排序。所谓自然顺序就是实现 Comparable 接口设定的排序方式。
- Comparator 是一个专用的比较器,当这个对象不支持自比较或者自比较函数不能满足要求时,可写一个比较器来完成两个对象之间大小的比较。
- Comparator 体现了一种策略模式 (strategy design pattern),就是不改变对象自身,而用一个策略对象 (strategy object) 来改变它的行为。
总而言之 Comparable 是自已完成比较,Comparator 是外部程序实现比较。
本文链接: https://linbei.top/Java%E5%9F%BA%E7%A1%80%E7%96%91%E9%9A%BE%E7%82%B9/
版权声明: 本作品采用 知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议 进行许可。转载请注明出处!