5.2、继承

这篇Java教程基于JDK1.8。教程中的示例和实践不会使用未来发行版中的优化建议。
5.2、继承

在前面的教程中,我们多次提到过 继承 。在Java编程语言中,一个类可以从其他的类派生出来,从而继承这些类的字段和方法。

继承 的思想很简单但是非常强大:当你想创建一个新类,但已知有一个类存在一部分你想要的代码,那么你就可以从这个已经存在的类中派生出新的类。这样做,你就可以重用这个类的字段和方法,而不用自己再写一遍。

子类将会继承父类中的所有成员(字段、方法和嵌套类)。构造器不是成员,所以构造器不会被继承,但可以在子类中调用父类的构造器。

Java平台类的层次结构

java.lang package包中定义的 Object 类。定义并实现了所有类的通用行为,在Java平台中,有很多类直接从 Object 类派生而来,另外一些类从其他的类派生而来,如此,就形成了类的层次结构。

在这里插入图片描述
在层次结构的最顶端,Object 类是所有类的最通用部分。靠近层次结构底部的类提供了更具体的行为。

继承的示例

下面的代码是Bicycle 类的一个可能实现:

public class Bicycle {
        
    // the Bicycle class has three fields
    public int cadence;
    public int gear;
    public int speed;
        
    // the Bicycle class has one constructor
    public Bicycle(int startCadence, int startSpeed, int startGear) {
        gear = startGear;
        cadence = startCadence;
        speed = startSpeed;
    }
        
    // the Bicycle class has four methods
    public void setCadence(int newValue) {
        cadence = newValue;
    }
        
    public void setGear(int newValue) {
        gear = newValue;
    }
        
    public void applyBrake(int decrement) {
        speed -= decrement;
    }
        
    public void speedUp(int increment) {
        speed += increment;
    }
        
}

一个声明为MountainBike的类,它继承自Bicycle类,可能是这样的:

public class MountainBike extends Bicycle {
        
    // the MountainBike subclass adds one field
    public int seatHeight;

    // the MountainBike subclass has one constructor
    public MountainBike(int startHeight,
                        int startCadence,
                        int startSpeed,
                        int startGear) {
        super(startCadence, startSpeed, startGear);
        seatHeight = startHeight;
    }   
        
    // the MountainBike subclass adds one method
    public void setHeight(int newValue) {
        seatHeight = newValue;
    }   
}

MountainBike继承了Bicycle的所有字段和方法,同时添加了一个字段seatHeight,以及一个设置该字段的方法。除了构造器之外,这就好像完全从头编写了一个新的MountainBike类,包含四个字段和五个方法。然而,你并不需要从头完成这项工作。如果Bicycle类中的方法非常复杂,并且花费了大量时间进行调试,那么这将更有价值。

你可以在子类中做什么

子类继承了父类所有publicprotected修饰的成员,而不管子类处于哪个包下。如果子类和父类在同一个包下,它将继承父类的package-private成员。你可以按原样使用继承的成员,替换它们,隐藏它们,或者用新成员补充它们:

  • 继承的字段可以直接使用,就跟其他字段一样
  • 可以在子类中定义一个与父类中字段同名的字段,称为 隐藏(不推荐)
  • 可以在子类中声明父类中不存在的字段
  • 继承的方法可以直接使用
  • 可以在子类中声明一个与父类中签名相同的实例方法,称为重写
  • 可以在子类中声明一个与父类中签名相同的静态方法,称为隐藏
  • 可以在子类中声明父类中不存在的新方法
  • 可以在子类构造器中调用父类构造器,隐式调用或者使用关键字super

本课程后续的章节将对以上情形展开讨论。

父类中的私有成员

子类不会继承父类中的private成员。然而,如果父类有提供publicprotected修饰的用来访问private字段的方法,这些方法依然可以被子类使用。
嵌套类可以访问闭包类中的所有私有成员。因此,子类继承的publicprotected嵌套类可以间接访问父类的所有私有成员。

对象转型

我们知道一个对象是实例化该对象的类的类型。比如:

public MountainBike myBike = new MountainBike();

这表示myBikeMountainBike类型的。

MountainBike是由BicycleObject演化而来的。也就是说,一个MountainBike是一个Bicycle,同时也是一个Object。它可以用在任何可以使用BicycleObject的地方。

反过来就不对了:一个Bycicle可能是一个MountainBike,但不是说一定是。同样,一个Object可能是Bicycle或者MountainBike,但不是说一定是。

转型是指用一种类型的对象代表另外一种类型的对象,当然这些对象必须是有继承与实现关系的。比如:

Object obj = new MountainBike();

此时obj既是一个Object也是一个MountainBike。这被称为隐式转换

另一方面,如果:

MountainBike myBike = obj;

我们将获得一个编译错误,因为对编译器而言它不知道objMountainBike类型的。然而,我们可以向编译器保证传递一个MountainBike类型的对象给到obj。如下:

MountainBike myBike = (MountainBike)obj;

该转型引入了一个运行时检查,obj被赋值给MountainBike类型,因此编译器假设objMountainBike类型的。如果在运行时obj不是MountainBike类型的,将会抛出一个异常。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值