面向对象
- 封装:隐藏细节
- 继承:子类继承父类
- 多态:
final关键字:子类不能覆盖父类中final修饰的方法,会报语法错误,属性没事儿,final意为最终(即不可更改),属性没事儿应该是因为它被理解为是子类的属性,不是重写的父类。
对象类型转化:强转容易出错,建议先 instanceof 判断类型,再强转。
子类可以通过super调用父类中的属性或方法,也可以调用被覆盖重写的属性的原版值。
方法重载
在同一个类中, 允许存在一个以上的同名方法, 只要它们的参数个数或者参数类型不同即可(与返回值类型无关, 只看方法名和参数列表)。
//如仅返回类型不同,方法名、参数列表都相同,这样的代码是不合法的
public int sum(int a){...} //此处会报语法错误
public boolean sum(int a){...} //此处会报语法错误
方法重写
类似于在子类中写了一个与父类相同返回值类型、方法名、参数列表的函数,相当于函数的覆盖。
抽象类和接口
- 抽象类的意义在于派生出子类,子类总是比父类更具体
- 抽象类包不包含抽象方法均可,但有抽象方法的一定是抽象类
- 子类通常实现抽象类的所有抽象方法,如果没有完全实现,子类也必须被定义为抽象类
- 抽象类允许包含静态字段和静态方法,但static和abstract不能共存
- 抽象类可以提供某些方法的部分实现(也就是可以有函数体)
- 抽象类、接口都不能被实例化
- 接口可被任何类实现,抽象类常用于被子类化,并共享部分实现
- 一个类只有一个直接父类,但可以实现多个接口
初学者应注意接口和抽象类在实际中的灵活应用,勿死磕概念。
集合
Collection接口(集合的最顶层接口)
它拥有两种遍历方式
- for-each
- Iterator迭代(如果涉及到remove元素,要使用这种迭代的方式,for-each可能会引发错误)
void filter(Collection<?> c){
for(Iterator<?> it=c.iterator();it.hasNext();){
if(!cond(it.next())
it.remove();
}
}
//移除集合c中的所有null元素
//singleton是一个静态工厂方法,返回一个包含指定元素的不可变Set集合
c.removeAll(Collections.singleton(null);
//将集合转为数组
Object[] a = c.toArray();
//有一种指定转换类型的复杂形式
String[] a = c.toArray(new String[0]);
Set接口——不能包含重复元素
3个通用实现:
- HashSet——哈希表存储,性能最佳
- TreeSet——红黑树存储,顺序排列
- LinkedHashSet——哈希表存储,链表连接,从而实现了顺序排列
List接口——有序集合,允许重复
2个通用实现:
- ArrayList——底层是基于动态数组,所以根据下标访问指定元素的效率高,末尾添加元素的效率高,但删除元素时会进行数组移位(比如删除第一个元素,其余所有元素都要依次向前移动一位)
- LinkedList——基于链表的动态数组,数据添加删除效率高,只需要改变指针指向即可,但是访问数据的平均效率低,需要对链表进行遍历
Map接口——键值对结构,键不重复
3个通用实现:
- HashMap——同上
- TreeMap——同上
- LinkedHashMap——同上
初学者注意以上只是几种通用实现,还存在其他的实现类,使用场景不同选择不同。