第5章类的继承性与态性_第1页
第5章类的继承性与态性_第2页
第5章类的继承性与态性_第3页
第5章类的继承性与态性_第4页
第5章类的继承性与态性_第5页
已阅读5页,还剩39页未读 继续免费阅读

下载本文档

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

文档简介

1、第第5章章 类的继承性与多态性类的继承性与多态性5.1 类的继承类的继承5.2 类的多态类的多态习题习题新类可从现有的类中产生,将保留现有类的状态属新类可从现有的类中产生,将保留现有类的状态属性和方法并可根据需要加以修改。新类还可添加新性和方法并可根据需要加以修改。新类还可添加新的状态属性和方法,这些新增功能允许以统一的风的状态属性和方法,这些新增功能允许以统一的风格处理不同类型的数据。这种现象就称为类的继承。格处理不同类型的数据。这种现象就称为类的继承。 5.1 类的继承类的继承 当建立一个新类时,不必写出全部成员变量和成员当建立一个新类时,不必写出全部成员变量和成员方法。只要简单地声明这个

2、类是从一个已定义的类方法。只要简单地声明这个类是从一个已定义的类继承下来的,就可以引用被继承类的全部成员。被继承下来的,就可以引用被继承类的全部成员。被继承的类称为父类或超类(继承的类称为父类或超类(superclass),这个新),这个新类称为子类。类称为子类。java提供了一个庞大的类库让开发人员继承和使用。提供了一个庞大的类库让开发人员继承和使用。通常要对子类进行扩展,即添加新的属性和方法。通常要对子类进行扩展,即添加新的属性和方法。这使得子类要比父类大,但更具特殊性,代表着一这使得子类要比父类大,但更具特殊性,代表着一组更具体的对象。继承的意义就在于此。组更具体的对象。继承的意义就在于

3、此。 5.1.1 父类和子类父类和子类 在类的声明语句中加入在类的声明语句中加入extends关键字和指定的类关键字和指定的类名即可实现类的继承,例如:名即可实现类的继承,例如: public class myapplet extends java.applet.appletpublic class myapplication extends framepublic class myapp1 extends objectpublic class myapp2那么,类的继承是从什么地方开始的?又是如何延那么,类的继承是从什么地方开始的?又是如何延续下来的呢?请看图续下来的呢?请看图5.1所示的模

4、拟图。所示的模拟图。图图5.1反映了反映了java类的层次结构。最顶端的类是类的层次结构。最顶端的类是object,它在,它在java.lang中定义,是所有类的始祖。中定义,是所有类的始祖。一个类可以有多个子类,也可以没有子类,但它必一个类可以有多个子类,也可以没有子类,但它必定有一个父类(定有一个父类(object除外)。除外)。图图 5.1子类不能继承父类中的子类不能继承父类中的private成员,除此之外,其成员,除此之外,其他所有的成员都可以通过继承变为子类的成员。另他所有的成员都可以通过继承变为子类的成员。另一方面,对继承的理解应该扩展到整个父类的分支,一方面,对继承的理解应该扩展

5、到整个父类的分支,也就是说,子类继承的成员实际上是整个父系的所也就是说,子类继承的成员实际上是整个父系的所有成员。有成员。 因此,可以得出如下结论:因此,可以得出如下结论: 子类只能有一个父类。如果省略了子类只能有一个父类。如果省略了extends,子类,子类的父类是的父类是object。子类继承了父类和祖先的成员,。子类继承了父类和祖先的成员,可以使用这些成员。在需要的时候,子类可以添加可以使用这些成员。在需要的时候,子类可以添加新的成员变量和方法,也可以隐藏父类的成员变量新的成员变量和方法,也可以隐藏父类的成员变量或覆盖父类的成员方法。或覆盖父类的成员方法。 1. 成员变量的继承成员变量的

6、继承 例例5.1 下面的下面的3个程序说明从点个程序说明从点point类扩展到线类扩展到线line类和圆类和圆circle类的方法,这是类的方法,这是3个公共类,不能个公共类,不能放在同一个文件中。它们都没有输出语句,即使补放在同一个文件中。它们都没有输出语句,即使补上相应的上相应的 main() 使之运行也看不到什么结果。使之运行也看不到什么结果。public class point protected int x, y; point(int a, int b) setpoint(a, b); public void setpoint(int a, int b) x=a; y=b; publ

7、ic int getx() return x;5.1.2 成员变量的继承和隐藏成员变量的继承和隐藏 public int gety() return y;public class line extends point protected int x, y, endx, endy; line(int x1, int y1, int x2, int y2) setline(x1, y1, x2, y2); public void setline(int x1, int y1, int x2, int y2) x=x1; y=y1; endx=x2; endy=y2; public int getx

