Inheritance
1. 派生类访问基类的私有域——必须借助基类的公有接口
Q:
1. 既然子类自动继承了父类的域,那么子类访问自己的域为何受限?
2. 如果子类方法每一次访问实例域,都要调用父类的公有接口,从实现角度看,是相当的繁琐,难道没有捷径走?
2. 派生类的构造器
调用父类构造器,初始化父类的“私有域”!
强调:
1. super必须是子类构造器的第一条语句
2. 若子类构造器未显式调用父类构造器(无super),则自动调用父类无参构造器
3. 在上述情况下,若父类未编写无参数构造器,则编译器报错
3. 比较super和this
| 必须作为第一条语句出现 |
|
super | 子类调用父类的构造器 | 调用父类方法 |
this | 调用本类的其他构造器 | 引用隐式参数 |
4. 多态ploymorphism
1. is-a规则:子类的每个对象也都是超类的对象
2. is-a置换准则:凡是超类对象出现的地方都可以用子类对象替换。例如,超类变量引用子类对象
3. Java中,对象变量是多态的:变量val既可以引用Emp对象,也可以引用Emp任何子类的对象
4. 即便超类变量可以引用子类对象,但这并不意味着它可以调用子类的特有方法,毕竟在编译器看来,它本质上仍然是超类的,因此,调用子类方法是非法的
5. 自然地,子类变量不能引用超类对象,所以,不能把超类引用赋给子类变量
6. Java中,子类数组的引用可以转换成超类数组的引用,而不需要类型转换。
强调:所有数组牢记创建的元素类型,只能将类型兼容的引用存储到数组中
5. 动态绑定Dymastic bilding
1. 编译器查看对象的声明类型和方法签名(方法名和参数类型)
2. 静态绑定(private、static、final修饰的方法)
3. 预先为每个类创建方法表,以节省时间开销
6. 子类和父类
1. 访问修饰符:子类的可见性低于父类
2. 可协变性:子类覆写方法的返回类型必须兼容父类的原始方法
3. 异常声明:父类声明的异常更通用
7. 阻止继承:final类
操作对象 | 对类的影响 | 对方法的影响 | 对实例域的影响 |
final类 | 不允许扩展(被继承) | final |
|
final方法 |
| 不允许子类覆写 |
|
final实例域 |
|
| 初始化后不允许修改值 |
为什么会有final类和方法:避免在子类中被改变语义
8. 强制类型转换
1. 为什么我们要进行类型转换?
在暂时忽略对象的实际类型后,使用对象的全部功能
2. 类型转换的陷阱?
在Java中,每个对象变量都属于一个类型。类型描述了该变量所引用以及能够引用的对象类型
将一个值存入变量,编译器将检查是否合法(只允许两种情况):1.子类引用赋给超类变量2.超类引用经过类型转换赋给子类变量(超类引用了子类对象)
3. 总结
进行类型转换之前,必须查看能否成功转换,否则将产生ClassCastException异常
所以,严格来讲,上述代码应该改为下述形式:
9. Object类
n equals方法
n instanceof运算符:对象是否是这个特定类或者是它的子类的一个实例
n 完美的equals方法如何编写?6’
n equals方法在继承中出现的问题:
n hashCode方法
n 散列码如何生成?
n hashCode方法和equals方法的联系:
n toString方法
n toString方法在子类中如何编写?
n System.out.println(x);当x是基本类型发生了什么?
10. 抽象类abstract——设计思想、模式
约定:
1. 包含抽象方法的类必须被声明抽象类
2. 抽象类可以包含具体数据和具体方法,这些域和方法应该通用的,与是否抽象无关
3. 即使不含抽象方法,也可以声明为抽象类
4. 抽象类不能被实例化,只能定义对象变量
5. 抽象类的对象变量只能引用非抽象子类的对象
11. 泛型数组列表
12. 对象包装器和自动装箱
1. 基本数据类型包装器wrapper:9’
Number(Integer/Long/Short/Byte/Float/Double)/Character/Void/Boolean
2. 不可变:一旦构造,其中的数值不许更改;final类:不可拓展
3. 泛型数组列表的参数类型不允许是基本数据类型,只能用包装器
4. 对象包装器没有基本数据类型效率高,所以数据集合的规模不要大
5. autoboxing & autounboxing:编译器认可,虚拟机执行
6. 相等性
why???
13. “变参”方法
按照书本上的解释,我觉得应该是Double…values
14. 枚举类
15. 反射