要想了解extends关键字,我们先要了解继承。继承是软件开发人员用来在类别之间建立is-a关系的一种编程结构。继承使我们能够从更通用的类别中派生出更具体的类别。Java通过类扩展支持单一继承,其中一个类通过扩展该类直接从另一类继承可访问的字段和方法。但是,Java不支持通过类扩展进行多重继承。
Java通过extends关键字支持类扩展。如果存在,则extends指定两个类之间的父子关系。下面,我们用extends在类Vehicle和之间建立关系Car,然后在Account和之间建立关系SavingsAccount:
例1. extends关键字指定了父子关系
class Vehicle
{
// member declarations
}
class Car extends Vehicle
{
// inherit accessible members from Vehicle
// provide own member declarations
}
class Account
{
// member declarations
}
class SavingsAccount extends Account
{
// inherit accessible members from Account
// provide own member declarations
}
该extends关键字的类名之后和在另一个类名指定。之前的班级名称extends标识子级,之后的班级名称extends标识父级。之后,extends由于Java不支持基于类的多重继承,因此无法指定多个类名称。
这些示例将is-a关系整理为:Car 是一个特殊的Vehicle,SavingsAccount 是一个特殊的Account。Vehicle并且Account被称为基类,父类或超类。Car并且SavingsAccount被称为派生类,子类或子类。
子类从其父类和其他祖先继承可访问的字段和方法。但是,它们从不继承构造函数。而是,子类声明其自己的构造函数。此外,他们可以声明自己的领域和方法,以区别于父母。参照例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描述了具有名称和初始金额的通用银行帐户类,它们都在构造函数中设置。此外,它还允许用户进行存款。(可以通过存入负数进行提款,但是我们会忽略这种可能性。)请注意,在创建帐户时必须设置帐户名称。
例3给出了SavingsAccount扩展Account其父类的子类。
例3. SavingsAccount子类扩展了Account其父类
class SavingsAccount extends Account
{
SavingsAccount(long amount)
{
super("savings", amount);
}
}
的SavingsAccount,因为它不需要额外的声明字段或方法的类是微不足道的。但是,它确实声明了一个构造函数,该构造函数初始化其Account超类中的字段。初始化发生在Account通过Java的super关键字调用的构造函数,然后是带括号的参数列表时。
例4进一步扩展Account了一个CheckingAccount类。
例4. CheckingAccount子类扩展了Account其父类
class CheckingAccount extends Account
{
CheckingAccount(long amount)
{
super("checking", amount);
}
void withdraw(long amount)
{
setAmount(getAmount() - amount);
}
}
CheckingAccount比SavingsAccount它声明一个withdraw()方法要实质性得多。
类层次结构示例:创建了一个AccountDemo应用程序类,可尝试使用Account类层次结构。首先看一下AccountDemo的源代码。
例5. AccountDemo演示帐户类层次结构
class AccountDemo
{
public static void main(String[] args)
{
SavingsAccount sa = new SavingsAccount(10000);
System.out.println("account name: " + sa.getName());
System.out.println("initial amount: " + sa.getAmount());
sa.deposit(5000);
System.out.println("new amount after deposit: " + sa.getAmount());
CheckingAccount ca = new CheckingAccount(20000);
System.out.println("account name: " + ca.getName());
System.out.println("initial amount: " + ca.getAmount());
ca.deposit(6000);
System.out.println("new amount after deposit: " + ca.getAmount());
ca.withdraw(3000);
System.out.println("new amount after withdrawal: " + ca.getAmount());
}
}
main()清单5中的方法首先演示SavingsAccount,然后CheckingAccount。假设Account.java,SavingsAccount.java,CheckingAccount.java,和AccountDemo.java源文件是在同一目录中,执行以下命令中的任编译所有这些源文件的:
javac AccountDemo.java
javac *.java
执行以下命令以运行该应用程序:
java AccountDemo
输出:
account name: savings
initial amount: 10000
new amount after deposit: 15000
account name: checking
initial amount: 20000
new amount after deposit: 26000
new amount after withdrawal: 23000
子类可以重写(替换)继承的方法,以便改为调用子类的方法版本。覆盖方法必须指定与被覆盖方法相同的名称,参数列表和返回类型。为了演示,我print()在Vehicle下面的类中声明了一个方法。
例6.声明print()要重写的方法
class Vehicle
{
private String make;
private String model;
private int year;
Vehicle(String make, String model, int year)
{
this.make = make;
this.model = model;
this.year = year;
}
String getMake()
{
return make;
}
String getModel()
{
return model;
}
int getYear()
{
return year;
}
void print()
{
System.out.println("Make: " + make + ", Model: " + model + ", Year: " +
year);
}
}
本文我们通过实例介绍了使用Java的extends关键字从父类派生子类,调用父类的构造函数和方法,覆盖方法等等。想要彻底掌握extends关键字,还需要更深入的学习,以上提到的只是我们需要掌握的基本知识和操作,可以结合本站的其他文章和专业课程来为自己解惑答疑,更快地学习Java知识。
HelloWorld10-31 08:24
军哥08-12 23:29
江湖人称小李白12-10 10:41
IT逐梦者08-17 21:43
HelloWorld11-06 11:19