8、() return x ; public int gety() return y ; public int getendx() return endx; public int getendy() return endy; public double length() return math.sqrt(endx-x) * (endx-x) + (endy-y) * (endy-y); public class circle extends point protected int radius; circle(int a, int b, int r) super(a, b); setradius(

9、r); public void setradius(int r) radius=r; public int getradius() return radius; public double area() return 3.14159*radius*radius; 上例中,上例中,point类具备一个点的特征。类具备一个点的特征。line和和circle类具备线和圆的特征,但它们都是从类具备线和圆的特征,但它们都是从point继承下继承下来的。下面分析一下这来的。下面分析一下这3个类各自都有哪些成员。个类各自都有哪些成员。 point: x, y / 受保护的成员变量,代表点的坐标受保护的成员变

10、量,代表点的坐标 point/ 点的构造方法点的构造方法 setpoint/ 设定点的坐标值的方法设定点的坐标值的方法 getx, gety/ 返回坐标返回坐标x和和y的值的方法的值的方法line: x, y, endx, endy/ 子类受保护的成员变量,代表线的两个端点坐标子类受保护的成员变量,代表线的两个端点坐标 line / 线的构造方法线的构造方法 setline / 设定线的两个端点坐标值的方法设定线的两个端点坐标值的方法 getx, gety/ 返回起点坐标返回起点坐标x和和y的值的方法的值的方法 getendx, getendy/ 返回终点坐标返回终点坐标endx和和endy的

11、值的方法的值的方法 length / 返回线的长度的方法返回线的长度的方法 x, y/ 继承父类的受保护成员变量,但被子类隐藏继承父类的受保护成员变量,但被子类隐藏 setpoint/ 继承父类的方法继承父类的方法 getx, gety/ 继承父类的方法,但被子类覆盖继承父类的方法,但被子类覆盖circle: radius / 子类受保护的成员变量,代表圆的半径子类受保护的成员变量,代表圆的半径 circle / 圆的构造方法圆的构造方法 setradius / 设定半径值的方法设定半径值的方法 getradius / 返回半径值的方法返回半径值的方法 area / 返回圆面积的方法返回圆面积

12、的方法 x, y / 继承父类的受保护成员变量继承父类的受保护成员变量 setpoint / 继承父类的方法继承父类的方法 getx, gety/ 继承父类的方法继承父类的方法从上面的分析可以看到,子类从上面的分析可以看到,子类circle继承了父类继承了父类point中的成员变量中的成员变量x和和y,也继承了,也继承了setpoint、getx和和gety方法。添加了自己的成员变量方法。添加了自己的成员变量radius,成员,成员方法方法setradius、getradius和和area。在构造方法。在构造方法circle中,调用了父类的构造方法设定圆心坐标。中,调用了父类的构造方法设定圆心

13、坐标。2. 成员变量的隐藏成员变量的隐藏所谓隐藏是指子类重新定义了父类中的同名变量,所谓隐藏是指子类重新定义了父类中的同名变量,如子类如子类line重新定义了重新定义了x为为x1,y为为y1,隐藏了父类,隐藏了父类point中的两个成员变量中的两个成员变量x和和y。子类执行自己的方。子类执行自己的方法时,操作的是子类的变量,子类执行父类的方法法时,操作的是子类的变量,子类执行父类的方法时,操作的是父类的变量。在子类中要特别注意成时,操作的是父类的变量。在子类中要特别注意成员变量的命名,防止无意中隐藏了父类的关键成员员变量的命名,防止无意中隐藏了父类的关键成员变量,这有可能给你的程序带来麻烦。变

14、量,这有可能给你的程序带来麻烦。line还覆盖了还覆盖了point的两个方法的两个方法getx和和gety。关于。关于方法覆盖,请看下面的内容。方法覆盖,请看下面的内容。 通过继承子类可以继承父类中所有可以被子类访问通过继承子类可以继承父类中所有可以被子类访问的成员方法,但如果子类的方法与父类方法同名,的成员方法,但如果子类的方法与父类方法同名,则不能继承,此时称子类的方法覆盖了父类的那个则不能继承,此时称子类的方法覆盖了父类的那个方法,简称为方法覆盖。方法的覆盖(方法,简称为方法覆盖。方法的覆盖(override),),为子类提供了修改父类成员方法的能力。例如,子为子类提供了修改父类成员方法

