chap5 java继承与多态.ppt_第1页
chap5 java继承与多态.ppt_第2页
chap5 java继承与多态.ppt_第3页
chap5 java继承与多态.ppt_第4页
chap5 java继承与多态.ppt_第5页
已阅读5页,还剩44页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、Chap5 继承与多态,继承的基本概念,继承是面向对象程序设计的一种重要手段,可以更有效的组织程序,明确类之间的关系,实现代码重用 当一个类获取另一个类的所有非私有属性作为自己的部分或全部成分时,就称这两个类之间具有继承关系。 被继承的类称为父类或超类 继承了父类或超类的所有数据和操作的类称为子类。,一个父类可以有多个子类 比如电话卡类,Java中一个子类只能有一个父类 即单继承 C+中一个子类可以有多个父类,即多重继承 类继承的方法:通过extends来实现 形式如:class subclass extends superclass subclass将继承它的父类superclass的所有非

2、私有属性作为自己的所有或部分成员。,说各个类的成员情况,默认属性均为公有的,域的继承与隐藏,域的继承 继承父类的所有非私有域,减少程序的维护工作量 域的隐藏 在子类中重新定义一个与从父类继承来的域 完全相同的变量。即子类中含有两个同名的 变量。当子类执行继承自父类的方法时,处 理的是继承自父类的变量;当子类执行它自 己定义的方法时,处理的是它自己定义的变 量,而把继承自父类的变量“隐藏”起来。,注意在域的隐藏情况下,继承自父类的变量在子类中仍然占有一个内存空间。,public class testhidefield public static void main(String args) su

