




版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
1、1第11章 继承和多态2引言 假设我们将定义类模型的圆,矩形,三角形。这些类都有许多共同的特点。设计这类以避免冗余的最好方法是什么?答案是使用继承。3学习目标u通过继承由父类创建子类(11.2节)。u使用关键字super调用父类的构造方法和方法(11.3节)。u在子类中覆盖方法(11.4节)。u区分覆盖和重载的不同(11.5节)。u探究object类中的tostring()方法(11.6节)。u理解多态性和动态绑定(11.7-11.8节)。u描述转换并解释显示向下转换的必要性(11.9节)。u探究object类中的equeals()方法(11.10节)。u存储,提取和操作ArrayList中的
2、对象(11.11节)。u使用ArrayList实现Stack类(11.12节)。u使用可见性修饰符protected使父类中的数据和方法可以被子类访问(11.13节)。u使用修饰符final防止类的拓展以及方法的覆盖(11.14节)。4父类和子类 GeometricObject -color: String -filled: boolean -dateCreated: java.util.Date +GeometricObject() +GeometricObject(color: String, filled: boolean) +getColor(): String +setColor(c
3、olor: String): void +isFilled(): boolean +setFilled(filled: boolean): void +getDateCreated(): java.util.Date +toString(): String The color of the object (default: white). Indicates whether the object is filled with a color (default: false). The date when the object was created. Creates a GeometricOb
4、ject. Creates a GeometricObject with the specified color and filled values. Returns the color. Sets a new color. Returns the filled property. Sets a new filled property. Returns the dateCreated. Returns a string representation of this object. Circle -radius: double +Circle() +Circle(radius: double)
5、+Circle(radius: double, color: String, filled: boolean) +getRadius(): double +setRadius(radius: double): void +getArea(): double +getPerimeter(): double +getDiameter(): double +printCircle(): void Rectangle -width: double -height: double +Rectangle() +Rectangle(width: double, height: double) +Rectan
6、gle(width: double, height: double color: String, filled: boolean) +getWidth(): double +setWidth(width: double): void +getHeight(): double +setHeight(height: double): void +getArea(): double +getPerimeter(): double 5父类的构造方法被继承吗F 不,构造方法不能被继承。他们是显式或隐式调用。显式调用使用super关键词。F 一个构造方法可用来构建一个类的实例。不像属性和方法,父类的构造方
7、法是不被子类继承的。它们只能在子类的构造方法中用关键字super调用。6构造方法链 构造方法可以调用重载的构造方法或它的父类的构造方法。如果它们都没有被显式的调用,编译器就回自动地将super()作为构造方法的第一条语句,例如: public A(double d) / some statements is equivalent to public A(double d) super(); / some statements public A() is equivalent to public A() super(); 7使用关键字superF调用父类的构造方法。F调用父类的方法。 关键字su
8、per是指使用这个super时的类的父类。关键字super可以用于两种途径:8l 我们必须使用关键字super调用父类的构造函数l 在子类中调用父类的构造函数的名字,将导致一个语法错误l Java要求关键词super必须出现在子类构造方法的第一个行。使用关键字super9构造方法链public class Faculty extends Employee public static void main(String args) new Faculty(); public Faculty() System.out.println(4) Facultys no-arg constructor is
9、 invoked); class Employee extends Person public Employee() this(2) Invoke Employees overloaded constructor); System.out.println(3) Employees no-arg constructor is invoked); public Employee(String s) System.out.println(s); class Person public Person() System.out.println(1) Persons no-arg constructor
10、is invoked); 构建一个类的实例时,将会调用沿着继承链的所有父类的构造方法。这就是构造方法链。10跟踪执行public class Faculty extends Employee public static void main(String args) new Faculty(); public Faculty() System.out.println(4) Facultys no-arg constructor is invoked); class Employee extends Person public Employee() this(2) Invoke Employees
11、 overloaded constructor); System.out.println(3) Employees no-arg constructor is invoked); public Employee(String s) System.out.println(s); class Person public Person() System.out.println(1) Persons no-arg constructor is invoked); 1. 从main方法开始animation11跟踪执行public class Faculty extends Employee publi
12、c static void main(String args) new Faculty(); public Faculty() System.out.println(4) Facultys no-arg constructor is invoked); class Employee extends Person public Employee() this(2) Invoke Employees overloaded constructor); System.out.println(3) Employees no-arg constructor is invoked); public Empl
13、oyee(String s) System.out.println(s); class Person public Person() System.out.println(1) Persons no-arg constructor is invoked); 2. 调用构造方法Facultyanimation12跟踪执行public class Faculty extends Employee public static void main(String args) new Faculty(); public Faculty() System.out.println(4) Facultys no
14、-arg constructor is invoked); class Employee extends Person public Employee() this(2) Invoke Employees overloaded constructor); System.out.println(3) Employees no-arg constructor is invoked); public Employee(String s) System.out.println(s); class Person public Person() System.out.println(1) Persons
15、no-arg constructor is invoked); 3. Invoke Employees no-arg constructoranimation13跟踪执行public class Faculty extends Employee public static void main(String args) new Faculty(); public Faculty() System.out.println(4) Facultys no-arg constructor is invoked); class Employee extends Person public Employee
16、() this(2) Invoke Employees overloaded constructor); System.out.println(3) Employees no-arg constructor is invoked); public Employee(String s) System.out.println(s); class Person public Person() System.out.println(1) Persons no-arg constructor is invoked); 4. Invoke Employee(String) constructoranima
17、tion14跟踪执行public class Faculty extends Employee public static void main(String args) new Faculty(); public Faculty() System.out.println(4) Facultys no-arg constructor is invoked); class Employee extends Person public Employee() this(2) Invoke Employees overloaded constructor); System.out.println(3)
18、Employees no-arg constructor is invoked); public Employee(String s) System.out.println(s); class Person public Person() System.out.println(1) Persons no-arg constructor is invoked); 5. Invoke Person() constructoranimation15跟踪执行public class Faculty extends Employee public static void main(String args
19、) new Faculty(); public Faculty() System.out.println(4) Facultys no-arg constructor is invoked); class Employee extends Person public Employee() this(2) Invoke Employees overloaded constructor); System.out.println(3) Employees no-arg constructor is invoked); public Employee(String s) System.out.prin
20、tln(s); class Person public Person() System.out.println(1) Persons no-arg constructor is invoked); 6. Execute printlnanimation16跟踪执行public class Faculty extends Employee public static void main(String args) new Faculty(); public Faculty() System.out.println(4) Facultys no-arg constructor is invoked)
21、; class Employee extends Person public Employee() this(2) Invoke Employees overloaded constructor); System.out.println(3) Employees no-arg constructor is invoked); public Employee(String s) System.out.println(s); class Person public Person() System.out.println(1) Persons no-arg constructor is invoke
22、d); 7. Execute printlnanimation17跟踪执行public class Faculty extends Employee public static void main(String args) new Faculty(); public Faculty() System.out.println(4) Facultys no-arg constructor is invoked); class Employee extends Person public Employee() this(2) Invoke Employees overloaded construct
23、or); System.out.println(3) Employees no-arg constructor is invoked); public Employee(String s) System.out.println(s); class Person public Person() System.out.println(1) Persons no-arg constructor is invoked); 8. Execute printlnanimation18跟踪执行public class Faculty extends Employee public static void m
24、ain(String args) new Faculty(); public Faculty() System.out.println(4) Facultys no-arg constructor is invoked); class Employee extends Person public Employee() this(2) Invoke Employees overloaded constructor); System.out.println(3) Employees no-arg constructor is invoked); public Employee(String s)
25、System.out.println(s); class Person public Person() System.out.println(1) Persons no-arg constructor is invoked); 9. Execute printlnanimation19例如一个父类没有构造方法public class Apple extends Fruit class Fruit public Fruit(String name) System.out.println(Fruits constructor is invoked); 在下面的程序中找出错误:20声明一个父类F一个
26、类从父类的属性和方法。我们也可以:添加新的属性添加新的方法重写父类的方法21重写父类的方法可以重写Circle类的printCircle()方法:public void printCircle() System.out.println(The circle is created + super.getDateCreated() + and the radius is + radius);22重写父类中的方法 子类从父类继承方法。有时,子类需要修改父类中定义的方法的实现,这称做方法的覆盖覆盖public class Circle extends GeometricObject / Other m
27、ethods are omitted /* Override the toString method defined in GeometricObject */ public String toString() return super.toString() + nradius is + radius; 23注意F 仅当实例方法可以访问时,它才能被覆盖。F 因为私有方法在它的类本身以外是不能访问的,所以它不能被覆盖。F 如果子类中定义的方法在父类中是私有的,那么这两个方法没有关系。24注意F 与实例方法一样,静态方法可以继承。F 然而,静态方法不能被覆盖。F 如果父类中定义的静态方法在子类中重
28、新定义,那么定义在父类中的静态方法将被隐藏。25覆盖和重载 public class Test public static void main(String args) A a = new A(); a.p(10); a.p(10.0); class B public void p(double i) System.out.println(i * 2); class A extends B / This method overrides the method in B public void p(double i) System.out.println(i); public class Tes
29、t public static void main(String args) A a = new A(); a.p(10); a.p(10.0); class B public void p(double i) System.out.println(i * 2); class A extends B / This method overloads the method in B public void p(int i) System.out.println(i); java中,覆盖是指在子类中定义与父类同名且参数类型和个数都相同的方法。故覆盖要求方法头与父类方法完全一致。26对象类object
30、和它的方法在Java的每一类是继承自java.lang.Object类。如果在定义一个类时没有指定继承性,那么这个类的父类被默认是Object。例如: public class Circle . Equivalent public class Circle extends Object . 27Object的toString()方法F调用一个对象的toString()会返回一个描述该对象的字符串。F默认情况下,它返回一个由对象所属的类名,at符号()以及对象十六进制形式的内存地址组成的字符串。Loan loan = new Loan();System.out.println(loan.toSt
31、ring();F这些代码会显示Loan15037e5的字符串。这个信息不是很有用,或者说没有声什么信息量。F通常应该覆盖这个toString()方法,这样,它可以返回一个代表该对象的描述性的字符串。28多态性,动态绑定和泛型编程public class PolymorphismDemo public static void main(String args) m(new GraduateStudent(); m(new Student(); m(new Person(); m(new Object(); public static void m(Object x) System.out.pri
32、ntln(x.toString(); class GraduateStudent extends Student class Student extends Person public String toString() return Student; class Person extends Object public String toString() return Person; 方法m采用object类型的参数。可以用任意对象作为参数来调用m方法。使用父类对象的地方都可以使用子类的对象,这就是通常所说的多态。当执行方法m(object x)时,调用参数x的toString方法。X可能会
33、是GradatueStudent,Student,Person或者Object的实例。类GradatueStudent,Student,Person或者Object都有它们对自己toString方法的实现。使用哪个实现取决于运行x时的实际类型。29动态绑定动态绑定 动态绑定的工作原理如下:假设一个对象实例的类C1,C2,Cn-1,Cn,C1是C2子类,C2是C3的子类,Cn-1是Cn的子类。也就是说,Cn是最通用的类,C1是最特殊的类。在Java中,Cn是Object类。如果对象o调用一个方法P,java虚拟机会依次在类C1,C2,Cn-1,Cn中查找方法p的实现,在这个秩序,直到它被发现。一
34、旦找到,停止查找然后调用这个第一个找到的实现。 Cn Cn-1 . . . . . C2 C1 Object Since o is an instance of C1, o is also an instance of C2, C3, , Cn-1, and Cn 30方法匹配与绑定F匹配的方法签名和绑定方法的实现是两个问题。F编译器在编译的时候根据参数类型、个数、顺序找到一个匹配的方法。F一种方法可以在几个不同的子类中实现。FJava虚拟机在运行时动态绑定方法实现。31转换对象F我们已经使用过转换运算符把一种基本类型变量转换为另一种基本类型。F转换也可以用来把一种类类型的对象转换为继承体系结
35、构中的另一种类类型的对象。 在上一节中,语句:m(new Student();将对象new Student()复制给一个object类型的参数。这条语句等价于:Object o = new Student(); / 隐式转换m(o);所以, Object o = new Student()是合法的,它称为隐式转换32为什么需要转换? 使用下面的语句把对象引用o赋值给Student类型的变量:Student b = o; 将会发生编译错误。 为什么语句Object o = new Student()可以运行,而语句Student b = o;不行呢?原因是Student对象总是Object的实例
36、,但是,Object对象不一定是Student实例。即使可以看到o实际上是一个Student的对象,但是编译器还没有聪明到懂得这一点。为了告诉编译器o就是Student对象,就要使用显式转换。它的语法与基本类型的语法很相似,用圆括号把目标类型的参数括住,然后放到要转换的对象前面,如下所示:Student b = (Student)o; / 显式转换33从父类到子类的转换 当把一个父类的实例转换为它的子类变量时,必须使用转换标记号“(子类名)”进行显式转换,但有时不一定转换成功。Apple x = (Apple)fruit;Orange x = (Orange)fruit;34 instance
37、of 运算符使用运算符instanceof确保对象是另一个对象的实例:Object myObject = new Circle();. / Some lines of code/* Perform casting if myObject is an instance of Circle */if (myObject instanceof Circle) System.out.println(The circle diameter is +(Circle)myObject).getDiameter(); .35小窍门F 为了更好的理解类型转换,可以认为它们类似于水果,苹果,橘子之间的关系。F 其
38、中水果类Fruit是苹果Apple和橘子类Orange的父类,苹果是水果,所以,总可以将Apple的实例安全的赋值给Fruit变量。F 但是,水果不一定是苹果,所以必须进行显式转换才能将Fruit的实例赋值给Apple的变量。36示例:演示多态性与转换程序创建两个几何对象:F 一个圆和一个矩形,调用displayGeometricObject方法显示它们。F 如果对象是一圆displayGeometricObject显示面积和周长。F 如果对象是一个矩形,这个方法显示它的面积。37 equals 方法Fequals方法测试两个对象是否相等,Object类中equals方法的默认实现是:publ
39、ic boolean equals(Object obj) return (this = obj);例如,equals方法在Circle类中重写。public boolean equals(Object o) if (o instanceof Circle) return radius = (Circle)o).radius; else return false; 38注意F = =比较运算符用于比较两个基本数据类型的值是否相等,或用于判断两个对象是否具有相同的引用。F 如果想让equals方法能判断两个对象是否具有相同的内容,可以在定义这些对象的类时,覆盖Circle类中的equals方法。
40、F 运算符= =要比equals方法的功能强大些,因为= =运算符可以检查两个引用变量是否指向同一个对象。39矢量数组线性表ArrayList类 我们可以创建一个数组来存储对象。但是,数组的大小是固定的一次创建数组。Java提供了ArrayList类,可用于存储无限数量的对象。 java.util.ArrayList +ArrayList() +add(o: Object) : void +add(index: int, o: Object) : void +clear(): void +contains(o: Object): boolean +get(index: int) : Objec
41、t +indexOf(o: Object) : int +isEmpty(): boolean +lastIndexOf(o: Object) : int +remove(o: Object): boolean +size(): int +remove(index: int) : Object +set(index: int, o: Object) : Object Appends a new element o at the end of this list. Adds a new element o at the specified index in this list. Removes
42、all the elements from this list. Returns true if this list contains the element o. Returns the element from this list at the specified index. Returns the index of the first matching element in this list. Returns true if this list contains no elements. Returns the index of the last matching element i
43、n this list. Removes the element o from this list. Returns the number of elements in this list. Removes the element at the specified index. Sets the element at the specified index. Creates an empty list. 40编译警告 将产生编译警告 “unchecked operation”。可以忽略它,也可以使用第21章中介绍的泛型类型来消除。41自定义栈类一个存储对象的栈类: MyStack -list: ArrayList +isEmpty(): boolean +getSize(): int +peek(): Object +pop(): Object +push(o: Object): void +search(o: Object): int Returns true if this stack is empty. Returns the number of elements in this stack. Returns the top element in this stack. Returns and remo
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 2024年中国佛教协会和中国佛学院招聘笔试真题
- 包仓库合同范本
- 保温棉合同范本
- 2024年清远市英德市市区学校选调教师考试真题
- 乡下老宅转让合同范本
- 包山正规合同范本
- 《三、应用设计模板》教学设计 -2024-2025学年初中信息技术人教版七年级上册
- 三层楼房施工合同范本
- Unit 8 Lesson 46 教学设计 - 2024-2025学年冀教版英语八年级下册
- 第2单元 单元备课说明2024-2025学年新教材七年级语文上册同步教学设计(统编版2024)河北专版
- 湖南省普通高中毕业生登记表模板
- 人教版七年级上册数学试卷全册
- 中职-中国历史教案
- 六年级小升初语文试卷 [六年级下册语文小升初试卷
- 计量泵的维护和修理知识培训讲义
- 危险化学品从业单位安全生产标准化宣贯
- 幼儿园中班开学第一课
- 招商人员薪酬及提成
- 物业保洁员培训专业课件
- 人教版小学六年级数学下册教材研说
- PPT办公使用技巧培训笔记(共52张)
评论
0/150
提交评论