15、的能力。例如,子类可以修改层层继承下来的类可以修改层层继承下来的tostring方法,让它输方法,让它输出一些更有用的信息。例出一些更有用的信息。例5.2显示了在子类显示了在子类circle中中添加添加tostring方法,用来返回圆半径和圆面积信息。方法,用来返回圆半径和圆面积信息。 5.1.3 成员方法的覆盖成员方法的覆盖 例例5.2 对对object的的tostring方法的覆盖示例,结果如方法的覆盖示例,结果如图图5.2所示。所示。图图 5.2class circle private int radius; circle(int r) setradius(r); public void

16、 setradius(int r) radius=r; public int getradius() return radius; public double area() return 3.14159*radius*radius; public string tostring() return 圆半径:圆半径: +getradius()+ 圆面积:圆面积: +area(); public class o1 public static void main(string args) circle c=new circle(10); system.out.println(n+c.tostring(

17、); 方法覆盖时要特别注意:方法覆盖时要特别注意: 用来覆盖的子类方法应和被覆盖的父类方法保持相用来覆盖的子类方法应和被覆盖的父类方法保持相同名称和相同返回值类型,以及相同的参数个数和同名称和相同返回值类型,以及相同的参数个数和参数类型。如果被覆盖的方法没有声明抛出异常,参数类型。如果被覆盖的方法没有声明抛出异常,子类的覆盖方法可以有不同的抛出异常子句。子类的覆盖方法可以有不同的抛出异常子句。有时,可能不需要完全覆盖一个方法,可以部分覆有时,可能不需要完全覆盖一个方法,可以部分覆盖一个方法。部分覆盖是在原方法的基础上添加新盖一个方法。部分覆盖是在原方法的基础上添加新的功能,即在子类的覆盖方法中

18、添加一条语句:的功能,即在子类的覆盖方法中添加一条语句: super.原父类方法名,然后加入其他语句。原父类方法名,然后加入其他语句。注意:注意: 不能覆盖父类中的不能覆盖父类中的final方法。同样也不能方法。同样也不能覆盖父类中的覆盖父类中的static方法,但可以隐藏这类方法。方法,但可以隐藏这类方法。也就是说,在子类中声明的同名静态方法实际上隐也就是说,在子类中声明的同名静态方法实际上隐藏了父类中的静态方法。此外,非抽象子类必须覆藏了父类中的静态方法。此外,非抽象子类必须覆盖父类中的抽象方法。盖父类中的抽象方法。 例例5.3 说明说明this和和super的使用,运行结果如图的使用,运

19、行结果如图5.3所所示。示。图图 5.3class point protected int x, y;5.1.4 this和和super point(int a, int b) setpoint(a, b); public void setpoint(int a, int b) x=a; y=b; class line extends point protected int x, y; line(int a, int b) super(a, b); setline(a, b); public void setline(int x, int y) this.x=x+x; this.y=y+y;

20、public double length() int x1=super.x, y1=super.y, x2=this.x, y2=this.y; return math.sqrt(x2-x1) * (x2-x1) + (y2-y1) * (y2-y1); public string tostring() return 直线端点:直线端点: + super.x + , + super.y + + x + , + y + 直线长度:直线长度: + this.length(); public class thisdemo public static void main(string args) li

21、ne line=new line(50, 50); system.out.println(n+line.tostring(); 总结上例,可以概括出总结上例,可以概括出this和和super 的作用。的作用。 (1) this实际代表的是当前类或对象本身。实际代表的是当前类或对象本身。在一个类中,在一个类中,this表示对当前类的引用,在使用类表示对当前类的引用,在使用类的成员时隐含着的成员时隐含着this引用,尽管可以不明确地写出,引用,尽管可以不明确地写出,例如例如length和和tostring中对中对x和和y的使用。当一个类被的使用。当一个类被实例化为一个对象时,实例化为一个对象时,t

22、his就是对象名的另一种表就是对象名的另一种表示。通过示。通过this可顺利地访问对象,凡在需要使用对可顺利地访问对象,凡在需要使用对象名的地方均可用象名的地方均可用this代替。例如:代替。例如: public class demo extends java.applet.applet implements actionlistener button button1=new button(add); public void init() add(button1); b u t t o n 1 . a d d a c t i o n l i s t e n e r ( t h i s ) ;

23、/ / 等 价 于等 价 于button1.addactionlistener(demo); (2) super代表着父类。代表着父类。如果子类的变量隐藏了父类的变量,使用不加引用如果子类的变量隐藏了父类的变量,使用不加引用的变量一定是子类的变量,如果要使用父类的变量,的变量一定是子类的变量,如果要使用父类的变量,就必须加上就必须加上super引用。同样道理,如果有方法覆引用。同样道理,如果有方法覆盖的发生,调用父类的方法时也必须加上盖的发生,调用父类的方法时也必须加上super引引用。用。例例5.4 在下面两个类中了解在下面两个类中了解super的使用,运行结果的使用,运行结果如图如图5.4

24、所示。所示。class classa boolean var; void method() var=true; class ba extends classa boolean var; void method() var=false; super.method(); system.out.println(子类变量子类变量var为为 +var); system.out.println(父类变量父类变量var为为 +super.var); public static void main(string args) ba a=new ba(); a.method(); 图图 5.4 (3) super

25、() 可用来调用父类的构造方法。可用来调用父类的构造方法。这也是惟一由程序员间接调用类的构造方法的途径,这也是惟一由程序员间接调用类的构造方法的途径,因为因为java规定类的构造方法只能由规定类的构造方法只能由new操作符调用,操作符调用,程序员不能直接调用。同理,程序员不能直接调用。同理,this() 也可用来间接也可用来间接调用当前类或对象的构造方法。调用当前类或对象的构造方法。类的构造方法是不能继承的,因为构造方法不是类类的构造方法是不能继承的,因为构造方法不是类的成员,没有返回值,也不需要修饰符。又由于父的成员,没有返回值,也不需要修饰符。又由于父类的构造方法和父类同名,在子类中继承父

26、类的构类的构造方法和父类同名,在子类中继承父类的构造方法肯定和子类不同名,这样的继承是无意义的。造方法肯定和子类不同名,这样的继承是无意义的。但子类可以使用但子类可以使用super()调用父类的构造方法,如在调用父类的构造方法,如在例例5.3中:中: class line extends point protected int x, y; line(int a, int b) super(a, b); setline(a, b); 其中其中super(a, b) 就是在子类中调用父类的构造方法,就是在子类中调用父类的构造方法,为父类的成员变量赋初值。为父类的成员变量赋初值。注意:注意: sup

27、er() 只能出现在子类的构造方法中,而只能出现在子类的构造方法中,而且必须是子类构造方法中的第一条可执行语句。且必须是子类构造方法中的第一条可执行语句。类的继承发生在多个类之间,而类的多态只发生在类的继承发生在多个类之间,而类的多态只发生在同一个类上。在一个类中,可以定义多个同名的方同一个类上。在一个类中,可以定义多个同名的方法,只要确定它们的参数个数和类型不同。这种现法,只要确定它们的参数个数和类型不同。这种现象称为类的多态。象称为类的多态。多态使程序简洁,为程序员带来很大便利。在面向多态使程序简洁,为程序员带来很大便利。在面向对象编程中,当程序要实现多个相近的功能时,就对象编程中,当程序

28、要实现多个相近的功能时,就给相应的方法起一个共同的名字,用不同的参数代给相应的方法起一个共同的名字,用不同的参数代表不同的功能。这样,在使用方法时不论传递什么表不同的功能。这样,在使用方法时不论传递什么参数,只要能被程序识别就可以得到确定的结果。参数,只要能被程序识别就可以得到确定的结果。类的多态性体现在方法的重载(类的多态性体现在方法的重载(overload)上,包)上,包括成员方法和构造方法的重载。括成员方法和构造方法的重载。 5.2 类的多态类的多态 方法的重载是指对同名方法的重新定义。方法的重载是指对同名方法的重新定义。例例5.5 对不同的数进行排序输出,运行结果见图对不同的数进行排序

29、输出,运行结果见图5.5。import java.awt.graphics;import java.applet.applet;class intsort public string sort(int a, int b) if (ab) return a+ +b; else return b+ +a; public string sort(int a, int b, int c) int swap;5.2.1 成员方法的重载成员方法的重载 if (ab) swap=a; a=b; b=swap; if (ac) swap=a; a=c; c=swap; if (bc) swap=b; b=c;

30、 c=swap; return a+ +b+ +c; public string sort(int arr) string s= ; int swap; for (int i=0; iarr.length; i+) for (int j=0; jarrj+1) swap=arrj; arrj=arrj+1; arrj+1=swap; for (int i=0; iarr.length; i+) s=s+arri+ ; return s; public class class2 extends applet intsort s=new intsort(); public void paint(g

31、raphics g) int a=30, b=12, c=40; int arr=34,8,12,67,44,98,52,23,16,16; g.drawstring(两个数的排序结果:两个数的排序结果: +s.sort(a,b),30,30); g.drawstring(三个数的排序结果:三个数的排序结果: +s.sort(a,b,c),30,60); g.drawstring(数组的排序结果:数组的排序结果: +s.sort(arr),30,90); 图图 5.5 程序可实现对程序可实现对2个数、个数、3个数和数组的排序。在主类个数和数组的排序。在主类class2中,分别向同一个方法中,分

32、别向同一个方法sort传递传递3种参数,都种参数,都得到了正确的输出。得到了正确的输出。intsort中没有添加成员变量,仅仅提供了中没有添加成员变量,仅仅提供了3个同名个同名方法:方法: public string sort (int a, int b)public string sort (int a, int b, int c)public string sort (int arr)它们的区别在于参数的个数和类型的差别,它们的区别在于参数的个数和类型的差别,java解解释器在运行这个程序时,可以根据参数的不同来调释器在运行这个程序时,可以根据参数的不同来调用不同的方法。用不同的方法。这种

33、多态性使类能够向外提供一个较为一致的接口,这种多态性使类能够向外提供一个较为一致的接口,对程序员来说,不必关心同名方法内部的细节差别,对程序员来说,不必关心同名方法内部的细节差别,只要掌握它们在使用时要求什么参数就可以了。只要掌握它们在使用时要求什么参数就可以了。应该注意到,程序中调用了应该注意到,程序中调用了intsort类的构造方法,类的构造方法,但这个构造方法并没有在但这个构造方法并没有在intsort中出现,它是怎么中出现,它是怎么来的呢?来的呢?每一个类都有一个默认的构造方法,这就是和类同每一个类都有一个默认的构造方法,这就是和类同名的无参构造方法。它实际上是父类的构造方法,名的无参

34、构造方法。它实际上是父类的构造方法,创建子类时由父类自动提供。因此,每个类的对象创建子类时由父类自动提供。因此,每个类的对象都可以使用这种方式来初始化对象。如同为变量声都可以使用这种方式来初始化对象。如同为变量声明数据类型一样,可为对象声明类的类型。如果在明数据类型一样,可为对象声明类的类型。如果在初始化对象时需要对象具有更多的特性,可重载构初始化对象时需要对象具有更多的特性,可重载构造方法。造方法。重载构造方法的目的是提供多种初始化对象的能力,重载构造方法的目的是提供多种初始化对象的能力,使程序员可以根据实际需要选用合适的构造方法来使程序员可以根据实际需要选用合适的构造方法来初始化对象。初始

35、化对象。 5.2.2 构造方法的重载构造方法的重载 例例5.6 构造方法的重载示例,运行结果如图构造方法的重载示例,运行结果如图5.6所示。所示。class rundemo private string username, password; rundemo() system.out.println(all is null!); rundemo(string name) username=name; rundemo(string name, string pwd) this(name); password=pwd; check(); void check() string s=null; if

36、 (username!=null) s=用户名:用户名: +username; else s=用户名不能为空!用户名不能为空!; if (password!=thisword) s=s+ 口令无效!口令无效!; else s=s+ 口令:口令: *; system.out.println(s); public class d1 public static void main(string args) new rundemo(); new rundemo(bill); new rundemo(null,bill); new rundemo(bill,thisword); 图图 5.6 重载构造方

37、法的执行由类根据实际参数的个数、类重载构造方法的执行由类根据实际参数的个数、类型和顺序确定,为程序员提供了较大的灵活性。型和顺序确定,为程序员提供了较大的灵活性。 5-1 什么是类的继承性?子类和父类有什么关系?什么是类的继承性?子类和父类有什么关系?5-2 什么是类的多态性?什么是类的多态性?5-3 何为隐藏、覆盖、重载?何为隐藏、覆盖、重载?5-4 this和和super类有什么作用?类有什么作用?5-5 什么是构造方法?什么是构造方法? 5-6 构造方法有何特点和作用?构造方法有何特点和作用? 习题习题 5-7 分析下面这段程序,指出父类、子类以及它们分析下面这段程序,指出父类、子类以及

38、它们的成员,成员的作用是什么?的成员,成员的作用是什么?class point int x, y; point(int a, int b) setpoint(a,b); public void setpoint(int a, int b) x=a; y=b;class circle extends point int radius; circle(int a, int b, int r) super(a,b); setradius(r); public void setradius(int r) radius=r; public double area() return 3.14159*radius*radius; 5-8 给出下面的不完整的类代码:给出下面的不完整的类代码: class person string name, department; int age; public person(string n) name = n; public person(string n, int a) name = n; age = a; public person(string n, string d, int a) _ department = d; 下面的哪些表达式可以加到构造方法中的下面的哪些表达式可以加到构造方法中的“_”处?(处?(c)a. person(n,a)。

温馨提示

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

评论

0/150

提交评论