java第五章 继承、多态、重载与接口

上传人:e****s 文档编号:243684823 上传时间:2024-09-28 格式:PPT 页数:167 大小:795.50KB
返回 下载 相关 举报
java第五章 继承、多态、重载与接口_第1页
第1页 / 共167页
java第五章 继承、多态、重载与接口_第2页
第2页 / 共167页
java第五章 继承、多态、重载与接口_第3页
第3页 / 共167页
点击查看更多>>
资源描述
,*,单击此处编辑母版标题样式,单击此处编辑母版文本样式,第二级,第三级,第四级,第五级,单击此处编辑母版标题样式,单击此处编辑母版文本样式,第二级,第三级,第四级,第五级,*,第五章 继承、多态、重载与接口,2,主要内容,Java,的继承,Java,的多态,Java,的覆盖,Java,的重载,构造方法的重载与继承,内部类与匿名类,接口,3,继承的概念,继承是存在于面向对象程序中的两个类之间的一种关系,当一个类获取另一个类中所有非私有数据和操作的定义作为自己的局部或全部成分时,就称这两个类之间具有继承关系,被继承的类称为父类或超类,继承了父类或超类的所有数据和操作的类称为子类,一个父类可以同时拥有多个子类,父类实际上是所有子类的公共域和公共方法的集合,每一个子类那么是父类的特殊化,是对公共域和方法在功能、内涵方面的扩展和延伸,Java,的继承,4,继承的概念,各种 卡类及其间的继承关系,Java,的继承,5,单重继承与多重继承,单重继承指任何一个类都只有一个单一的父类,多重继承是指一个类可以有一个以上的父类,它的数据属性和操作从所有这些父类中继承,单重继承的程序结构比较简单,支持多重继承的程序,其结构那么是复杂的网状,设计、实现都比较复杂,C+是开发人员熟悉的支持多重继承的面向对象的编程语言,Java语言出于平安、可靠性的考虑,仅支持单重继承,Java,的继承,6,Java,的派生子类,Java中的继承是通过extends关键字来实现的,在定义类时使用extends关键字指明新定义类的父类,就在两个类之间建立了继承关系,定义形式,class SubClass extends SuperClass, ,如果没有extends子句,那么该类默认为的子类,所以,Java中,所有的类都是通过直接或间接地继承得到的,新定义的类称为子类,它可以从父类那里继承所有非private的属性和方法作为自己的成员,Java,的继承,7,Java,的派生子类,继承关系在,UML,图中,是用一个箭头来表示子类与父类的关系的,类,Student,从类,Person,继承,定义如下,class Student extends Person ,/,Java,的继承,8,派生子类实现 卡类的继承结构,1,:,abstract class PhoneCard,2,:,3,:,double balance;,4,:,5,:,abstract boolean performDial( );,6,:,double getBalance( ),7,:, return balance; ,10,:,11,:,abstract class None-Number-PhoneCard,extends,PhoneCard,12,:,13,:,String phoneSetType;,14,:,15,:,String getSetType( ),16,:,17,:,return phoneSetType;,18,:,19,:,Java,的继承,9,派生子类实现 卡类的继承结构,20,:,abstract class Number-PhoneCard,extends,PhoneCard,21,:,22,:,long cardNumber;,23,:,int password;,24,:,String connectNumber;,25,:,boolean connected;,26,:,27,:,boolean performConnection(long cn,int pw),28,:,29,:,if(cn = cardNumber & pw = password),30,:,31,:,connected = true;,32,:,return true;,33,:,34,:,else,35,:,return false;,36,:,37,:,Java,的继承,10,派生子类实现 卡类的继承结构,38,:,class magCard extends None-Number-PhoneCard,39,:,40,:,String usefulArea;,41,:,42,:,boolean performDial( ),43,:,44,:,if( balance 0.9),45,:,46,:,balance -= 0.9;,47,:,return true;,48,:,49,:,else,50,:,return false;,51,:,52,:,Java,的继承,11,派生子类实现 卡类的继承结构,53,:,class IC-Card extends None-Number-PhoneCard,54,:,55,:,boolean performDial( ),56,:,57,:,if( balance 0.5),58,:,59,:,balance -= 0.9;,60,:,return true;,61,:,62,:,else,63,:,return false;,64,:,65,:,Java,的继承,12,派生子类实现 卡类的继承结构,66,:,class IP-Card extends Number-PhoneCard,67,:,68,:,Date expireDate;,69,:,boolean performDial( ),70,:,71,:,if( balance 0.3 & expireDate.after(new Date( ),72,:,73,:,balance -= 0.3;,74,:,return true;,75,:,76,:,else,77,:,return false;,78,:,79,:,Java,的继承,13,派生子类实现 卡类的继承结构,80,:,class D200-Card extends Number-PhoneCard,81,:,82,:,double additoryFee;,83,:,84,:,boolean performDial( ),85,:,86,:,if( balance (0.5 + additoryFee ),87,:,88,:,balance -= (0.5 + additoryFee);,89,:,return true;,90,:,91,:,else,92,:,return false;,93,:,94,:,Java,的继承,14,派生子类实现 卡类的继承结构说明,代码定义了七个类,None-Number-PhoneCard,类和,Number-PhoneCard,类是,PhoneCard,类派生出的子类,magCard,类和,IC-Card,类是,None-Number-PhoneCard,类派生出的子类,IP-Card,类和,D200-Card,类是,Number-PhoneCard,类派生出的子类,程序中只有在第,3,句,(PhoneCard,类中,),定义了,域,balance,但在第,44,,,46(magCard,类中,),,第,57,,,59(IC-Card,类中,),,第,71,,,73(IP-Card,类中,),,第,86,,,88(D200-Card,类中,),句中都使用了,balance,域,它们自身并未定义,balance,域,使用的,balance,都是从父类,PhoneCard,那里继承来的,Java,的继承,15,派生子类实现 卡类的继承结构说明,PhoneCard类在第5句定义了一个抽象方法performDial( ),它的两个子类也是抽象类,可以不实现这个抽象方法,分别派生出来的4个 卡类不是抽象类,故而分别定义了针对自己具体情况的performDial( )方法,第68句使用一个java.util包中的Java系统类Date,每个Date类的对象代表一个具体的日期,第71句中new Date( )表达式的作用是创立一个包含当前日期的Date类的对象,after( )方法是Date类的方法,在失效日期比当前日期晚时,expireDate.after(new Date( )返回true,否那么返回false,Java,的继承,16,域的继承,子类可以继承父类的所有非私有域,例如各类 卡类所包含的域分别为,PhoneCard类:double balance;,None-Number-PhoneCard类:,double balance; /继承自父类PhoneCard,String phoneSetType;,Number-PhoneCard类:,double balance; /继承自父类PhoneCard,long cardNumber;,int password;,String connectNumber;,boolean connect;,magCard类:,double balance; /继承自父类None-Number-PhoneCard,String phoneSetType; /继承自父类None-Number-PhoneCard,String usefulArea;,Java,的继承,17,域的隐藏,子类重新定义一个与从父类那里继承来的域变量完全相同的变量,称为,域的隐藏,80,:,class D200-Card extends Number-PhoneCard,81,:,82,:,double additoryFee;,83,:,double balance;,84,:,boolean performDial( ),85,:,86,:,if( balance (0.5 + additoryFee ),87,:,88,:,balance -= (0.5 + additoryFee);,89,:,return true;,90,:,91,:,else,92,:,return false;,93,:,94,:,Java,的继承,18,域的隐藏,第,83,句增加定义了一个与从父类那里继承来的,balance,变量完全相同的变量后,,D200-Card,类中的域变为,D200-Card,类,double balance; /,继承自父类,Number-PhoneCard,double balance; /D200-Card,类自己定义的域,long cardNumber; /,继承自父类,Number-PhoneCard,int password; /,继承自父类,Number-PhoneCard,String connectNumber; /,继承自父类,Number-PhoneCard,boolean connect; /,继承自父类,Number-PhoneCard,double additoryFee;,Java,的继承,域的隐藏,子类中定义了与父类同名的属性变量,即出现了子类变量对同名父类变量的隐藏,所谓隐藏是指子类拥有了两个相同名字的变量,一个继承自父类,另一个由自己定义,当子类执行继承自父类的操作时,处理的是继承自父类的变量,而当子类执行它自己定义的方法时,所操作的就是它自己定义的变量,而把继承自父类的变量“隐藏起来,20,域的隐藏举例,TestHiddenField.java,1,:,public class TestHiddenField,2,:,3,:,public static void main(String args),4,:,5,:,D200-Card my200 = new D200-Card( );,6,:,my200.,balance,= 50.0;,7,:,System.out.println(,父类被隐藏的金额为:,+my200.,getBalance( ),);,8,:,if(my200.performDial( ),9,:,System.out.println(,子类的剩余金额为:,+my200.,balance,);,10,:,11,:,12,:,abstract class PhoneCard,13,:,14,:,double balance;,Java,的继承,21,域的隐藏举例,TestHiddenField.java,15,:,16,:,abstract boolean performDial( );,17,:,double getBalance( ),18,:,19,:,return balance;,20,:,21,:,22,:,abstract class Number-PhoneCard extends PhoneCard,23,:,24,:,long cardNumber;,25,:,int password;,26,:,String connectNumber;,27,:,boolean connected;,28,:,Java,的继承,22,域的隐藏举例,TestHiddenField.java,29,:,boolean performConnection(long cn,int pw),30,:,31,:,if(cn = cardNumber & pw = password),32,:,33,:,connected = true;,34,:,return true;,35,:,36,:,else,37,:,return false;,38,:,39,:,40,:,class D200-Card extends Number-PhoneCard,41,:,42,:,double additoryFee;,43,:,double balance;,Java,的继承,23,域的隐藏举例,TestHiddenField.java,44,:,45,:,boolean performDial( ),46,:,47,:,if(,balance, (0.5 + additoryFee ),48,:,49,:,balance,-= (0.5 + additoryFee);,50,:,return true;,51,:,52,:,else,53,:,return false;,54,:,55,:,Java,的继承,24,域的隐藏举例,TestHiddenField.java,显示结果,Java,的继承,25,域的隐藏举例,TestHiddenField.java代码说明,第5句创立了一个D200-Card类的对象my200,这个对象有两个balance变量,一个继承自父类PhoneCard,另一个是在第43句中重新定义的自身的balance变量,第6句为my200对象的balance变量赋值,根据域隐藏的原那么,这里是为my200自身的balance变量赋值,第7句输出my200对象的getBalance( )方法的返回值,这里的getBalance( )方法是在父类PhoneCard中定义的,它返回的是my200对象继承自父类PhoneCard的balance变量的数值,这个balance没有被赋值,其数值是缺省的0.0,第8句调用my200对象的performDial( )方法拨打 ,修改my200对象自身的balance变量。第9句输出拨打 之后,my200对象的balance变量的数值,Java,的继承,26,方法的继承,父类的非私有方法可以被子类所继承,各种 卡所包含方法如下,PhoneCard类:,abstract boolean performDial( );,double getBalance( ),None-Number-PhoneCard类:,abstract boolean performDial( );/继承自父类PhoneCard,double getBalance( ) /继承自父类PhoneCard,String getSetType( ),Number-PhoneCard类:,abstract boolean performDial( ); /继承自父类PhoneCard,double getBalance( ) /继承自父类PhoneCard,boolean performConnection(long cn,int pw),magCard类:,double getBalance( ) /继承自父类None-Number-PhoneCard,String getSetType( ) /继承自父类None-Number-PhoneCard,boolean performDial( ),Java,的继承,27,方法的继承,根据方法的继承关系,各种 卡所包含方法如下,IC-Card类:,double getBalance( ) /继承自父类None-Number-PhoneCard,String getSetType( ) /继承自父类None-Number-PhoneCard,boolean performDial( ),IP-Card类:,boolean performDial( ),double getBalance( ) /继承自父类Number-PhoneCard,boolean performConnection(long cn,int pw),D200-Card类:,boolean performDial( ),double getBalance( ) /继承自父类Number-PhoneCard,boolean performConnection(long cn,int pw),Java,的继承,28,this,与,super,this和super是常用来指代子类对象和父类对象的关键字,Java系统默认,每个类都缺省地具有null,this和super三个域,所以在任意类中都可以不加说明而直接使用它们,其中null代表“空, 代表一个什么也没有的“空值,在定义一个对象但尚未为其开辟内存单元时可以指定这个对象为null,this和super两个域那么与继承有密切关系,Java,的继承,29,this,在方法及构造方法中,使用,this,来访问域及方法,this,表示,当前对象,的一个引用,对象的引用可以理解为对象的另一个名字,利用,this,可以调用当前对象的方法或使用当前对象的域,如,double getBalance( ),return this.balance;,表示返回的是当前同一个对象的,balance,域,当然在这种情况下,this,也可以不加,更多的情况下,,this,用来把当前对象的引用作为参数传递给其他的对象或方法,Java,的继承,30,this,使用this还可以解决局部变量方法中的变量或参数变量与域变量同名的问题。如,在构造方法中,经常这样用:,Person( int age, String name ),this.age = age;,this.name = name;,这里,this.age表示域变量,而age表示的是参数变量,Java,的继承,31,this,构造方法中还可以用this来调用另一构造方法,如,Person( ),this( 0, );,如果在构造方法中调用另一构造方法,那么这条调用语句必须放在第一句,Java,的继承,32,This,举例:,getDouble.java,1,:,package p1;,2,:,import java.applet.*;,3,:,import java.awt.*;,4,:,import java.awt.event.*;,5,:,public class getDouble extends Applet implements ActionListener,6,:,7,:,Label prompt;,8,:,TextField input;,9,:,double d = 0.0;,10,:,11,:,public void init( ),12,:,13,:,prompt = new Label(,请输入一个浮点数:,);,14,:,input = new TextField(10);,15,:,add(prompt);,16,:,add(input);,17,:,input.addActionListener(this);,18,:,Java,的继承,33,this,getDouble.java,19,:,public void paint(Graphics g),20,:,21,:,g.drawString(,你输入了数据:, + d, 10, 50);,22,:,23,:,public void actionPerformed(ActionEvent e),24,:,25,:,d = Double.valueOf(input.getText( ).doubleValue( );,26,:,repaint( );,27,:,28,:,Java,的继承,34,this,getDouble.java,说明,第,17,句调,用的,addActionListener( ),方法是系统类,TextField,的方法,调用这个方法要求提供一个实现了,ActionListener,接口的对象作为实际参数,第,5,句,中定义的用户类,getDouble,利用,implements,关键字,(,接口及其实现将在本章后面介绍,),实现了,ActionListener,接口,就使用,this,将当前,getDouble,类的对象指定为调用,addActionListener( ),方法的实际参数,Java,的继承,35,super,super表示当前对象的直接父类对象,是当前对象的直接父类对象的引用,所谓直接父类是相对于当前对象的其他“祖先类而言的,例如,假设类A派生出子类B,B类又派生出自己的子类C,那么B是C的直接父类,而A是C的祖先类,同理,Number-PhoneCard类是D200-Card类的直接父类,PhoneCard类是D200-Card类的祖先类,子类自动地继承父类的(非private)属性和方法,一般情况下,使用this可以访问父类的域和方法,有时为了明确地指明父类的域和方法,就要用关键字super,Java,的继承,36,super,例如:父类,Person,有一个域,age,,在子类,Student,中用,age, this.age, super.age,来访问,age,是完全一样的,void testThisSuper(),int a1,a2,a3;,a1 = age;,a2 = this.age;,a3 = super.age;,Java,的继承,37,super,有时需要使用,super,以区别同名的域与方法,使用,super,可以访问,被子类所隐藏了的同名变量,当覆盖父类的同名方法的同时,又要调用父类的方法,就必须使用,super,例如,void sayHello(),super.sayHello();,System.out.println( My school is + school );,从这里可以看出,即使同名,也仍然可以使用父类的域和方法,这也使得在覆盖父类的方法的同时,又利用已定义好的父类的方法,Java,的继承,38,super,在严格意义上,构造方法是不能继承的,比方,父类Person有一个构造方法Person(String, int),不能说子类Student也自动有一个构造方法Student(String, int),但是,这不并意味着子类不能调用父类的构造方法,子类在构造方法中,可以用super来调用父类的构造方法,Student(String name, int age, String school ),super( name, age);,this.school = school;,使用时,super()必须放在第一句,Java,的继承,39,super,TestSuper.java,package p3;,12,:,abstract class PhoneCard,13,:,14,:,double balance;,16,:,abstract boolean performDial( );,17,:,double getBalance( ),18,:,19,:,return,balance,;,20,:,21,:,22,:,abstract class Number-PhoneCard extends PhoneCard,23,:,24,:,long cardNumber;,25,:,int password;,39,:,Java,的继承,40,super,TestSuper.java,40,:,class D200-Card extends Number-PhoneCard,41,:,42,:,double additoryFee;,43,:,double,balance,;,44,:,45,:,boolean performDial( ),46,:,47,:,if(,balance, (0.5 + additoryFee ),48,:,49,:,balance,-= (0.5 + additoryFee);,50,:,return true;,51,:,52,:,else,53,:,return false;,54,:,55,:,double getBalance( ),56,:,57,:,return,super.balance,;,58,:,59,:,Java,的继承,41,super,TestSuper.java,1,:,public class TestSuper,2,:,3,:,public static void main(String args),4,:,5,:,D200-Card my200 = new D200-Card( );,6,:,my200.balance = 50.0;,7,:,System.out.println(,父类被隐藏的金额为:,+,my200.getBalance( );,8,:,if(my200.performDial( ),9,:,System.out.println(,子类的剩余金额为:,+,my200.balance,);,10,:,11,:,Java,的继承,42,super,TestSuper.java,显示结果,Java,的继承,43,super,TestSuper.java,代码说明,第,57,句,D200-Card,类的方法,getBalance( ),返回的是当前对象的,super,域的,balance,变量,当前对象的,super,域是,D200-Card,类的直接父类,Number-PhoneCard,的引用,Number-PhoneCard,的,balance,变量是从,PhoneCard,类那里继承来的,因此,即使调用子类的,getBalance( ),方法,返回的仍是没有赋值的父类的,balance,变量,Java,的继承,44,super,TestSuper.java,代码说明,注意:,this,和,super,是属于,类的有特指的域,只能用来代表当前对象和当前对象的直接父对象,,而不能像其他类的属性一样随意引用,下面语句中的用法都是错误的,D200-Card my200 = new D200-Card( ) ;,my200.this.getBalance ( ) ; /,错误,my200.super.getBalance ( ) ; /,错误,除了用来指代当前对象或父类对象的引用外,,this,和,super,还有一个重要的用法,就是,调用当前对象或父类对象的构造方法,Java,的继承,45,this,与,super,在构造方法中的使用小结,this调用本类的其他构造方法,super调用直接父类的构造方法,如果没有this及super,那么编译器自动加上super(),即调用直接父类不带参数的构造方法,this或super要放在第一条语句,且只能够有一条,举例:ConstructCallThisAndSuper.java,Java,的继承,46,this,与,super,小结,ConstructCallThisAndSuper.java,package p4;,public class ConstructCallThisAndSuper,public static void main(String args),Person p = new Graduate();,class Person,String name;,int age;,Person(),Person( String name, int age ),this.name=name;,this.age=age;,System.out.println(In Person(String,int);,Java,的继承,47,this,与,super,小结,ConstructCallThisAndSuper.java,class Student extends Person,String school;,Student( String name, int age, String school ),super(name, age);,this.school = school;,System.out.println(In Student(String,int,String);,Student(),this(null, 0, null);,System.out.println(In Student();,class Graduate extends Student,Graduate(),System.out.println(In Graduate();,Java,的继承,48,this,与,super,小结,ConstructCallThisAndSuper.java运行结果,在构造方法中调用this及super或自动参加的super,最终保证了任何一个构造方法都要调用父类的构造方法,而父类的构造方法又会再调用其父类的构造方法,直到最顶层的Object类,这是符合面向对象的概念的,因为必须令所有父类的构造方法都得到调用,否那么整个对象的构建就可能不正确,Java,的继承,49,父类对象与子类对象的转换,类似于根本数据类型数据之间的强制类型转换,存在继承关系的父类对象和子类对象之间也可以在一定条件下相互转换,父类对象和子类对象的转化需要注意如下原那么,子类对象可以被视为是其父类的一个对象,父类对象不能被当作是其某一个子类的对象,如果一个方法的形式参数定义的是父类对象,那么调用这个方法时,可以使用子类对象作为实际参数,如果父类对象引用指向的实际是一个子类对象(在以前的某个时候根据(1)把子类对象的引用赋值给这个父类对象的引用),那么这个父类对象的引用可以用强制类型转换转化成子类对象的引用,Java,的继承,50,父类对象与子类对象的转换,举例,/,定义父类,class SuperClass,int x;,/,定义子类,class SubClass extends SuperClass,int y;,char ch;,/,使用父类与子类,public class UseSuperSub,SuperClass sc,sc_ref;,SubClass sb, sb_ref;,sc = new SuperClass( );,sb = new SubClass( );,/,父类引用可以指向子类对象,sc_ref = sb;,/,父类引用转换成子类引用,sb_ref = (SubClass)sc-ref;,Java,的继承,51,上溯造型,把派生类型当作根本类型处理只需写单一的代码,只与根底类打交道,忽略派生类型的特定细节。这样的代码易于编写和理解,且假设通过继承增添了一种新类型,新类型会像在原来的类型里一样正常的工作,是程序具备了扩展性。,doStuff(Shape s),s.erase();,/,s.draw();,Circle c=new Circle();,Triangle t= new Triangle();,Line l= new Line();,doStuff(c);,doStuff(t);,doStuff(l);,Java,的继承,52,主要内容,Java,的继承,Java,的多态,Java,的覆盖,Java,的重载,构造方法的重载与继承,内部类与匿名类,接口,53,多态概念,面向过程的语言编程,过程和方法各自对应一定的功能,它们之间是不能重名的,否那么在用名字调用时,就会产生歧异和错误,在面向对象的程序设计中,却需要利用这样的“重名现象来提高程序的抽象度和简洁性,Java,的多态,54,多态概念,举例:“拨打 是所有 卡都具有的操作,但是不同的 卡“拨打 操作的具体实现是不同的,磁卡的“拨打 是“找到磁卡 机直接拨号,200卡的“拨打 是“找到双音频 机,先输入卡号、密码后再拨号,如果不允许这些目标和最终功能相同的程序用同样的名字,就必须分别定义“磁卡拨打 、“200卡拨打 等多个方法,这样一来,继承的优势就荡然无存了,在面向对象的程序设计中,为了解决这个问题,引入了多态的概念,Java,的多态,55,多态概念,多态 (Polymorphism) 是指一个程序中同名的不同方法共存的情况,即一个程序中相同名字表示不同含义的情况,覆盖(override) 子类对父类方法,重载(overload) 同一个类中定义多个同名的不同方法,动态绑定dynamic binding -虚方法调用(virtual method invoking),多态优点,提高了程序的抽象程度和简洁性,最大限度地降低了类和程序模块之间的耦合性,提高了类模块的封闭性,使得它们不需了解对方的具体细节,就可以很好地共同工作,Java,的多态,56,基于覆盖的多态方法实现,子类对继承自父类的方法的重新定义,就称为方法的覆盖(overriding),是一种很重要的多态的形式,PhoneCard类的每一个子类都将继承这个方法performDial( ),但该方法代表的相同功能在不同种类的 卡中的具体实现不同,为了表达这一点,不同的子类可以重新定义、编写“拨打 这个方法(performDial( )的内容,以满足本类的特殊需要,实现这个具体 卡的特定拨打 的方法,所有子类中,但凡实现拨打 这种功能的方法,虽然内容不同,但却共享相同的名字“performDial,Java,的多态,57,基于覆盖的多态方法实现,在覆盖多态中,由于同名的不同方法是存在于不同的类,(,如磁卡、,IP,卡、,200,卡等,),中的,所以只需在调用方法时指明调用的是哪个类的方法,就可以很容易地把它们区分开来,如,MymagCard.performDial( )(MymagCard,是,magCard,类的对象,),my200.performDial( ),Java,的多态,58,基于覆盖的多态方法实现,另外还有一种不明确指定具体子类而把区分工作留给系统的情况,比方设某业务员需要向总部汇报一条消息,总部指示他:用 或 卡拨打,至于业务员使用何种 卡,具体如何拨打 这些细节那么不需要总部了解,系统会自动分辨所使用的 卡是哪种类型的 卡,并调用相应的拨打 的具体方法,Java,的多态,59,基于重载的多态方法实现,同一类中定义同名方法的情况称为重载(overloading),方法同名的原因,是因为它们的最终功能和目的都相同,但是由于在完成同一功能时,可能遇到不同的具体情况,所以需要定义含不同的具体内容的方法,来代表多种具体实现形式,例如,一个类需要具有打印的功能,而打印是一个很广泛的概念,对应的具体情况和操作有多种,如实数打印、整数打印、字符打印、分行打印等,为了使打印功能完整,在这个类中就可以定义假设干个名字都叫print的方法,每个方法用来完成一种不同于其他方法的具体打印操作,处理一种具体的打印情况,Java,的多态,60,基于重载的多态方法实现,由于重载发生在同一个类里,不能再用类名来区分不同的方法,所以一般,采用不同的形式参数列表,,包括形式参数的个数、类型、顺序的不同,来区分重载的方法,打印实数的,print,方法的形式参数是一个实数和打印格式串,,打印整数的,print,方法的形式参数是一个整数和打印格式串,Java,的多态,61,基于重载的多态方法实现,当其他类要利用这个类的打印功能时,它只需简单地调用,print,方法并把一个参数传递给,print,,由系统根据这个参数的类型来判断应该调用哪一个,print,方法,在实际应用中,这个被传递的参数很可能是来自另一个操作的结果,它在不同的情况下可能是动态变化的,而调用,print,的类可以对这一切一无所知,它所关心的仅仅是打印功能被完成了,至于具体打印了什么,如何打印的,可以统统不予细究,Java,的多态,62,虚方法调用,用虚方法调用,可以,实现运行时的多态,!,在使用,上溯造型,的情况下,子类对象可以当做父类对象,对于重载或继承的方法,,Java,运行时系统根据调用该方法的实例的类型来决定选择哪个方法调用,所有的非,final,方法都会自动地进行绑定!,Java,的多态,63,虚方法调用,举例,:TestVirtualInvoke.java,Java,的多态,package p5;,class Shape,void draw() System.out.println(Shape Drawing); ,class Circle extends Shape,void draw() System.out.println(Draw Circle); ,class Triangle extends Shape,void draw() System.out.println(Draw Three Lines); ,class Line extends Shape,void draw() System.out.println(Draw Line); ,64,public class TestVirtualInvoke,static void doStuff( Shape s ),s.draw();,public static void main( String args ),Circle c = new Circle();,Triangle t = new Triangle();,Line l = new Line();,doStuff(c);,doStuff(t);,doStuff(l);,虚方法调用,举例,:TestVirtualInvoke.java,Java,的多态,65,虚方法调用,子类重载父类方法时,运行时系统调用子类的方法;子类继承父类方法时,那么调用父类的方法,运行时,根据实际的类型调用正确的方法,对面向对象的程序设计来说,就叫“多态型性,用虚方法调用,可以实现运行时的多态,它表达了面向对象程序设计中的代码复用性,已编译好的类库可以调用新定义的子类的方法而不必重新编译,而且如果增加几个子类的定义,只需分别用new生成不同子类的实例,会自动调用不同子类的相应方法,static, private, 和 final不存在虚方法的调用问题,Java,的多态,66,动态类型确实定,变量,instanceof,类型结果是,boolean,值,package p6;,public class InstanceOf,public static void main(String args),Object things = new Object3;,things0 = new Integer(4);,things1 = new Double(3.14);,things2 = new Double(2.09);,double s = 0;,for( int i=0; ithings.length; i+ ),if(,thingsi instanceof Integer,),s += (Integer)thingsi).intValue();,else if( thingsi instanceof Double ),s += (Double)thingsi).doubleValue();,System.out.println(sum= + s);,Java,的多态,67,Class,类,对象可以通过,getClass(),方法来获得运行时的信息,getClass(),是的方法,而,Object,是所有类的父类,任何对象都可以用,getClass(),方法,这种获得运行时对象的方法也叫,反射,举例:,RunTimeClassInfo.java,getClass(),方法得到对象的运行时的类信息,即一个,Class,类的对象,它的,getFields(),及,getMethods(),方法能进一步获得其详细信息,Java,的多态,68,Class,类,RunTimeClassInfo.java,package p7;,import java.lang.reflect.*;,class RunTimeClassInfo ,public static void main(String args) ,Object obj = new java.awt.Color(1,1,1);,Class cls = obj.getClass();,System.out.println( ,类名,: +,cls.getName(),);,Field fields = cls.getFields();,for( int i=0; ifields.length; i+ ),Field f = fieldsi;,System.out.println( ,域,: +,f.getName(),+ : + f );,Method methods =,cls.getMethods();,for( int i=0; imethods.length; i+ ),Method m = methodsi;,System.out.println( ,方法:, + m.getName() + : + m );,Java,的多态,类名,:,域,:,域,域,域,方法,:,getBlue:public int java.awt.Color.getBlue(),方法:,getColor:public static java.awt.Color java.awt.Color.getColor(java.lang.String,int),方法:,getColor:public static java.awt.Color java.awt.Color.getColor(java.lang.String),70,主要内容,Java,的继承,Java,的多态,Java,的覆盖,Java,的重载,构造方法的重载与继承,内部类与匿名类,接口,71,方法的覆盖,子类也可以重新定义与父类同名的方法,实现对父类方法的覆盖(Overriding),方法覆盖与域隐藏的不同之处,子类隐藏父类的域只是使之不可见,父类的同名域在子类对象中仍然占有自己的独立的内存空间,子类方法对父类同名方法的覆盖将去除父类方法占用的内存,从而使父类方法在子类对象中不复存在,在各 卡类的方法中,magCard,IC-Card,IP-Card,D200-Card四个类都定义了自己的performDial( )方法,所以它们从父类那里继承来的抽象的performDial( )就不存在了,Java,的覆盖,72,方法的覆盖举例,TestOverLoad.java,在,D200-Card,类中增加定义一个与从父类那里继承来的,getBalance( ),方法同名的方法,Java,的覆盖,12,:,abstract class PhoneCard,13,:,14,:,double balance;,15,:,16,:,abstract boolean performDial( );,17,:,double getBalance( ),18,:,19,:,return,balance,;,20,:,21,:,73,方法的覆盖举例,TestOverLoad.java,22,:,abstract class Number-PhoneCard extends PhoneCard,23,:,24,:,long ca
展开阅读全文
相关资源
正为您匹配相似的精品文档
相关搜索

最新文档


当前位置:首页 > 管理文书 > 各类标准


copyright@ 2023-2025  zhuangpeitu.com 装配图网版权所有   联系电话:18123376007

备案号:ICP2024067431-1 川公网安备51140202000466号


本站为文档C2C交易模式,即用户上传的文档直接被用户下载,本站只是中间服务平台,本站所有文档下载所得的收益归上传人(含作者)所有。装配图网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。若文档所含内容侵犯了您的版权或隐私,请立即通知装配图网,我们立即给予删除!