第5章 类的继承性与多态性 主要任务: 介绍类的继承性和多态性,以及一些 相关问题。.

Slides:



Advertisements
Similar presentations
网络应用程序设计 2014 JavaBean. JavaBean 及其属性 JavaBean 就是一种 Java 的组件技术 JavaBean 是 Java 类 JavaBean 通过约定的方法名实现属性功能 简单属性 void setXxx(Type value) Type getXxx() boolean.
Advertisements

第五章 类的继承和派生 Inheritance/extends/derive. 教学目标 理解继承的概念和作用 派生类的定义 理解访问修饰符 protected 方法的重写 继承下的构造函数的使用 继承下的 finalize 方法的使用 理解超类和子类的关系.
面向对象程序设计 、. 第二章 面向对象的分析与设计 学习目标 1 确定系统中的对象 2 确定对象的属性及操作 3 测试对象的有效性 4 区分对象和类 5 了解面向对象的编程和过程化编程之间的区别 6 了解封装的主要好处 7 了解软件开发的主要步骤.
第3章 面向对象的编程技术.
第四章 类、对象和接口.
3.2 Java的类 Java 类库的概念 语言规则——程序的书写规范 Java语言 类库——已有的有特定功能的Java程序模块
JAVA 编 程 技 术 主编 贾振华 2010年1月.
Java的面向对象程序设计.
项目6 通用堆栈.
Java程序设计教程 第一讲 Java概述.
四資二甲 第三週作業 物件導向程式設計.
面向对象的程序设计(一).
第一章 面向对象程序设计.
第二章 JAVA语言基础.
類別與物件 Class & Object.
Ch07 介面與多重繼承 物件導向程式設計(II).
第14章 c++中的代码重用.
第10讲 Java面向对象编程基础(4) 教学目标 主要内容.
JAVA程序设计 (03) JAVA Programming
1 Department of Computing.
第六章 JAVA语言中的面向对象特性 6.1 类 6.2 对象 6.3 面向对象的特性 6.4 抽象类、接口和Inner Class.
第四章 Java面向对象程序设计.
第5章 Java中类、对象、接口 及包的概念 5.1 类的基本概念 5.2 类的继承概念 5.3 抽象类和接口 5.4 包.
第5章 面向对象程序设计 本章要点 5.1 面向对象程序设计概述 5.2 Java语言的面向对象程序设计 5.3 方法的使用和对象数组
第四章 在 C# 中实现 OOP 概念.
第六章 类的扩展与继承.
Java 程式設計 講師:FrankLin.
西南科技大学网络教育系列课程 高级语程序设计(Java) 第五章 继承、接口与范型.
Java软件设计基础 5. 继承与多态.
面向对象程序设计 、.
Java程序设计 第9章 继承和多态.
辅导课程六.
绘制圆与多边形 椭圆形 绘制椭圆形的方法是 drawOval(x ,y , width , height), 绘制实心椭圆形的方法是
中国矿大计算机学院杨东平 第5章 接口和包 中国矿大计算机学院杨东平
3.1 数据类型 3.2 标识符与关键字 3.3 常量 3.4 变量 3.5 运算符与表达式 3.6 一个编程实例
第9讲 Java的继承与多态(一) 类的继承 子类的创建 方法覆盖.
第5讲 使用类和对象编程(三) 内部类 实例 程序控制结构 选择语句.
C/C++/Java 哪些值不是头等程序对象
第七章 操作符重载 胡昊 南京大学计算机系软件所.
JAVA 编 程 技 术 主编 贾振华 2010年1月.
C++语言程序设计 C++语言程序设计 第七章 类与对象 第十一组 C++语言程序设计.
第二章 Java基本语法 讲师:复凡.
EBNF与操作语义 请用扩展的 BNF 描述 javascript语言里语句的结构;并用操作语义的方法描述对应的语义规则
$9 泛型基础.
C++复习3 ----类的继承与派生.
C#面向对象程序设计 $6 深入理解类.
C++语言程序设计 C++语言程序设计 第九章 类的特殊成员 第十一组 C++语言程序设计.
Aspect Oriented Programming
Java程式初體驗大綱 大綱 在學程式之前及本書常用名詞解釋 Hello Java!程式 在Dos下編譯、執行程式
Interfaces and Packages
本节内容 类成员的访问控制 视频提供:昆山爱达人信息技术有限公司 官网地址: 联系QQ: QQ交流群 : 联系电话:
第九节 赋值运算符和赋值表达式.
多层循环 Private Sub Command1_Click() Dim i As Integer, j As Integer
C++语言程序设计 C++语言程序设计 第八章 继承 C++语言程序设计.
辅导课程十五.
第二章 Java基本语法 讲师:复凡.
第二章 Java基本语法 讲师:复凡.
方法進階及物件導向基礎 Lecturer: 楊昌樺.
第7章 模板 陈哲 副教授 南京航空航天大学 计算机科学与技术学院.
第6單元 6-1 類別的繼承 (Class Inheritance) 6-2 抽象類別 (Abstract Class)
辅导课程十二.
C++语言程序设计 C++语言程序设计 第九章 类的特殊成员 第十一组 C++语言程序设计.
C++语言程序设计 C++语言程序设计 第九章 类的特殊成员 第十一组 C++语言程序设计.
JAVA 程式設計與資料結構 第三章 物件的設計.
第2章 Java语言基础.
创建、启动和关闭Activity 本讲大纲: 1、创建Activity 2、配置Activity 3、启动和关闭Activity
使用Fragment 本讲大纲: 1、创建Fragment 2、在Activity中添加Fragment
第二章 Java基础语法 北京传智播客教育
第6章 继承和多态 伍孝金
Summary
Presentation transcript:

第5章 类的继承性与多态性 主要任务: 介绍类的继承性和多态性,以及一些 相关问题。

本章主要内容 1.类的继承 2.类的多态

5.1 类的继承 什么是类的继承? 新类可从现有的类中产生,将保留现有类的状态属性和方法并可根据需要加以修改。新类还可添加新的状态属性和方法,这些新增功能允许以统一的风格处理不同类型的数据。这种现象就称为类的继承。

5.1.1 父类和子类 当建立一个新类时,不必写出全部成员变量和成员方法。只要简单地声明这个类是从一个已定义的类继承下来的,就可以引用被继承类的全部成员。被继承的类称为父类或超类(superclass),这个新类称为子类。

在类的声明语句中加入extends关键字和指定的类名即可实现类的继承,例如: public class MyApplet extends java.applet.Applet public class MyApplication extends Frame public class MyApp1 extends Object public class MyApp2 第一条语句声明子类MyApplet的父类是Applet,并指明Applet的层次结构;第二条语句声明子类MyApplication的父类是Frame;第三条语句声明子类MyApp1的父类是Object,但编程中通常会省略extends Object子句;第四条语句在字面上没有extends,但实际上等价于public class MyApp2 extends Object。

类的继承的模拟图

图反映了什么? 图5.1反映了Java类的层次结构。最顶端的类是Object,它在java.lang中定义,是所有类的始祖。一个类可以有多个子类,也可以没有子类,但它必定有一个父类(Object除外)。 子类不能继承父类中的private成员,除此之外,其它所有的成员都可以通过继承变为子类的成员。另一方面,对继承的理解应该扩展到整个父类的分支,也就是说,子类继承的成员实际上是整个父系的所有成员。例如,toString这个方法是在Object中声明的,被层层继承了下来,用于输出当前对象的基本信息。

结论: 子类只能有一个父类。如果省略了extends,子类的父类是Object。子类继承了父类和祖先的成员,可以使用这些成员。在需要的时候,子类可以添加新的成员变量和方法,也可以隐藏父类的成员变量或覆盖父类的成员方法。