3、bclass subc1=new subclass(); System.out.println(subc1.supergetvar();/输出super System.out.println(subc1.subgetvar();/输出sub System.out.println(subc1.supervar);/输出sub class superclass String supervar=“super”; String supergetvar()return supervar; class subclass extends superclass String supervar=“sub”;/子

4、类中有两个supervar String subgetvar() return supervar; ,方法的继承和覆盖,方法的继承:子类继承父类所有的非私有方法。 方法的覆盖:与域的隐藏类似,子类中定义与父类中相同的方法。不同的是继承自父类同名方法在子类中被覆盖,在子类中没有内存存放。,public class testoverload public static void main(String args) subclass subc1=new subclass(); subc1.superprint(); class superclass void superprint() System.

5、out.println(“super method”); class subclass extends superclass void superprint()/父类的superprint()被覆盖,不存在了 System.out.println(“sub method”); ,this 与super,this 表示的是当前对象的一个引用。可以理解为对象的另一个名字。 super 用于在一个类中引用它的父类,即引用父类的成员。注意super代表的是当前类的直接父类,而不是它的祖先类。 B是C的直接父类 A是C的祖先类,public class testthisandsuper public s

6、tatic void main(String args) phonecard200 pc200=new phonecard200(123,111); System.out.println(“父类的值”+pc200.getbalance(); System.out.println(“本类的值”+pc200.get200balance(); class phonecard double balance=100; class phonecard200 extends phonecard long cardnum; long password; double balance=200; phonecar

7、d200(long cardnum,long password) this.cardnum=cardnum; this.password=password; double getbalance()return super.balance; double get200balance()return this.balance;,多态,多态是由封装和继承所引出的另一面向对象程序设计的特征。 所谓多态,一般是指一个程序中同名的不同方法共存的情况。 在面向过程程序设计中一个程序中不允许有同名的过程或函数 面向对象设计中却利用这种重名提高程序的抽象度和简洁度 多态的实现方式:方法的覆盖 方法的重载和对象引

8、用的多态,方法的覆盖,前面已经讲过,通过子类重新定义从父类那里继承的方法实现。 要实现覆盖,子类和父类定义的方法名要完全一致,包括修饰符和参数列表。 如何区分同名的方法呢? 由于两个方法处在不同的类中,因此调用时只要指明是哪个类的方法即可。父类的对象调用的是父类的方法,子类的对象调用的是子类的方法。,方法的重载,重载,是在一个类中定义同名字的方法的情况。 存在的必要性:完成某个操作时,可能会遇到不同的情况,需要定义不同的具体内容。 例如:print方法有: public void print(); public void print(boolean x); public void print(

9、char x); public void print(int x); public void print(float x); public void print(String x); 如何区分?通过方法的参数列表区分,包括参数的个数、类型和顺序的不同来区分。,对象引用的多态,类似与强制类型转换。子类的对象可以做父类对象来使用。 例如:单位里有职工(Employee),职工中有少数人是管理者(Manager),有个别是单位领导(Leader) 于是这三个类可以形成以下关系:,class Empolyeedouble salary; class Manager extends Empolyeedo

10、uble allowance; class Leader extends Manager Employee emp1=new Employee(); Employee emp2=new Manager();/emp2是Employee类型的变量 Employee emp3=new Leader(); emp2.salary emp2.allowance 父类变量可以让一个子类的对象做父类对象可以做的事情。也就是说,通过父类的变量不能让子类对象做父类对象不能做的事情,即使子类对象有这样的功能。,如果父类变量实际指向子类对象,可以使用类似强制类型转换,将父类变量转换为子类变量 Manager mg

11、r=(Manager)em2p; emp2.allowance 下面的情况是错的: Employee emp=new Employee() Manager mgr=(Manager)emp,在对象引用的多态中,如何确定某个变量是父类的对象,还是子类的对象呢? 可以使用关系运算符instanceof 例:Employee emp=new Employee() emp instanceof Employee /结果为true emp instanceof Manager /结果为false Employee emp2=new Manager() emp instanceof Employee /结

12、果为false emp instanceof Manager /结果为true,构造函数的重载,在一个类中,可以根据需要,定义多个构造函数。当然,它们的参数列表应不同。系统会根据创建对象时给出的实参判断应该调用哪个构造函数。 如果不构造任何构造函数,系统会默认构造一个空构造函数,不执行任何具体操作。,类 phonecard200可以定义以下构造函数: phonecard200() phonecard200(long cn) cardnum=cn; phonecard200(long cn,long pw) cardnum=cn; password=pw phonecard200(long cn

13、,long pw,double b) cardnum=cn; password=pw ; balance=b; 创建一个对象: phonecard200 pc200=new phonecard200(1234,1234),可以使用this简化定义, this(参数列表) 必须在第一句 phonecard200() phonecard200(long cn) this(); cardnum=cn; phonecard200(long cn,long pw) this(cn); password=pw phonecard200(long cn,long pw,double b) this(cn,p

14、w); balance=b; 但是不能显示调用其他的构造函数: phonecard200(long cn,long pw,double b) phonecard200(cn,pw); balance=b;,调用父类的构造函数,严格说,父类和子类间的构造函数不存在继承关系,但是它们却存在一定的关系。 如果子类没有定义任何构造函数,则创建子类对象时,调用父类无参数的构造函数 如果子类定义了构造函数,则在创建子类对象时,系统将首先隐含执行无参数的构造函数,然后在执行子类自己的构造函数 如果在子类自己定义的构造函数中,利用super显示调用父类构造函数,系统将不再隐含执行父类的无参数构造函数。,cla

15、ss phonecard double balance; phonecard() System.out.println(this is from super); class phonecard201 extends phonecard,class phonecard200 extends phonecard double additoryfee; phonecard200() System.out.println(this is from sub); class phonecard300 extends phonecard double additoryfee; phonecard300(do

16、uble additoryfee) this.additoryfee=additoryfee; System.out.println(this is from sub); ,public class myphone public static void main(String args) System.out.println(子类没有定义构造函数); phonecard201 pc201=new phonecard201(); System.out.println(子类定义了无参数的构造函数); phonecard200 pc200=new phonecard200(); System.out

17、.println(子类定义了含参数的构造函数); phonecard300 pc300=new phonecard300(0.5); ,请你编程验证,子类的构造函数中用super用父类的含参数构造函数时,系统是否调用父类无参数构造函数。,注意:super的显示调用语句必须在子类构造函数的第一句可执行语句。 例:class num_phonecard double balance; num_ phonecard (double b) balance=b; class phonecard200 extends num_phonecard long cardnum, password; phonec

18、ard200(long cn,long pw, double b) super(b); cardnum=cn;password=pw; ,如何为用户自定义类设计构造函数,不定义构造函数; 根据情况定义有一定功能的构造函数,即初始化变量或对数据做合法性检查 利用重载技术,定义多个构造函数,实现多层次的对象初始化。如:phonecard200 如果存在类间继承关系,可以利用super调用父类的构造函数。,对象初始化过程,分为三步 当为对象分配内存空间后,首先将属性单元初始化。赋默认值 执行显示初始化。类定义时付的初值。如:int i=9; 执行构造函数中的初始化,public class test

19、init3public static void main(String args) Manager mgr=new Manager(“王欣”,200f); System.out.println(); System.out.println(mgr.salary); System.out.println(mgr.married); System.out.println(mgr.allowance); class Employee String name; float salary; boolean married; Employee() salary=500; ,class Man

20、ager extends Employee float allowance; String post=“Mgr”; Manager(String n,float aa) name=n; allowance=aal; ,首先,隐含初始化4个属性,name=null, salary=0.0,married=false,allowance=0.0,然后,执行显示的初始化, post=“Mgr”; 最后执行构造函数的初始化,先调用父类无参数构造函数,对salary=500 再执行Manager类自己的构造函数 name=“王欣”,allowance=200,包及其使用,java应用开发过程中,会定义和

21、使用很多的类,如何管理这些类是一个必须解决的问题。 在操作系统中,系统采用目录(文件夹)来组织和管理文件。在一个文件夹中文件不能重名,但是不同文件夹中的文件可以重名。 类似地,java也采用了这样的管理方式。不过我们将文件夹称为“包”package,不同类的属性可以重名,不同包的类可以重名。利用包虎贲名字空间以避免类名冲突。 包是一种松散的类的集合,他们通常一起完成某个任务。 包有两种:一种是无名字包,一种是有名字包 无名包:其他程序不能使用无名包中的类 有名包:文件第一句声明:package 包名; 其他程序可以使用其中的类。包名.类名 包名通常使用小写字母;url的逆序,包的创建,在jav

22、a源程序的第一句声明包名,以下两种格式: package 包名;或 package 包名1.包名2. 例package abc; package abc.test; 创建一个包abc 创建abc包中的包test 一个abc文件夹 abc文件夹的子文件夹test,package abc; public class myabc public static void main(String args) testpackage tp=new testpackage(); tp.pnt(); class testpackage void pnt() System.out.println(this mes

23、sage is from testpackage); ,package abc; public class t2 public static void main(String args) System.out.println(this is from t2); testpackage tp=new testpackage(); tp.pnt(); ,myabc testpackage t2同一个包的类, 所以是互相可见的,可以不用import直接引用,如何编译运行,手工方式 Java开发过程中,源文件和类文件应该分开存放在不同的目录中。以下都假设在f:javasrc中存放源文件myabc 自动

24、方式 在编译的同时自动完成包的创建和类的加入,手工方式,编译:f: javac javasrcmyabc.java或者f:javasrcjavac myabc.java 编译生成myabc.class 和testpackage.class 根据文件要求通常在源文件所在目录的上一级目录中新建以包名命名的文件夹 abc 将生成的字节码文件拷贝到包文件夹 abc 运行java程序 java 包名.主类名 f: java abc.myabc,自动方式,用javac -d编译 自动创建包的目录并加载类 如:f:javasrc javac -d 包所在目录 源文件名 例如: f:javasrc javac

25、 -d f: myabc.java 或f: javac d f: javasrcmyabc.java f: javac d . javasrcmyabc.java -d . 表示当前目录 运行:f:java abc.myabc,包的使用,包的指定 在一个类中,可以使用包名.类名使用包中的类 引入所需要的类 import 包名.类名; 引入整个包 import 包名.*; 包的定位 系统如何寻找包? 通过设置环境变量classpath,可以采用命令行方式,set classpath=.;f:workspace; classpath 告知java解释器类文件在哪里,接口 interface,接口是

26、用来实现类间多重继承的结构。 由于JAVA是单重继承,随着子类的增加,越处在下层的子类的间接父类就越多,所继承的方法就越来越多,造成子类成员的膨胀和难以管理。 为了实现从其他父类中继承某些的操作,引入接口,实现了多重继承,但是又不会带来多重继承的内存开销大等缺点。 public class myplet extends Applet implements ActionListener,接口的基本概念 所谓接口,就是一系列常量和方法协议的集合,它提供了多个类共同行为的接口,但不限制每个类如何实现这些方法。 方法协议:是指只有方法名和参数列表,而没有方法体的一种说明格式。他只体现方法的说明,但不指

27、定方法体,真正的方法体是类来实现的。,接口的声明 public interface 接口名 extends 父接口名列表 /大括号里是接口体 publicstaticfinal 域类型 域名=常量值 public abstractnative返回类型 方法名(参数列表)throw 异常列表 修饰符 public 和缺省类型,缺省情况下具有包访问性,public可以被其他任何代码所使用。 接口有继承性,可以继承多个父接口,继承父接口的所有属性和方法。,接口体的定义 由两部分组成,一部分是接口的属性,即常量,一部分是接口的方法的声明。 接口的常量默认类型为public final static,不

28、写修饰符也是同样效果 接口的方法隐含类型为public abstract,接口中只能给出抽象方法的方法名、返回值和参数列表,不能定义方法体。接口的方法体可以用其他语言书写,此时方法可以有native修饰符 例子 interface performdail publicfinalstatic double balance; publicabstract double getbalance( ); ,接口,接口,类,实现,实现,接口与类存在的本质区别 类有成员变量和方法,而接口只有常量和方法协议。 接口的方法协议与方法实体之间只起到一种界面的作用,它限定了方法实体中的参数类型一定要与方法协议中规定

29、的参数类型保持一致,除此之外,还要求方法名,参数个数及方法返回类型的一致性。 类与接口之间并不存在子类和父类的继承关系,一个类可以实现多个接口,实现接口:接口只是定义了一些抽象方法,如果不具体实现就没有任何意义。实现接口:某个类为接口中的抽象法书写方法体。注意: 类在声明部分,必须用implements指明要实现的接口名 格式:class xx implements f1,f2 接口中的方法已默认是public 修饰符,所以在实现时必须显示地使用public修饰,否则将被警告缩小了接口中定义的方法的访问控制范围 类在实现接口中的方法时,必须使用完全相同的方法名(覆盖) 如果一个类是非抽象类,则必须实现所有抽象方法,包括从父类继承的抽象方法和实现自接口中的抽象方法。如果一个类是抽象类,则可以不实现接口中的抽象方法,interface adddemo public int add(int x, int y); interface subdemopublic int sub(int x, int y);

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论