英语原文共 719 页,剩余内容已隐藏,支付完成后下载完整资料
第九章
结果
在本章的结束,你应该能够:
解释“继承”一词;
使用UML符号设计继承结构;
在Java中实现继承关系;
区别方法重写和方法重载;
解释术语类型转换并在Java中实现;
解释抽象修饰词在应用于类和方法时的用法;
解释final修饰词在类和方法中的使用,描述所有Java类派生自对象类的方式。
9.1 介绍
面向对象的软件开发方法的最大好处之一是,它为我们提供了重用已经编写的类的机会。这些类可以是我们自己编写的,也可以是别人编写的。让我们看看一个可能的场景。假想您想开发一个软件系统,并且在分析过程中确定了对一个名为Employee的类的需求。您可能已经注意到组织的某个同事已经编写了Employee类;与其编写自己的类,不如联系您的同事,让她允许您使用她的Employee类。
到目前为止一切都很好,但是如果您得到的Employee类没有达到您的期望呢?可能您的员工是兼职员工,您希望您的类具有类似hourlyPay或calculateweeklyPay和setHourlyPay这样的方法,这些属性和方法并不存在于得到的Employee类中。
您可能认为有必要进入旧的类并开始摆弄代码。但是没有必要,因为面向对象编程语言提供了通过添加属性和方法来扩展现有类的能力。这就是所谓的继承。
9.2 定义继承
继承是类之间共享属性和方法。我们取一个类,然后根据第一个类定义其他类。新类继承第一个类的所有属性和方法,但也有自己的属性和方法。让我们通过考虑Employee类来理解这一点。
Employee |
-number:String name: String |
Employee(String) setName(String) getNumber():String getName():String |
PartTimeEmployee |
-hourlyPay:double |
PartTimeEmployee( String, String,double) setHourlyPay(double) getHourlyPay():double calculateWeeklyPay(int):double |
图9.1 一个继承关系
假设我们的Employee类有两个属性,分别是number和name,一个用户定义的构造函数,以及一些基本的get和set方法。我们现在定义我们的PartTimeEmployee类,该类将继承这些属性和方法,但也可以拥有自己的属性和方法。我们将给它一个额外的属性,hourlyPay,一些访问这个属性的方法和一个额外的方法,calculateWeeklyPay,如图9.1所示,它使用UML符号来继承,也就是一个三角形。
从这个图中可以看出,继承关系是一个层次关系。位于层次结构顶部的类,本例中的Employee类,被称为超类(或基类),PartTimeEmployee被称为子类(或派生类)。
继承关系也经常被称为是一种关系,在本例中,PartTimeEmployee也是一种Employee。
9.3 用Java实现继承
Employee类的代码如下:
Employee |
public class Employee{ private string number; private string name; public Employee(string numberIn,string nameIn){ number=numberIn; name=nameIn;} public void setName(String nameIn){ name=nameIn; } public string getNumber(){ return number; } public string getName(){ return name; } } |
这里没有什么新内容,所以让我们继续我们的PartTimeEmployee类。我们将首先给出代码,然后进行分析。
PartTimeEmployee |
public class PartTimeEmployee extends Employee//这个类是Employee的子类 { private double hourlyPay;//这个属性是这个子类特有的 //结构 Public PartTimeEmployee(String numberIn,String nameIn,double hourlyPayIn){ super(numberIn,nameIn); hourlyPay=hourlyPayIn; } //这些方法也是子类中特有的 public double getHourlyPay(){ return hourly Pay;} public void setHourlyPay(double hourlyPayIn){ hourlyPay=hourlyPayIn;} public double calculateWeeklyPay(int noofHoursIn){ return noofHoursIn*hourlyPay;} } |
第一行是类头本身:
public class PartTimeEmployee extends Employee//这个类是Employee的子类
这里我们看到了关键字extends的使用。以这种方式使用这个词意味着PartTimeEmployee类(子类)继承了Employee类(超类)的所有属性和方法。因此,尽管我们还没有对它们进行编码,但是PartTimeEmployee类的任何对象都有一个名为name的属性和一个名为getNumber的方法,PartTimeEmployee现在也是一种Employee。
但您觉得这里有问题吗?这些属性已经在超类中声明为私有的,所以尽管它们现在是PartTimeEmployee类的一部分,但是没有一个PartTimeEmployee类方法可以直接访问它们——子类只有与其他类相同的访问权限。
有很多方法可以解决这个问题:
我们可以将原始属性声明为public,但是这将带走封装的全部意义。
我们可以使用特殊关键字protected来代替private,这样做的结果是,任何声明为受保护的内容都可以被任何子类的方法访问。然而,这里有两个问题需要考虑。首先,当您希望您的类能够被继承时,您必须是提前进行预测。第二个问题是,它削弱了您在类中封装信息的努力,因为在Java中,受保护的属性也可以被同一包中的任何其他类访问(您将在第一章中了解更多关于包这个词的含义)。
尽管有上述说明,但这是一种完全可以接受的使用方法,特别是在您将类作为离散应用程序的一部分编写的情况下,而且您将提前知道某些类需要子类化。您将在本节中看到这样的例子。
顺便说一句,UML图中,受保护的属性由散列符号#表示。
另一个解决方案,也是我们现在将要使用的,是将属性保留为私有的,但是要预先仔细计划我们将提供哪些get和set方法。
在类标头之后,我们有以下声明:
private double hourlyPay;
它声明了一个属性hourlyPay,这是我们的子类所特有——但是要记住,它是超类的属性。Employee将被继承,因此实际上,任何PartTimeEmployee的对象都有三个属性。
接下来是构造函数。我们希望能够在创建对象时为编号和名称赋值,就像我们对Employee对象所做那样;因此,我们的构造函数将需要接收分配给number和name属性的参数。
但是等一下!我们要怎么做呢?number和name的属性已在超类中声明为私有,因此子类的对象无法访问它们。幸运的是,有一个办法可以解决这个问题。我们可以使用关键字super来调用超类的构造函数。看如何做到这一点:
public PartTimeEmployee(String numberIn;String nameIn,double, hourlyPayIn)
super(numberIn,nameIn);//调用超类的构造函数hourlyPay=hourlyPayIn;
在调用超类的构造函数之后,我们需要执行另一个任务——即将第三个参数hourlyPayIn分配给hourlyPay属性。但是,请注意,调用super的行必须是第一行——如果我们这样编写构造函数,它将无法编译。
/*这个版本的构造函数不会编译-对super的调用方法必须是第一指令*/
public PartTimeEmployee(String numberIn,String nameIn,double hourlyPayIn)
hourlyPay=hourlyPayIn;
super(numberIn,nameIn);/这个调用应该是第一个指令!
PartTimeEmployee的其余方法是特定于子类的新方法:
double double getHourlyPay()
return hourlyPay;
public void setHourlyPay(double hourlyPayIn)
hourlyPay=hourlyPayIn;
public double calculateWeeklyPay(int noofHoursIn)
return noofHoursIn*hourlyPay;
前两个分别提供对hourlyPay属性的读和写访问。第三个是工作小时数,用它乘以小时工资来计算工资。下面的程序演示了PartTimeEmployee类的用法。
import java.util.Scanner;
public class PartTimeEmployeeTester
public static void main(string [] args)
Scanner keyboard = new scanner(System.in);
scanner keyboardstring = new Scanner(System.in);
string name,number;
double pay;
int hours;
PartTimeEmployee emp;//获取用户的详细信息;
System.out.print('Employee Number?');
number=keyboardstring.nextline();
System.out.print('Employees name?');
name=keyboardstring.nextline();
System.out.print('Hourly Pay?');
pay=keyboardstring.nextDouble();
System.out.print('Hours worked this week?');
hours=keyboardstring.nextInt();
//创建一个新的兼职雇员
emp=new PartTimeEmployee(number,name,pay);
//展示兼职雇员的详细信息,包括每周工资
System.out.println();
//接下类的两个方法继承自Employee类
System.out.println(emp.getName());
System.out.println(emp.getNumber);
System.out.println(emp.calculateWeeklyPay(hours));
}
}
这里是一个样本测试运行:
Employee Number?A103456
Employees Name?Mandy Lifeboats
Hourly
剩余内容已隐藏,支付完成后下载完整资料
资料编号:[235385],资料为PDF文档或Word文档,PDF文档可免费转换为Word
以上是毕业论文外文翻译,课题毕业论文、任务书、文献综述、开题报告、程序设计、图纸设计等资料可联系客服协助查找。