内部类主要用于设计具有相互协作关系的类集合。
接口默认的方法是public,默认的接口常量是public static final。 所以接口中尽量不要写上这些默认的重复值。但是在实现类中的方法一定要写上public。
接口中不能有实例域。
因为compareTo要求返回一个整型,所以compareTo方法的注意点:
1. 减法的溢出:一个正整数减去一个负整数,值可能会超出整数的最大值。
2. 浮点数相减,两个很接近但不相等的数,有可能差值四舍五入后变成了0,二者就相等了。
所以要注意不能直接这样返回 if(a>b) return a-b; 可以返回 1 0 -1
如果非要这么做,就要确保两点:
两个int型的绝对值都不超过整数最大值的1/2
或者 相减的两个int值同正或同负
为什么不能直接实现compareTo方法而非要先实现comparable接口呢?
因为java是强类型语言,在调用sort方法的时候,一定要用到compareTo,编译的时候编译器就要判断是否有此方法。那么如何判断呢?java的规则就是如果你实现了comparable接口,那么就必然有此方法,我就编译通过。否则就报异常。
说白了,就是java自己定义的规则,要sort就必须满足条件:实现comparable接口或者comparator接口
java实现排序的两种方式:
第一种,实现comparable接口,重写compareTo方法。集合类调用sort方法,传入要排序的集合。
第二种是写一个实现一个comparator接口的类(比较器),集合类调用sort方法,传入要排序的集合和比较器。
P208
compareTo方法比较两个对象必须可以反对称。对于对称性,必须要考虑参数不是同一个类的情况,即父类和子类。(equals方法也是这样,都要考虑参数不同类的问题)
那么假如父类定义了compareTo方法,子类直接使用可能报错。
父类employe,子类manager
public int compareTo(Employee other){
Manager otherManager = (Manager)other; //NO
……
}
有两种处理方法:
第一种检查不是同一类,抛出异常。
第二种在父类中提供一个final的compareTo方法。
接口与抽象类。抽象类可以说是特殊的类,接口可以说是特殊的抽象类。
接口是为了解决类不支持多继承问题的。
clone方法是Object类的一个protected方法,因此无法直接调用anObject.clone();——这里可以是在子类中定义一个方法,方法中调用super.clone(),但是却不能子类对象直接调用父类的方法。要理清访问权限的问题。
也就是在用户编写的代码中不能直接调用它,只有Employee类才能clone一个employee对象。
注意protected方法的访问权限,同一个包中的所有类和不同包中的子类
拷贝要注意深拷贝和浅拷贝的区别。默认的克隆是浅拷贝。对于引用型的域需要特别注意。
如要重新定义clone方法,需要实现Cloneable接口,并且用public修饰符重新定义clone方法。即使默认的clone方法能够满足需求,也应该这么做,否则无法使用clone。
cloneable是标记接口,标记接口没有方法,唯一目的是为了insatance of检查类型。
回调函数,某个特定的事件发生时应该采取的动作。
内部类可以访问外部类的数据,包括私有域
内部类可以对一个包中的其他类隐藏起来
局部内部类不能用private或public声明,他的作用域被限定在声明这个局部类的代码块中。
局部内部类可以访问局部变量(外部类的变量),不过这些变量需要声明成final的。
要想修改传入的final参数的值,方法是将使用长度为1的数组,修改其中的值即可。
匿名内部类,如果new后边的构造函数的括号后边多了一个{ },那么就是一个匿名内部类。当要定义一个回调函数又不想写大量代码时可以使用匿名内部类。
静态内部类, 如果内部类只为了把类隐藏在另一个类的内部,而不需要内部类引用外部类的对象,就可以使用静态内部类。有些叫嵌套类(nested class)
声明在接口中的内部类自动为public static 。
代理