5.1.2 成员变量的继承和隐藏 1.成员变量的继承 2.成员变量的隐藏

Point(int a, int b) {setPoint(a, b);} 例5.1 下面的三个程序说明从点Point类扩展到线Line类和圆Circle类的方法,这是三个公共类,不能放在同一个文件中。它们都没有输出语句,如果运行看不到什么结果。 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; } public int getX() {return x;} 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() {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(r); } public void setRadius(int r) {radius=r;} public int getRadius() {return radius;} public double area() {return 3.14159*radius*radius;}

Point 的成员 x, y // 受保护的成员变量,代表点的坐标 Point // 点的构造方法 setPoint // 设定点的坐标值的方法 getX, getY // 返回坐标x和y的值的方法

x, y, endX, endY // 子类受保护的成员变量,代表线的两个端点坐标 x, y // 继承父类的受保护成员变 量,但被子类隐藏 Line 的成员 x, y, endX, endY // 子类受保护的成员变量,代表线的两个端点坐标 Line // 线的构造方法 setLine // 设定线的两个端点坐标值的方法 getX, getY // 返回起点坐标x和y的值的方法 getEndX, getEndY // 返回终点坐标endX和endY的值的方法 length // 返回线的长度的方法 x, y // 继承父类的受保护成员变 量,但被子类隐藏 setPoint // 继承父类的方法 getX, getY // 继承父类的方法,但被子类覆盖

radius // 子类受保护的成员变量,代表圆的半径 Circle 的成员 radius // 子类受保护的成员变量,代表圆的半径 Circle // 圆的构造方法 setRadius // 设定半径值的方法 getRadius // 返回半径值的方法 area // 返回圆面积的方法 x, y // 继承父类的受保护成员变量 setPoint // 继承父类的方法 getX, getY // 继承父类的方法

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

5.1.3 成员方法的覆盖 已知通过继承子类可以继承父类中所有可以被子类访问的成员方法,但如果子类的方法与父类方法同名,则不能继承,此时称子类的方法覆盖了父类的那个方法,简称为方法覆盖。方法的覆盖(override),为子类提供了修改父类成员方法的能力。例如,子类可以修改层层继承下来的toString方法,让它输出一些更有用的信息。下面的例子显示了在子类Circle中添加toString方法,用来返回圆半径和圆面积信息。

例5.2 对Object的toString方法的覆盖。结果如图所示。

class Circle { private int radius; Circle(int r) {setRadius(r);} public void 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()); } 程序中改写了上一节介绍的Circle,添加了toString方法并修改了它的返回值。由于toString和继承下来的方法名相同、返回值类型相同,因此就覆盖了父类中的toString方法。而父类Point中的toString方法尽管没有显示出来,它仍然存在,它是从Object中继承下来的。

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

5.1.4 this和super 例5.3 this和super的使用。运行结果如图所示。

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; }

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;

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[]) { Line line=new Line(50, 50); System.out.println("\n"+line.toString()); }

this和super 的作用: (1)this实际代表的是当前类或对象本身。 在一个类中,this表示对当前类的引用,在使用类的成员时隐含着this引用,尽管可以不明确地写出,例如length和toString中对x和y的使用。当一个类被实例化为一个对象时,this就是对象名的另一种表示。通过this可顺利地访问对象,凡在需要使用对象名的地方均可用this代替。

(2)super代表着父类 如果子类的变量隐藏了父类的变量,使用不加引用的变量一定是子类的变量,如果使用父类的变量,就必须加上super引用。同样道理,如果有方法覆盖的发生,调用父类的方法时也必须加上super引用。

例5.4 了解下面两个类中super的使用。运行结果如图所示。

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

