composition java_全面掌握Java继承的核心和要点

0.摘要

Java通过继承(inheritance)和组合(composition)支持类重用。本教程由两部分组成,教你如何在Java程序中使用继承。在第1部分中,你将学习如何使用extends关键字从父类派生子类、调用父类构造函数和方法以及覆盖方法。在第2部分中,你会了解java.lang.Object,它是Java的超类,其他所有类都继承自该类。

要完成关于继承的学习,请参阅我的Java技巧,它解释了何时使用组合与继承。你会明白为什么组合是继承的重要补充,以及如何使用它来防止Java程序中的封装问题。

1. Java的两例继承

继承是一种编程结构,软件开发人员使用它来建立类别之间的is-a关系。继承使我们能够从更一般的类别派生出更具体的类别。更具体的类别是一种更一般的类别。例如,支票账户是一种你可以存取款的账户。同样,卡车是一种运输大型物品的具体交通工具。

继承可以通过多个层次下降,导致更加特定的类别。例如,图1显示了从vehicle(交通工具)继承的car和truck;旅行车wagon继承自汽车car;垃圾车继承自卡车。箭头从更具体的“子”类别(向下)指向不太具体的“父”类别(向上)。

本例演示了单继承,其中子类别继承一个直接父类别的状态和行为。相反,多重继承使子类别能够从两个或多个直接父类别继承状态和行为。图2中的层次结构演示了多重继承。

4f32bd1e6cb91436b20467fc4a53caa9.png

图1:继承层次图例

类别由类来描述。Java通过类扩展支持单继承,其中一个类通过扩展另一个类直接继承可访问的字段和方法。但是,Java不支持通过类扩展进行多重继承。在查看继承层次结构时,你可以通过菱形解构模式的存在轻松地检测到多重继承。图2显示了车辆、陆地车辆、水上车辆和气垫船上下文中的这种模式。

08201acdd2532e9ef197cbf3308decd1.png

图2 继承关系解构

类别由类来描述。Java通过类扩展支持单继承,其中一个类通过扩展另一个类直接继承可访问的字段和方法。但是,Java不支持通过类扩展进行多重继承。在查看继承层次结构时,你可以通过菱形解构模式的存在形式而轻松地检测到多重继承。图2显示了车辆、陆地车辆、水上车辆和气垫船的上下文中的这种解构模式。

2.关键字extends

Java通过extends关键字来支持类扩展。当存在时,extends指定两个类之间的父-子关系。下面我使用extend来建立类Vehicle和Car之间的关系,然后是Account和SavingsAccount之间的关系:

清单-1:extends标识出父子关系

class Vehicle{ // 成员声明}class Car extends Vehicle{ // 从Vehicle继承了可访问成员 // 这里提供自有的成员声明}class Account{ // 成员声明}class SavingsAccount extends Account{ // 从Account继承的可访问成员 //这里提供自有的成员声明}

extends关键字在类名之后和另一个类名之前指定。在extends之前的类名标识出子类,在extends之后的类名标识出父类。extends后不可能指定多个类名,因为Java不支持基于类的多重继承。

这些例子编写了is-a关系:Car是一个专门的车辆,SavingsAccount是一个专门的帐户。Vehicle和Account被称为基类、父类或超类。Car和SavingsAccount被称为派生类、子类或子类。

final型的类

你可以声明一个不允许扩展的类;比如出于安全原因。在Java中,我们使用final关键字来防止某些类被扩展。简单地在类头前面加上final,就像 final class Password 一样。一旦给定此种声明,如果有人试图扩展Password,编译器将报告错误。

子类从父类和其他祖先继承可访问的字段和方法。但是,它们从不继承构造函数。相反,子类声明它们自己的构造函数。此外,它们可以声明自己的字段和方法,以区别于它们的父类。考虑清单2所示。

清单2:一个Account父类

class Account{ private String name; private long amount; Account(String name, long amount) { this.name = name; setAmount(amount); } void deposit(long amount) { this.amount += amount; } String getName() { return name; } long getAmount() { return amount; } void setAmount(long amount) { this.amount = amount; }}

清单2描述了一个具有名称name和初始金额amount的通用银行帐户类,它们都在构造函数中设置。此外,它还允许用户存款。(你可以通过存入负数来取款,但我们将忽略这种可能性。)注意,帐户名必须在创建帐户时设置。

注意:

货币量表示。在表示货币值的数量时,你可能更喜欢使用double或float来存储货币值,但是这样做可能会导致不准确。要获得更好的解决方案,推荐使用BigDecimal,它是Java标准类库的一部分。

清单3显示了一个SavingsAccount子类,它扩展了它的Account父类。

请单3:继承自Account的子类SavingsAccout

class SavingsAccount extends Account{ SavingsAccount(long amount) { super("savings
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值