第五章 继承

5.1 类 超类和子类

  • 关键字extends 用来继承
  • 关键字super在子类的方法中调用父类的方法,还可以用来调用父类的函数。
  • 在子类中不能删除父类的域和方法

子类的构造器

  1. 使用super()方法调用父类的构造器,但必须是子类构造器的第一条。
  2. 若子类构造器没有显式调用超类的构造器,默认调用父类的无参数构造器,此时若父类中没有,报错。

继承的层次

  • 一个祖先类可以拥有多个子孙继承链

多态

程序中任何出现超类对象的地方都可以用子类对象替换。(反过来不可以滴)
也就是说,对象变量是多态的

方法调用的原理

注:虚拟机会预先为每个类创建方法表。
注意:子类方法不可低于超类方法的可见性。

阻止继承 final类和方法

  • 父类中被final修饰的方法不能被子类覆盖、
  • final类中所有方法自动成为final方法,但是不包括域(也就是说,域仍然是变量)

final的好处?
可以避免动态绑定带来的开销。

强制类型转换

明确:父类向子类的转换必然报错。
使用instanceof()函数预先检查,避免报错。
一般情况下,尽量少使用类型转换。

抽象类

把更具有通用性的属性放置在较高层次的通用超类中。

  • 抽象类使用abstract关键字。
  • 凡包含抽象方法的类都是抽象类。当然抽象类也可以包含具体数据和具体方法。
  • 即使不含抽象方法,也可以是抽象类。

一些抽象类的注意点:

  1. 抽象类不可以实例化
  2. 可以定义抽象类的对象变量,但是必须引用非抽象 类的对象。
  3. 然而,必须注意,抽象类的对象变量只能调用抽象类中声明的方法。

受保护访问

  • protected关键字:子类得到信任,但是其他类不行。

5.2 Object类:所有类的超类

  1. 该类的对象可以引用任何类型的对象
  2. 只有基本类型不是对象,其他的都是对象
  3. 在子类中定义equals方法需要先调用超类的equals方法,如果相等则继续比较子类的实例域。
  4. if(!super.equals(otherObject)) return false;

相等测试与继承

如何编写一个完美的equals()方法?
1)显示参数命名为otherObject,稍后转化为一个叫other的变量。
2)检测this与otherObject是否引用同一个对象
3)检测Otherobject是否是null。
4)比较this与otherObject是否属于同一个类,如果equals的语义在每个子类中有所改变,那么使用getclass检测。
5)将otherObject转化为相应的类类型变量。
6)现在开始对所有的域进行比较。

注:数组的比较可以用Array.equals()方法进行检测,每一个数组元素是否相等。

hashCode方法

  • 定义在Object类中,因此每一个对象都有默认的散列码。其值为对象的存储地址。
  • 该方法返回整形数值,注意 合理组合各个实例域的散列码,让生成的hashCode()更加均匀。
  • 静态的Objects.hashCode()方法,是null安全的。Double.hashcode()避免生成Double对象。
  • 更好的做法,使用hash()组合多个散列值。
  • Equals和hashCode的定义 必须一致。
  • 数组类型的域有:Array.hashcode()

toString 方法

数组的打印使用Arrays.toString()的静态方法,而不用toSring
如果是多维数组,则需要使用Arrays.deepToString()

5.3 泛型数组列表

在使用ArrayList构造器时,可以使用:
1)ensureCapacity(100)预先分配空间。
2)也可以ArrayList<employee>staff=new ArrayList<>(100)
这两者是等价的。
在确认数组大小不发生变化之后 staff.trimTiSize()可以去除空块。

一个扩展数组的小技巧:
X[]a=new X[list.size()]
list.toArray(a) 将数组元素拷贝到一个数组中。

类型化与原始数组列表的兼容性问题

兼容主要表现在函数的参数与返回值两个方面。

可以将类型化数组列表传递给原始数组列表参数
但是,反过来会有警告,在警告无严重后果时,可以加@suppress(“unchecked”)语句。
P183

5.4 对象包装器与自动装箱

  • 自动装箱和自动拆箱是指Integer 和int两者之间的转化。
  • 对象包装器类是final,因此不能被继承。
  • 如何编写修改数值参数值的方法?使用IntHolder类的对象

5.5 参数数量可变的方法

  • 只需要这样给函数传参:(double…values) 其中values是一个数组列表。
  • 以prntf函数为例子,编译器需要对printf的每次调用进行转换,以便将参数绑定到数组上。并在必要的时候进行自动装箱。实际,printf()方法接受了两个参数,一个是格式字符串,一个是Object[]数组,其中保存着所有的参数。如果调用者提供的是整形数组或者是基本类型的值,那么自动装箱可以把他们转化成对象。

5.6枚举类

  • 比较两个枚举类型的值时,直接==
  • toString 方法的逆方法Size s=Enum.valueOf(Size.class,"Stirng")
  • compareTo比较的是枚举值的索引。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值