Java高级程序设计2.docx
《Java高级程序设计2.docx》由会员分享,可在线阅读,更多相关《Java高级程序设计2.docx(17页珍藏版)》请在冰豆网上搜索。
![Java高级程序设计2.docx](https://file1.bdocx.com/fileroot1/2023-1/23/874a094a-6a16-4c98-b655-cc6a7f2205cd/874a094a-6a16-4c98-b655-cc6a7f2205cd1.gif)
Java高级程序设计2
第七章多态
7.1概念
多态即程序中同名的不同方法共存的情况,以下为两种常见的多态方式:
●子类对父类方法的覆盖
●利用重载在同一个类中定义多个同名的不同方法
7.2域的继承与隐藏
●父类的所有非私有域是各子类都有的域的集合:
继承
●子类中变量对同名父类变量和属性的隐藏
●子类执行继承父类的操作时,处理父类的变量,执行自己定义的方法时,操作自己定义的变量。
程序7-1 TestHiddenField.java
程序源代码说明
publicclassTestHiddenField
{
publicstaticvoidmain(Stringargs[])
{
D200_Cardmy200=newD200_Card();
my200.balance=50.0;
System.out.println("Fatherbalance:
"+my200.getBalance());
//子类D200_Card中没有getBalance()方
//法,故继承父类PhoneCard的方法,所
//以使用PhoneCard的balance域
if(my200.performDial())
System.out.println("Sonbalance:
"+my200.balance);
//子类D200_Card中有balance域,所以
//使用自己的balance域
}
}
abstractclassPhoneCard
{
doublebalance;
abstractbooleanperformDial();
doublegetBalance()
{
returnbalance;
}
}
abstractclassNumber_PhoneCardextendsPhoneCard //抽象子类Number_PhoneCard
{
longcardNumber;
intpassword;
StringconnectNumber;
booleanconnected;
booleanperformConnection(longcn,intpw)
{
if(cn==cardNumber&&pw==password)
{
connected=true;
returntrue;
}
else
{
connected=false;
returnfalse;
}
}
}
classD200_CardextendsNumber_PhoneCard //具体子类D200_Card
{
doubleadditoryFee;
doublebalance;
booleanperformDial()
{
if(balance>(0.5+additoryFee))
{
balance-=0.5+additoryFee;
returntrue;
}
else
returnfalse;
}
}
7.3方法的继承与覆盖
子类可以实现对父类同名方法的覆盖。
●方法的覆盖与域的隐藏的区别在于:
子类隐藏父类的域只是使之不可见,父类的同名域在子类对象中仍占有内存空间,而子类方法对父类方法的覆盖将清除父类方法占用的内存空间。
●子类对父类方法的覆盖应保持与父类完全相同的方法头声明,即方法名,返回值,参数列表都相同。
程序7-2 TestOverLoad.java
程序源代码说明
publicclassTestOverLoad
{
publicstaticvoidmain(Stringargs[])
{
D200_Cardmy200=newD200_Card();
my200.balance=50.0;
System.out.println("Fatherbalance:
"+my200.getBalance());
//因为子类D200_Card已定义了方法
//getBalance(),所以覆盖父类
//PhoneCard定义的方法getBalance()
if(my200.performDial())
System.out.println("Sonbalance:
"+my200.balance);
}
}
abstractclassPhoneCard
{
doublebalance;
abstractbooleanperformDial();
doublegetBalance() //父类PhoneCard定义的方法getBalance()
{
returnbalance;
}
}
abstractclassNumber_PhoneCardextendsPhoneCard
{
longcardNumber;
intpassword;
StringconnectNumber;
booleanconnected;
booleanperformConnection(longcn,intpw)
{
if(cn==cardNumber&&pw==password)
{
connected=true;
returntrue;
}
else
{
connected=false;
returnfalse;
}
}
}
classD200_CardextendsNumber_PhoneCard
{
doubleadditoryFee;
doublebalance;
booleanperformDial()
{
if(balance>(0.5+additoryFee))
{
balance-=0.5+additoryFee;
returntrue;
}
else
returnfalse;
}
doublegetBalance()
//子类D200_Card定义的方法getBalance()
{
returnbalance;
}
}
7.4this与super
●Java系统默认,每个类都缺省地具有null,this,super三个域,可以直接使用。
null代表空,在定义一个对象但尚未为其开辟内存单元时可以指定这个对象为null
Node*pnode;
pnode=NULL;
if(pnode==NULL)newmalloc(….)
deletepnode;
pnode=NULL;
this代表当前对象的一个引用,但它不是地址,与指针无关,仅仅是对象的另一个名字
super表示当前对象的直接父类对象
●父类对象与子类对象的转换要注意以下原则:
子类对象可以被视为是其父类的一个对象
父类对象不能被当作是其某一个子类的对象
如果一个方法的形式参数定义的是父类对象,那么调用这个方法时,可以使用子类对象作为实际参数
如果父类对象引用指向的实际是一个子类对象,那么这个父类对象的引用可以用强制类型转换转化为子类对象的引用
程序7-3 HiddenField.java
程序源代码说明
publicclassHiddenField
{
publicstaticvoidmain(Stringargs[])
{
D200_Cardmy200=newD200_Card();
my200.balance=50.0;
System.out.println("Fatherbalance:
"+my200.getBalance());
//用直接父类Number_PhoneCard的balance
//域,它没有,则用再上一层PhoneCard的balance
if(my200.performDial())
System.out.println("Sonbalance:
"+my200.balance);
}
}
abstractclassPhoneCard
{
doublebalance;
abstractbooleanperformDial();
doublegetBalance()
{
returnbalance;
}
}
abstractclassNumber_PhoneCardextendsPhoneCard
{
longcardNumber;
intpassword;
StringconnectNumber;
booleanconnected;
booleanperformConnection(longcn,intpw)
{
if(cn==cardNumber&&pw==password)
{
connected=true;
returntrue;
}
else
{
returnfalse;
}
}
}
classD200_CardextendsNumber_PhoneCard
{
doubleadditoryFee;
doublebalance;
booleanperformDial()
{
if(balance>(0.5+additoryFee))
{
balance-=0.5+additoryFee;
returntrue;
}
else
returnfalse;
}
doublegetBalance()
{
returnsuper.balance;
//表示使用它直接父类的balance域
}
}
7.5继承与finalize()
publicclassFrogextendsAmphibian{
//Constructtheapplication
Frog(){
System.out.println("Frog()");
}
protectedvoidfinalize()throwsThrowable{
System.out.println("Frogfinalize");
if(DoBaseFinalization.flag)
super.finalize();
}
//Mainmethod
publicstaticvoidmain(String[]args){
if(args.length!
=0&&args[0].equals("finalize"))
DoBaseFinalization.flag=true;
else
System.out.println("Notfinalizingbases");
newFrog();
System.out.println("Bye");
System.gc();
}
}
classDoBaseFinalization{
publicstaticbooleanflag=false;
}
classAmphibianextendsAnimal{
Characteristicp=newCharacteristic("canliveinwater");
Amphibian(){
System.out.println("Amphibian()");
}
protectedvoidfinalize()throwsThrowable{
System.out.println("Amphibianfinalize");
if(DoBaseFinalization.flag)
super.finalize();
}
}
classCharacteristic{
Strings;
Characteristic(Stringc){
s=c;
System.out.println("CreatingCharacteristic"+s);
}
protectedvoidfinalize(){
System.out.println("finalizingCharacteristic"+s);
}
}
classAnimalextendsLivingCreature{
Characteristicp=newCharacteristic("hasheart");
Animal(){
System.out.println("Animal()");
}
protectedvoidfinalize()throwsThrowable{
System.out.println("Animalfinalize");
if(DoBaseFinalization.flag)
super.finalize();
}
}
classLivingCreature{
Characteristicp=newCharacteristic("isalive");
LivingCreature(){
System.out.println("LivingCreature()");
}
protectedvoidfinalize()throwsThrowable{
System.out.println("LivingCreaturefinalize");
if(DoBaseFinalization.flag)
super.finalize();
}
}
输出:
P236
1Notfinalizingbases2CreatingCharacteristicisalive3LivingCreature()4CreatingCharacteristichasheart5Animal()6CreatingCharacteristiccanliveinwater7Amphibian()8Frog()9Bye10Frogfinalize11finalizingCharacteristicisalive12finalizingCharacteristichasheart13finalizingCharacteristiccanliveinwater
◆每个class含有一个characteristic成员,它会被终止
◆object的finalize()是个protected,不允许被降低访问权限
◆如果不人工调用super.finalize(),则父亲的finalize不会被启动
7.6构造函数的继承与重载
●构造函数可以从父类那里继承,也可以互相重载。
●类的若干个构造函数可以相互调用,一个构造函数调用另一构造函数时,可以使用关键字this,同时这个调用语句应该是整个构造函数的第一个可执行语句。
●子类继承父类的构造函数遵循以下原则
(1)子类无条件地继承父类的不含参数的构造函数
(2)如果子类没有构造函数,则根据上一条,继承父类无参数的构造函数
(3)如果子类有构造函数,则先继承父类无参数的构造函数,再执行自己的构造函数
(4)子类可以继承父类的有参数的构造函数,必须用super关键字显式使用,而且该语句必须是子类构造函数的第一个可执行语句。
publicclassPolyConstructors{
//Mainmethod
publicstaticvoidmain(String[]args){
newRoundGlyph(5);
}
}
classRoundGlyphextendsGlyph{
intradius=1;
RoundGlyph(intr){
radius=r;
System.out.println("RoundGlyph.RoundGlyph(),radius="+radius);
}
voiddraw(){
System.out.println("RoundGlyph.draw(),radius="+radius);
}
}
abstractclassGlyph{
abstractvoiddraw();
Glyph(){
System.out.println("Glyph()beforedraw()");
draw();
System.out.println("Glyph()afterdraw()");
}
}
输出:
P239
1Glyph()beforedraw()2RoundGlyph.draw(),radius=0
//调用RoundGlyph的draw是从Glyph过来的,因此此时的radius还未赋值3Glyph()afterdraw()4RoundGlyph.RoundGlyph(),radius=5
第八章接口
8.1接口
8.1.1接口概述
●接口是用来实现类间多重继承的功能的
●接口的定义:
将完成特定功能的若干属性组织成相对独立的属性集合,该属性集合就是接口
●ActionListener接口的功能 actionPerformed()方法
●接口定义的仅仅是实现某一特定功能的一组功能的对外接口和规范,而并没有真正实现这个功能,真正实现在继承这个接口的各个类中完成,因而通常把接口功能的继承称为“实现”。
8.1.2声明接口
[public]interface接口名 [extends父接口名列表]
{
}
●接口是由常量和抽象方法组成
●类只能有一个父类,但可实现多个接口(中间用“,”分隔)
●public接口是公共接口,没有public的接口只能被同一包中的其他类和接口使用
●接口中的属性都是publicstaticfinal的,方法都是publicabstract的,方法还可用其他语言写,这时是native修饰的。
8.1.3实现接口
一个类要实现接口时,要注意:
●在类的声明部分,用implements关键字声明该类将要实现哪些接口
●如果实现某接口的类不是abstract的抽象类,则在类的定义部分必须实现指定接口的所有抽象方法
●如果实现某接口的类是abstract的抽象类,则它可以不实现该接口所有的方法。
但是对于这个抽象类任何一个非抽象的子类面言,它们父类所实现的接口中的所有抽象方法都必须有实在的方法体。
●一个类在实现某接口的抽象方法时,必须使用完全相同的方法头,如果所实现的方法与抽象方法有相同的方法名和不同的参数列表,则只是在重载一个新的方法,而不是实现已有的抽象方法。
●接口的抽象方法的访问限制符都已指定为public,所以类在实现方法时,必须显式地使用public修饰符,否则将被系统警告为缩小了接口中定义的方法的访问控制范围。
程序8-5 ImplementActionListener.java
程序源代码说明
importjava.applet.*;
importjava.awt.*;
importjava.awt.event.*;
publicclassImplementActionListenerextendsAppletimplementsActionListener
{
//该类要实现接口ActionListener
TextFieldpassword=newTextField("Password");
Buttonbtn=newButton("Hidden");
publicvoidinit()
{
add(password);
add(btn);
btn.addActionListener(this);
}
publicvoidactionPerformed(ActionEvente)
{
password.setEchoChar('*');
password.selectAll();
}
}
8.2嵌套interface
classA{
interfaceB{
voidf();
}
publicclassBImpimplementsB{
publicvoidf(){}
}
privateclassBImp2implementsB{
publicvoidf(){}
}
publicinterfaceC{
voidf();
}
classCImpimplementsC{
publicvoidf(){}
}
privateclassCImp2implementsC{
publicvoidf(){}
}
privateinterfaceD{
voidf();
}
privateclassDImpimplementsD{
publicvoidf(){}
}
publicclassDImp2implementsD{
publicvoidf(){}
}
publicDgetD(){returnnewDImp2();}
privateDdRef;
publicvoidreceiveD(Dd){
dRef=d;
dRef.f();
}
}
interfaceE{
interfaceG{
voidf();
}
publicinterfaceH{//redundant"public"
voidf();
}
voidg();
//cannotbeprivatewithinaninterface;
//!
privateinterfaceI{}
//接口内的所有元素都是public,这里不能是private
}
publicclassNestingInterfaces{
publicclassBImpimplementsA.B{
publicvoidf(){}
}
classCImpimplementsA.C{
publicvoidf(){}
}
//ca