5.2 类的多态 类的继承发生在多个类之间,而类的多态只发生在同一个类上。在一个类中,可以定义多个同名的方法,只要确定它们的参数个数和类型不同。这种现象称为类的多态。 多态使程序简洁,为程序员带来很大便利。在OOP中,当程序要实现多个相近的功能时,就给相应的方法起一个共同的名字,用不同的参数代表不同的功能。这样,在使用方法时不论传递什么参数,只要能被程序识别就可以得到确定的结果。 类的多态性体现在方法的重载(overload)上,包括成员方法和构造方法的重载。

5.2.1 成员方法的重载 方法的重载是指对同名方法的不同使用方式。 看下面这个例子。

例5.5 对不同的数进行排序输出,运行结果见图。 例5.5 对不同的数进行排序输出,运行结果见图。

import java.awt.Graphics; import java.applet.Applet; class IntSort { public String sort(int a, int b) { if (a>b) return a+" "+b; else return b+" "+a; }

public String sort(int a, int b, int c) { int swap; if (a<b) { swap=a; a=b; b=swap; } if (a<c) { a=c; c=swap;

if (b<c) { swap=b; b=c; c=swap; } return a+" "+b+" "+c; public String sort(int arr[]) { String s=" "; int swap;

for (int i=0; i<arr.length; i++) for (int j=0; j<arr.length-1; j++) if (arr[j]>arr[j+1]) { swap=arr[j]; arr[j]=arr[j+1]; arr[j+1]=swap; } s=s+arr[i]+" "; return s;

public class Class2 extends Applet { IntSort s=new IntSort(); public void paint(Graphics 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); }

程序中调用了IntSort类的构造方法,但这个构造方法并没有在IntSort中出现,它是怎么来的呢? 每一个类都有一个缺省的构造方法,这就是和类同名的无参构造方法。它实际上是父类的构造方法,创建子类时由父类自动提供。因此,每个类的对象都可以使用这种方式来初始化对象。如同为变量声明数据类型一样,可为对象声明类的类型。如果在初始化对象时需要对象具有更多的特性,可重载构造方法。

5.2.2 构造方法的重载 重载构造方法的目的: 提供多种初始化对象的能力,使程序员可以根据实际需要选用合适的构造方法来初始化对象。

例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 (userName!=null) s="用户名:"+userName; else s="用户名不能为空!"; if (password!="ThisWord") s=s+" 口令无效!"; 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"); }

习 题 1.什么是类的继承性?子类和父类有什 么关系? 2.什么是类的多态性? 3.何为隐藏、覆盖、重载? 习 题 1.什么是类的继承性?子类和父类有什 么关系? 2.什么是类的多态性? 3.何为隐藏、覆盖、重载? 4.this和super类有什么作用? 5.什么是构造方法? 6.构造方法有何特点和作用?

7.分析下面这段程序,指出父类、子类以及它们的成员,成员的作用是什么? 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;}

8.给出下面的代码: class Person { String name,department;       public void printValue(){          System.out.println("name is "+name);          System.out.println("department is "+department);       }    }    public class Teacher extends Person {       int salary;          ————————          System.out.println("salary is "+salary); 下面的哪些表达式可以加入到Teacher类的 printValue()方法中?为什么?(D) A. printValue(); B. this.printValue(); C. person.printValue(); D. super.printValue().

9.创建一个Fraction类执行分数运算。要求如下: ⑴ 用整型数表示类的private成员变量:f1和f2。 ⑵ 提供构造方法,将分子存入f1,分母存入f2。 ⑶ 提供两个分数相加的运算方法,结果分别存入f1和f2。 ⑷ 提供两个分数相减的运算方法,结果分别存入f1和f2。 ⑸ 提供两个分数相乘的运算方法,结果分别存入f1和f2。 ⑹ 提供两个分数相除的运算方法,结果分别存入f1和f2。 ⑺ 以a/b的形式打印Fraction数。 ⑻ 以浮点数的形式打印Fraction数。 ⑼ 编写主控程序运行分数运算。