Java中的继承(三)

继续使用上一篇Java中的继承(二)中的代码为例。在Java中有一种可以用来判断时都应该将数据设计为继承关系的规则,也就是”is-a”规则。这表明一个子类的对象也是超类的对象。

简单来说所有在使用超类的地方都可以使用子类来替换。比如示例代码中的经理都是雇员一样。但是在子类的地方不可以使用超类来替换。比如不是所有雇员都是经理。也就是说is-a规则是单向的,只能由子类替换超类,而不能使用超类来替换字类。因为根据继承的规则,子类拥有所有超类的方法和域,因此超类可以使用子类来替换。但是更重要的是,子类可以添加或者重写方法或者域,因此就不能保证子类能够使用超类来替换。

例如可以将一个子类的对象变量赋给超类的变量:

Employee e;
e=new Employee(…);
e=new Manager(…);

另外,可以这样使用:

Manager boss=new Manager(…);
Employee[] staff=new Employee[3];
staff[0]=boss;

在这段代码中,声明了一个一个Manager类型的boss对象,一个Employee类型长度为3的staff数组对象,boss对象被当作Employee类型类型在staff[0]处被引用。这说明,子类是可以被当作超类的对象。

这意味着,可以如此调用:

boss.setBonus(5000);

但是却不能如此调用:

staff[0].setBonus(5000);

这是因为staff[0]处的boss对象的类型是Employee,但是staff数组是Employee类型的。因此根据is-a规则的单项性,超类是不能被当作子类来使用的,因为Employee类型的对象中并没有setBonus方法,所以编译器会返回错误。

在设计类的时候,如果不希望一个类被继承的话可以使用final关键字。不允许扩展的类被称为final类。如果不希望有人定义Manager类的子类就可以这样写:

final class Manager extends Employee{
    …
}

超类中的方法也可以声明为final,这样子类就不能修改final方法,以保持方法的语义不被改变。

2 Comments

Leave a Comment.