优秀笔记
5.1 类,超类和子类
- 在设计时应将通用的方法放在超类中,而将特殊的方法放在子类中。
- 子类继承父类的所有域和方法,可是却不能直接访问父类中域的值,必须通过父类提供的公共方法。调用父类的方法用关键字super。
- 由于子类不能直接访问到父类的域,故在子类的构造方法中需要用到super来初始化从父类中继承的域。
- 一个声明为父类类型的对象变量既可以引用父类对象,又可以引用子类对象。虚拟机知道变量实际引用的变量类型,所以能够正确地调用方法,引用哪个类型就调用那个类型的方法。
- 一个对象变量可以引用多种实际类型的对象的现象称为多态。在运行时能够自动选择调用哪个方法的现象称为动态绑定。
- 方法调用的具体步骤:
- 编译器查看对象的声明类型和方法名,然后列出所有本类中和超类中修饰符为public的同名方法。
- 编译器查看调用方法是提供的参数类型,如果在1的列表的方法中存在参数类型完全匹配的,那么就调用这个方法,这个过程称之为重载解析。
- 如果是private方法,static方法,final方法或者构造器,那么编译器将可以准确的知道应该调用什么方法,我们将这种调用方式称之为静态调用。如果调用的方法依赖于隐式参数的实际类型即调用方法的对象变量实际引用的类型,并且在运行时实现动态绑定,那么我们称之为动态绑定。
- 当程序运行,并采用动态绑定的方式来调用方法时,虚拟机一定调用与对象变量所引用的实际类型最合适的那个类的方法,即优先查找本类,如果本类中没有符合的方法,那么查找父类。
- 动态绑定的重要特性:无需对现存的代码进行修改,就可以对程序进行扩展。
- 使用final关键字可以阻止其他类继承此类,在final类中所有的方法都自动声明为final,域则不会。
- 在Java中每个对象变量都属于一个类型,类型描述了这个变量所引用的以及能够引用的对象类型,即这个类和他的子类。
- 进行类型转换的唯一原因是:在暂时忽略对象的实际类型后,使用对象的全部功能。使用instanceof操作符可以判断是否能够成功转换
if(employee instanceof Manger){};
。
5.2 object:所有类的超类
- 在Java中只有基本类型不是对象,object是所有对象的超类。
- 编写equals方法的建议:
1.比较两个类是否引用同一个对象
if(this == otherObject)return true;
2.检查otherObject是否为null
if(otherObject == null) return false;
比较两个类是否属于同一个类
if(getClass() != otherObject.getClass()) return false;
3.将otherObject强制转换为this的同类,然后在进行相关域的比较。使用==来比较基本类型域,使用equals来比较对象域。
ClassName other = (ClassName)otherObject;
return field1 == other.field1 && Objects.equals(field2,other.field2) && ...;
- 为了避免发生类型错误,可以使用@Override对覆盖的超类方法进行标记。
@Override public boolean equals(Object other)
- hashCode(散列码)是由对象导出的一个整型值,也可以为负数,散列码是没有规律的。他代表的是对象的存储地址。
- 重写equals方法的同时也必须重写hashCode方法,为了将对象插入到散列表中。
- Objects.hashCode方法 防止空指针异常。
- 调用 JDK1.7 中的 Objects.hash方法 ,并提供多个参数,可组合多个散列值。
- 数组类型的域,使用静态的 Arrays.hashCode方法 来计算散列码。
- 一个类的equals方法必须与hashCode方法定义一致,即如果equals方法比较ID,那么hashCode方法就需要散列ID,这么做的原因是如果
a.equals(b)
返回ture,那么a.hashCode()
与b.hashCode()
返回值也要一致。 - toString方法用于返回描述对象的字符串。
getClass().getName()
方法用于返回类名的字符串。- Object 类定义了 toString 方法,用来打印输出 对象所属的 类名和散列码。
- 建议为自定义的每一个类增加 toString 方法。
5.3 泛型数组列表
- ArrayList是一个采用类型参数的泛型数组。使用方法为
ArrayList<Employee> staff = new ArrayList<Employee>();
- 泛型数组可以自动调节数组容量。
- add方法添加元素,set方法替换元素,get方法获取元素,size方法获取当前数组的长度。
- 如果调用add方法添加元素且内部空间已经满了,那么泛型数组就会创建一个更大的数组,并将所有的对象拷贝过去。
- trimToSize方法用于固定当前泛型数组的长度,垃圾回收器将会回收多余的空间,应当确认不会再添加元素时使用此方法。