《Java编程思想》读书笔记(二)

第五章 隐藏实施过程

包:库单元

  1. 每个编译单元(一个.java文件)内部只能有一个public类,对于.java文件中的每个类都有一个.class扩展名。一个有效程序就是一系列.class文件,他们可以封装压缩到一个JAR文件里
  2. package 语句必须作为文件的第一个非注释语句出现,作用是指出这个编译单元属于名为某个库的一部
  3. package 和 import 关键字分割单个全局命名空间,保证不会产生名字的冲突
  4. Java 解释器的工作程序:找到环境变量CLASSPATH,从这里展开对.class 文件的搜索,生成从 CLASSPATH 根开始的一个路径名,成为CLASSPATH 内的各个条目(入口)

Java访问指示符

  1. Java中每个访问指示符都只控制着对那个特定定义的访问,这与C++存在着显著不同,在C++中,访问指示符控制着它后面的所有定义,直到又一个访问指示符加入为止
  2. 无修饰符,即默认为friendly,相同包内的类可以访问,子类不在同一包中时不可以访问。当某个文件没有明确的包名时,Java会将其看做“默认包”的一部分,该文件对于所在目录中的其他文件来说是friendly
  3. public为对所有类开放访问;private仅能被当前类的方法访问;protected可以被同一包中的类以及所有子类(即使子类不在同一包中)访问

类访问

可使用访问指示符对类添加限制,但要注意:

1) 每个编译单元(文件)都只能有一个public 类

2)public 类的名字必须与包含了编译单元的那个文件的名字完全相符,甚至包括它的大小写形式

3)可能(但并不常见)有一个编译单元根本没有任何public类,此时可按自己的意愿任意指定文件名

4)不可将类设成 private(那样会使除类之外的其他东西都不能访问它),也不能设成 protected,若不愿其他任何人访问那个类,可将所有构建器设为private

第六章 类再生

类再生:通过创建新类来重复使用代码,但却用不着重新创建,可以直接使用别人已建好并调试好的现成类。但这样做必须保证不会干扰原有的代码。有两种方法:

1)类的合成:在新类里简单地创建原有类的对象

2)类的继承

继承的语法

  1. 继承是java面向对象编程技术的一块基石,因为它允许创建分等级层次的类。继承就是子类继承父类的特征和行为,使得子类对象(实例)具有父类的实例域和方法,或子类从父类继承方法,使得子类具有父类相同的行为

  2. super关键字:引用当前类继承的“超类”(Superclass)的属性或方法

  3. 创建衍生类的一个对象时,它在其中包含了基础类的一个“子对象”。这个子对象就象我们根据基础类本身创建了它的一个对象。从外部看,基础类的子对象已封装到衍生类的对象里了

  4. 在衍生类的构建器中,Java 会自动插入对基础类构建器的调用

  5. 在衍生类的构建器中,对基础类构建器的调用是必须做的第一件事情

合成与继承的结合

  1. 如果需要进行清除,要注意清除顺序:首先完成与类有关的所有特殊工作(可能要求基础类元素仍然可见),然后调用基础类清除方法
  2. 无论一个方法在衍生类还是基础类中定义,重载都会生效

到底选择合成还是继承

“属于”关系是用继承来表达的,而“包含”关系是用合成来表达的

上溯造型

  1. 上溯造型肯定是安全的,因为我们是从一个更特殊的类型到一个更常规的类型
  2. 父类和子类均有一个变量,最后拿到的是父类的变量
  3. 父类和子类均有一个方法,最后执行的是子类的方法
  4. 在判断是否要用到继承时,一个最简单的办法就是考虑是否需要从新类上溯造型回基础类。若必须上溯,就需要继承。但如果不需要上溯造型,就应提醒自己防止继承的滥用

final关键字

  1. final数据:

    • 对于基本数据类型,final 会将值变成一个常数(编译期常数,它永远不会改变),对这样的一个常数进行定义的时候,必须给出一个值,且这个值不能修改
    • 对于对象句柄,final 会将句柄变成一个常数,进行声明时,必须将句柄初始化到一个具体的对象,而且永远不能将句柄变成指向另一个对象,但对象本身是可以修改的,同样的规则也适用于数组
    • static与final共用时,static强调变量只有一个(只会初始化一次),final强调是一个常数
  2. 空白final:尽管被声明成 final,但却未得到一个初始值,但必须在实际使用前正确的初始化。强行要求对空白final 进行赋值处理——要么在定义字段时使用一个表达式,要么在每个构建器中进行初始化。这样做可以使位于类内部的一个final 字段对每个对象都可以有所不同,同时依然保持其“不变”的本质

  3. 可将方法的参数变量设为final属性,但在该方法的内部,不能改变该变量的内容,即基本变量的值不能修改,对象的内容也不能修改(仅可读)

  4. final方法:

    • 为方法“上锁”,防止任何继承类改变它的本来含义,即该方法的行为在继承期间保持不变,而且不可被覆盖或改写
    • 程序执行效率高:将一个方法设成 final 后,编译器会忽略方法调用机制而采取的常规代码插入方法,即用方法主体内实际代码的一个副本来替换方法调用。只有在方法的代码量非常少,或者想明确禁止方法被覆盖时,才考虑将一个方法设为final
    • 类内所有private方法都自动成为final
  5. final类:不允许继承,由于禁止了继承,所以一个 final 类中的所有方法都默认为 final

初始化和类装载

  1. 类代码在首次使用的时候载入。装载的时候,所有static 对象和 static 代码块都会按照本来的顺序初始化(亦即它们在类定义代码里写入的顺序),static 数据只会初始化一次
  2. 继承初始化:
    • 在装载过程中,如果发现有一个基础类(extends),基础类也会随之装载,直到载入根基础类
    • 接下类从基础类开始执行static初始化,然后是下一个衍生类,以此类推
    • 此时必要的类已经装载完毕,可以创建对象,首先对象中所有的基本类型会设为默认值,对象句柄设为null
    • 随后调用类构建器,先基础类后衍生类,实例变量会按照本来的顺序得以初始化,最后执行剩余的部分