Java核心卷一复习笔记(3)——第五章

  • Post author:
  • Post category:java


5.1.3 子类构造器
使用super 调用构造器的语句必须是子类构造器的第一条语句 。
如果子类的构造器没有显式地调用超类的构造器 , 则将自动地调用超类默认 ( 没有参数 )的构造器。如果超类没有不带参数的构造器 , 并且在子类的构造器中又没有显式地调用超类的其他构造器 ’ 则 Java 编译器将报告错误。
结论:

创建子类对象时,先调用父类构造方法,再调用子类构造方法,然后创建子类这个对象。
5.1.5
对象变量是多态的 。 一个Employee 变量既可以引用一个Employee 类对象 , 也可以引用一个 Employee 类的任何一个子类的对象


方法的重写(override)两同两小一大原则





方法名相同,参数类型相同

子类返回类型小于等于父类方法返回类型,

子类抛出异常小于等于父类方法抛出异常,

子类访问权限大于等于父类方法访问权限。

5.1 . 7 阻止继承 : final 类和方法



希望阻止人们利用某个类定义子类 。 不允许扩展的类被称为 final





。 如果


在定义类的时候使用了 final 修饰符就表明这个类是 final 类




类中的特定方法也可以被声明为 final 。 如果这样做

, 子类就不能覆盖这个方法 ( final类中的所有方法自动地成为 final 方法 )。
域也可以被声明为 final 。 对于 final 域来说 , 构造对象之后就不允许改变它们的值了 。 不过, 如果将一个类声明为
final , 只有其中的方法自动地成为 final ,而不包括域。
String 类也是 final 类 , 这意味着不允许任何人定义 String 的子类。 换言之 , 如果有一个 String
的引用, 它引用的一定是一个 String 对象, 而不可能是其他类的对象 。
5.1.9 抽象类
包含一个或多个抽象方法的类本身必须被声明为抽象的。
类即使不含抽象方法, 也可以将类声明为抽象类 。抽象类不能被实例化。
可以定义一个抽象类的对象变量 , 但是它只能引用非抽象子类的对象 。
5.1.10 受保护的访问
子类也不能访问超类的私有域。
希望超类中的某些方法允许被子类访问 ,或允许子类的方法访问超类的某个域。 为此 , 需要将这些方法或域声明为 protected 。
下面归纳一下 Java 用于控制可见性的 4 个访问修饰符 :
1 ) 仅对本类可见 private。
2 ) 对所有类可见 public :
3 ) 对本包和所有子类可见 protected。
4 ) 对本包可见 — 默认 ( 很遗憾 ) ,不需要修饰符。
5.2 超类
Object 类是 Java 中所有类的始祖 , 在 Java 中每个类都是由它扩展而来的。 但是并不需要这样写 :
public class Employee extends Object
如果没有明确地指出超类, Object 就被认为是这个类的超类
5.2.1 equals
Object 类中的 equals 方法用于检测一个对象是否等于另外一个对象 。 在 Object 类中 , 这个方法将判断两个对象是否具有相同的引用。 如果两个对象具有相同的引用 , 它们一定是相等的。
5.2.3 hashCode方法
散列码 ( hash code ) 是由对象导出的一个整型值。 散列码是没有规律的 。
static int hash ( Object . .. objects )
返回一个散列码, 由提供的所有对象的散列码组合而得到 。
5.2.4 toString()方法
如果 x 是任意一个对象 , 并调
System . out . println ( x ) ;
println 方法就会直接地调用 x . toString ( ), 井打印输出得到的字符串 。
Object 类定义了 toString 方法 , 用来打印输出对象所属的类名和散列码 。 例如 , 调用
System . out . println ( System . out )
将输出下列内容 :
java . io . Pri ntStream@2f6684
之所以得到这样的结果是因为 PrintStream 类的设计者没有覆盖 toString 方法。
5.3 泛型数组列表
如果调用 add 且内部数组已经满了, 数组列表就将自动地创建一个更大的数组, 并将所有的对象从较小的数组中拷贝到较大的数组中 。如果已经清楚或能够估计出数组可能存储的元素数量 , 就可以在填充数组之前调用ensureCapacity 方法 :
staff . ensureCapacity ( lOO ) ;
这个方法调用将分配一个包含 100 个对象的内部数组。 然后调用100 次 add , 而不用重新分配空间。另外
, 还可以把初始容量传递给 ArrayList构造器 :
ArrayList < Employee > staff = new ArrayListo ( lOO )
5.4对象包装器与自动装箱
将 int 这样的基本类型转换为对象 。 所有的基本类型都冇一个与之对应的类。
对象包装器类是不可变的 , 即一旦构造了包装器 , 就不允许更改包装在其中的值。
对象包装器类还是 final ,因此不能定义它们的子类 。
有一个很有用的特性 , 从而更加便于添加 int 类型的元素到 ArrayLisKlntegeP中。 下面这个调用
list . add ( 3 ) ;
将自动地变换成
list . add ( Integer . value 0f ( 3 )) ;
这种变换被称为自动装箱 ( autoboxing ) 。
相反地 , 当将一个 Integer 对象赋给一个 int 值时, 将会自动地拆箱 。 也就是说 , 编译器将下列语句 :
int n = list . get ( i ) ;
翻译成
int n = list . get ( i ) . intValue ( ) ;
= = 运算符也可以应用于对象包装器对象, 只不过检测的是对象是否指向同一个存储区域
要想将字符串转换成整型 , 可以使用下面这条语句 :
int x = Integer . parselnt ( s )
5.5 参数数量可变的方法
System . out . printf(“%d ” , n ) ;
System . out . printf ( ” %d % s “, n , ” widgets ” ) ;
在上面两条语句中, 尽管一个调用包含两个参数 , 另一个调用包含三个参数 , 但它们调用的都是同一个方法。
printf 方法是这样定义的 :
public class PrintStream
{
public PrintStream printf ( String fmt , Object .. . args ) { return format ( fmt , args ) ; }
}
这里的省略号 . . . 是 Java 代码的一部分, 它表明这个方法可以接收任意数量的对象 ( 除fmt参数之外 )。
实际上, printf 方法接收两个参数 , 一个是格式字符串 ,另一个是 Object ] 数组 ,

和String类不同的是,StringBufffer和StringBuilder类的对象能够被多次的修改,并且不产生新的未使用对象。

StringBuilder类在Java5中被提出,它和StringBuffer直接的最大不同在于StringBuilder的方法不是线程安全的(不能同步访问)。由于StringBuilder相较于StringBuffer有速度优势,所以多数情况下建议使用StringBuilder类。但在要求线程安全下,必须使用StringBuffer类。



版权声明:本文为qq_34230513原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。