第5章 继承.docx
- 文档编号:3329047
- 上传时间:2022-11-21
- 格式:DOCX
- 页数:13
- 大小:26.96KB
第5章 继承.docx
《第5章 继承.docx》由会员分享,可在线阅读,更多相关《第5章 继承.docx(13页珍藏版)》请在冰豆网上搜索。
第5章继承
第5章继承
教学重点与难点
Ø理解继承与复用的概念
Ø理解父类和子类
Ø掌握扩展类编程
Ø理解多态性与动态绑定
Ø掌握如何建立包和接口
5.1继承的概念
继承的思想就是允许在已经存在类的基础上构建新的类。
当继承一个已经存在的类时,就复用(继承)了那个类的方法和字段,同时可以在新类中增添新的方法和字段以适应环境。
继承性是软件复用的一种形式。
新类由已存在的类生成,通过保留它们的属性和行为,并且根据新的要求对性能加以修改,添加新的属性和行为。
继承就是能够直接获得已有的性质和特征,而不必重复定义它们。
例如:
一位面向对象的程序员A,在编程过程中需
要描述和处理个人信息,于是他定义了类Person,
其结构如下:
publicclassPerson{
publicStringname;
publicintage;
publicDatebirthDate;
publicStringgetInfo(){………}
}
之后,A又遇到了新的需求-----需要描述和处理学生
信息,于是他又定义了一个新的类Student:
publicclassStudent
{
publicStringname;
publicintage;
publicDatebirthDate;
publicStringschool;
publicStringgetInfo(){…}
}
从上面两个类的定义可以看出,类Student与类
Person结构太接近了,只是相差了一个school属
性,其它所有的内容被重复定义。
如果采用继承机
制,则对于类Student的定义就简单多了。
如下:
publicclassStudentextendsPerson
{
publicStringschool;
}
Student类同样包含Person类中的所有属性和方
法。
在上面的结构中,关键字“extends”标明了要
继承的是那个类。
新类除了继承原有类的属性和方
法外,还可以根据需要添加更多的属性和方法。
新
定义的类称为子类,被继承的已经存在的类称为父
类、超类或基类。
在面向对象系统中,提取公共属性和行为并将其
放在一个父类中,接着用继承性构建子类,这样可
以避免重复定义公共属性和行为。
子类继承了父类
的功能,并根据需要添加功能。
每个子类也可以成
为将来某个子类的父类。
子类从父类继承有两个方
面:
属性的继承、方法的继承。
例如:
Test.java
如果子类只从一个父类继承,则称为单继承;如
果子类从一个以上的父类继承,则称为多继承(多
重继承)。
Java只支持单继承。
继承关系可以传递。
如下图:
A
BCD
EF
上图中的E继承C,而C继承A,因而E也继承了
A,所以E也是A的子类,是间接的子类,C则是A
的直接子类。
子类直接继承的那个类-----直接父类,通过关键
字extends来实现;两级或两级以上的父类-----
间接父类。
5.2扩展类
从一个已存在的类继承或衍生下来的类-------
扩展类。
子类是父类的扩展,除继承父类的属性和方法
外,子类还可以增加父类没有的属性和方法。
子
类比父类具有更多的功能。
1、属性继承与隐藏
例如:
定义经理类,它继承了员工类。
classMangerextendsEmployee
{
publicvoidsetBons(doubleb)
{
bonus=b;
}
privatedoublebonus;
}
说明:
(1)虽然被继承的父类成员变量没有在子类
声明中列出,但是父类的这些成员变量确实存在
于子类中----属性的继承。
每个Manger对象都有
4个字段:
name、salary、hireDay、bonus。
(2)子类不能访问父类的private成员(属性
和方法),但子类可以访问其父类的public、默
认和Protected成。
例如Test.java。
(3)在子类中定义与父类中相同的属性------
属性的隐藏。
2、方法继承、覆盖与重载
方法继承:
即使在子类中没有声明,对于Manger
对象,可以使用员工类中的getName、getHireDay
等方法。
但对于一个Employee对象,不能使用子类
中的setBonus等方法。
方法覆盖:
子类中定义与父类中同名的方法。
多
用于改写或补充完善父类中的方法。
如:
Manger类中的getSalary方法。
它返回基本
薪金和奖金的总和。
如何实现呢?
写为如下形式:
publicdoublegetSalary()
{
returnsalary+bonus;
}
不能实现。
这是因为Manger类中的getSalary方
法不能直接访问其父类中的私有字段。
只有员工
类中的方法才能访问这些私有字段。
改写程序为:
publicdoublegetSalary()
{
doublebaseSalary=getSalary();
returnbaseSalary+bonus;
}
问题在于:
调用getSalary方法只不过是简单地调
用自己,即递归调用。
需要调用父类的getSalary
方法,而不是当前类的。
解决办法是使用super关键字。
函数调用
super.getSalary()意味着调用Employee类中
的getSalary()方法。
正确实现如下:
publicdoublegetSalary()
{
doublebaseSalary=super.getSalary();
returnbaseSalary+bonus;
}
注意事项:
(1)不使用super而希望引用父类方法会导致无限
的递归;
(2)对于父类提供的方法,子类可以覆盖它,但这
不是必须的,即子类也可以使用父类的方法;
(3)方法覆盖时,应保持与父类完全相同的方法头
声明,即与父类完全相同的方法名、返回值类型和
参数列表;
(4)子类可以添加属性,也可以添加方法或者覆盖
父类中的方法。
但是不能去除父类中的方法和属性。
方法重载:
用相同的方法名但不同的参数表来定义
方法就称为方法重载。
重载的方法可以有不同的返
回值类型,但必须有不同的参数表。
当调用一个重
载的方法时,编译器通过检查调用语句中的参数来
选择恰当的方法。
如:
String类有4个indexof方法
indexof(inta)
indexof(inta,intb)
indexof(StringA)
indexof(StringA,intB)
3、在子类中使用构造函数
(1)子类构造函数总是先调用(显式地或隐式地)
其父类的构造函数,以创建和初始化子类的父类成
员。
显式指采用super调用,必须是子类构造函数
中的第一条语句。
(2)构造函数不能继承,它们只属于定义它们
的类。
(3)当创建一个子类的对象时,子类构造函数
首先调用父类的构造函数并执行,接着才执行子类
构造函数。
4、父类对象与子类对象的关系
调用过程:
e.getSalary()
尽管e的声明类型是Employee,但是e所指向
实际类型即可以是Employee,也可是Manger。
一个对象变量可以指向多种实际类型(多态)。
当e指向一个Employee对象时,e.getSalary()
会调用Employee类中的getSalary()方法;而当
e指向一个Manger对象时,getSalary()方法就变
成了Manger类中的getSalary()方法。
例如:
ManagerTest.java
说明:
(1)子类对象可以被视为其父类的一个对象,如一
个Manager对象也是一个Employee对象。
(2)父类对象不能被当做其某一个子类的对象。
(3)如果一个方法的形式参数定义的是父类对象,当调用这个方法时,可以使用子类对象作为实际参数。
(4)如果父类对象引用指向的实际是一个子类对象,那么这个父类对象的引用可用强制类型转换成子类对象的引用。
Personp=newPerson(“Liming”,50)
Students=newStudent(“Wangqiang”,20,“PKU”);
Personp2=newStudent(“Zhangyi”,18,“THU”);
Students2=(Student)p2
5.3多态与动态绑定
一、多态
任何场合子类对象都可以替代父类对象的使用---
多态。
在JAVA中,对象变量是多态的。
一个Employee
类型可以是任何子类(如Manager等)的对象类型。
每1个经理是1个员工,但并不是每个员工都是经理。
例如:
上例中staff[0]是一个Employe类对象,但调
用了子类Manager对象的setBouns方法,薪金和奖
金加在了一起。
二、动态绑定
在运行时自动选择正确的方法进行调用称为动态
绑定。
也称虚方法调用。
调用一个对象方法的过程:
1、编译器检查对象的声明类型和方法名。
2、编译器检查方法调用中的参数类型。
三、关键字this、super
this和super是常用来指代父类对象与子类对象的
关键字,Java系统默认,每个类都缺省地具有null
this、super三个量,所以在任意类中都可以不加说
明而直接引用它们。
1、this
this表示的是当前对象。
用法如下:
(1)使用this来访问域及方法
在方法及构造方法中,可以使用this来访问对象的域和方法,包括父类中的域和方法。
如:
System.out.println(“HHHH”+name);
System.out.println(“HHHH”+this.name);
(2)使用this解决局部变量与域同名的问题
如:
Person(intage,Stringname){
this.age=age;
this.name=name;
}
(3)构造方法中,用this调用另一构造方法
如:
Person(){
this(0,“”);
}
2、super:
多指父类。
多用于子类对象调用父类中重写前的方法。
(1)super可用于访问父类中定义的属性。
(2)super可用于调用父类中定义的方法。
(3)super可用于在子类构造方法中调用父类的
构造方法。
(4)super的追溯不仅限于直接父类。
语法格式:
super.属性名
super.方法名(参数表)
例如:
Test1.java
四、动态类型的确定
多态性导致了引用变量的声明类型和其实际引用
对象的类型可能不一致,为准确地鉴别一个对象的
真正类型,Java提供了一个运算符instanceof,它
的语法格式为:
<引用类型变量>instanceof<引用类型>
注意:
如果变量与类型相同,或者是类型的子类型,
则结果就是true,反之为false。
例如:
InstanceOf.javaTestInstanceOf.java
5.4包
一、包的用途
为了方便管理和使用,通常把需要在一起工作的
类放在一起,形成一个包,因此包是类的集合。
标准的Java类库由许多包组成,其中包括lang、
Util、io、net等。
标准类库是分层次的。
就象硬盘
上的文件管理一样。
所有的Java包都包含在Java、
Javax层下。
使用包的主要原因是保证类名的唯一性。
假设两
个程序员都提供了一个Employee类,只要把它们
放在不同的包中,就不会有冲突。
使用包可以使用
包中的所有类,也可以使用来自其它包中的公共类。
二、创建包
创建包的过程:
(1)定义一个public类。
如果类不是公共的,
它只能被同一包中的其它类使用。
(2)选择一个包名,并把package语句加到
源文件中。
如:
packagemyclass;
(3)编译源文件。
它就被放到当前目录下,
以供其它程序使用。
例如:
创建myclass包
三、引用包
1、在每个类名前加上完整的包名
使用import语句,可以引入一个特定的类,也可
以引入整个包。
如:
importjava.util.*;
importjava.util.Date;
importjava.awt.event;
2、向包中添加类
使用package语句。
如:
packagecom.home.user
3、定位类
类被存储在文件系统的子目录中。
应该把类放在
一个或多个特定的目录中,如:
/home/user/classdir
设置类路径:
CLASSPATH环境变量。
四、JavaAPI包
如:
java.lang、util、io、awt、net、applet、
sql、rmi、security等。
javax.swing
5.5接口
一、接口的概念
接口是用来实现类间多重继承功能的结构。
在语
法上有些相似于类,它定义了若干个抽象方法和常
量,形成一个属性集合,该属性集合通常对应于某
一组功能,其主要作用是可以帮助实现类似于类的
多重继承的功能。
凡是需要实现这种特定功能的类,
都可以继承这个属性集合并在类内使用它,这个属
性集合就是接口。
需要特别说明的是,Java中一个类获取某一接口
定义的功能,并不是通过直接继承这个接口中的属
性和方法来实现的。
接口中的属性都是常量,接口
中的方法都是没有方法体的抽象方法。
也就是说,
接口定义的仅仅是实现某一特定功能的一组对外接
口和规范,而并没有真正地实现这个功能,这个功
能的真正实现是在“继承”这个接口的各个类中完成
的,要由这些类来具体定义接口中的各抽象方法的
方法体。
因而在Java中,通常把对接口功能的“继
承”称为“实现(implements)”。
接口把方法的定义和对它的实现区分开。
同时,
一个类可以实现多个接口来达到“多重继承”的目的。
二、接口声明
Java中声明接口的语法如下:
[public]interface接口名[extends父接口名列表]
{//接口体
//常量域声明
[public][static][final]域类型域名=常量值;
//抽象方法声明
[public][abstract]返回值方法名(参数列表)
}
从上面的接口定义可以知道:
接口是由常量和抽象
方法组成的特殊类。
例:
给出一个接口定义。
interfaceCollection
{
publicstaticfinalintMAXNUM=100;
publicabstractvoidadd(Objectobj);
voiddelete(Objectobj);
voidfind(Objectobj);
intcurrentCount();
}
三、接口实现
接口实现是指具体地实现接口所规定的功能,则
需某个类为接口中的抽象方法书写语句并定义实在
的方法体。
一个类要实现某个或某几个接口时,请注意以下
几个问题:
(1)在类的声明部分,用implements关键字声
明该类将要实现哪些接口。
如:
classPointextendsObjectimplementsShape
{………}
(2)如果实现某接口的类不是abstract的抽象类,
则在类的定义部分必须实现指定接口的所有抽象方
法,即为所有抽象方法定义方法体,而且方法头部
分应该与接口中的定义完全一致,即有完全相同的
返回值和参数列表。
(3)如果实现某接口的类是abstract抽象类,则
它可以不实现该接口所有的方法。
但是对于这个抽
象类的任何一个非抽象子类,它们父类所实现接口
中的所有抽象方法都必须有实在的方法体。
(4)接口的抽象方法,其访问控制符都已指定为
public,所以类在实现方法时,必须显式地使用
Public控制符,否则将被系统警告:
缩小了接口定
义的方法的访问控制范围。
例:
使用接口
例:
定义和使用接口(例5-5)
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 第5章 继承
![提示](https://static.bdocx.com/images/bang_tan.gif)