资源预览内容
第1页 / 共62页
第2页 / 共62页
第3页 / 共62页
第4页 / 共62页
第5页 / 共62页
第6页 / 共62页
第7页 / 共62页
第8页 / 共62页
第9页 / 共62页
第10页 / 共62页
亲,该文档总共62页,到这儿已超出免费预览范围,如果喜欢就下载吧!
资源描述
Java程序设计第七章 继承、接口学习目标 理解继承的含义以及类的层次关系 理解抽象类和具体类的区别 理解多态的含义以及如何实现多态 理解类型系统 理解接口以及实现接口 理解接口和抽象的区别 理解基本的设计模式和实现 掌握Object类,掌握主要方法的作用 理解对象相等性的判断机制 继承是自然界的一种普遍现象。作为面向对象 技术的实现,Java提供了通过继承创建新类来 实现类的重用,在清晰的描述问题域的层次体 系时,继承有着重要的作用。作为系统建模的 一种主要原则,理解继承的关键在于能够认识 抽象的作用。 本质上接口是一种设计模式,它和继承还有着 一定的区别,在开发中它的使用更加频繁。作 为本章的另外一个重要内容,类型的转换机制 也是需要认真领会的。 7.1 类的层次结构 层次是我们生活中经常可 见的一种结构。例如一个 企业通常有着明晰的组织 结构,除了这种组织结构 外,另外一种典型的层次 结构就是分类结构了,例 如有关生物的分类: 在Java语言中,所有的类都有着严格的层次体系 ,除了根类,每个类都有着唯一的超类 7.2 创建现有类的子类从Java编程语言的角度来看,继承发生在一个被称为“ 超类”(或者称为“基类”superclass)与一个被称为“子 类”(subclass)之间,用extends来实现,如: class ChildClass extends SuperClass /. 这里表示子类ChildClass派生于超类SuperClass。准 确的说,我们创建了属于SuperClass类的一个新的子 类型。在发生继承关系时,一个子类对于超类的继承 表现在以下几个方面: l 继承超类的属性 l 继承超类的方法 l 使用超类的构造函数 1.继承超类的属性u一个子类继承超类的属性之后能否使用取决于超 类属性的访问属性以及子类和超类所属包的关系 ,图5-3说明了这个问题。 根据继承规则,如图7-3中显示的那样:u当超类和子类在同一包中时,子类可以继承(既可 以直接使用)超类中除private修饰的一切属性u而当超类和子类不在同一个包内时,子类除了超类 中用private修饰的属性不能继承外,超类中那些 没有明确访问范围的属性也不能被继承。 所以,当明确一个类需要作为基类来使用时,考 虑清楚每一个数据成员的访问范围是很重要的。 2.继承超类的方法 u子类对于超类方法(不包括超类的构造函数)的继 承规则和上述的属性继承规则一样。 u在超类中被说明为private的方法不能被子类继 承使用, u那些没有说明访问范围的方法,只有当子类和超 类在一个包内才可以被继承使用, u除此之外,超类的其它方法都可以被子类继承使 用。 7.2.2 使用super访问超类的构造方法 使用超类的构造方法 u构造方法不同于一般的方法,子类无法使用超类的构造方 法作为自己的构造方法,子类必须有自己的构造方法,但 可以使用父类的构造方法,形式是。super(x,); 调用父类构造方法时应遵循的原则:u只能在子类中调用父类的构造方法,而且必须是第一条语 句,即不要在父类构造方法前放任何子类构造方法代码.u调用父类构造方法时,必须使用super()。u如果父类没有显式声明构造方法,则子类中可以不用调用 父类构造方法,但也可调用父类默认的无参数的构造方法 ,形式如super()一个超类public class Student String studentid; /学生编号String name; /学生姓名String speciality; /专业public Student(String studentid, String name) this.studentid = studentid;this.name = name; /分配专业public void assignSpeciality(String speciality)this.speciality=speciality; /定义该对象的字符串表示public String toString()return studentid+“, “+name+“, “+ speciality; 一个继承于Student的子类public class Postgraduate extends StudentString orientation; /增加了研究方向public Postgraduate(String studentid, String name,Strin g orientation) super(studentid, name); /调用超类Student的构造函数this.orientation = orientation; public void changeOrientation(String nweOrientation)/变更研究方向this.orientation=nweOrientation; public static void main(String args0)Postgraduate student=new Postgraduate(“001“,“Zhang- hua“,“AI“);student.assignSpeciality(“Computer Science“);System.out.println(student); /默认执行超类的toString(), 图5-4形象的说明了在创建一个研 究生对象student时,超类和子类 的关系。在子类的构造函数中的 第一行就是super(studentid, name) 表示这里要调用超类的构造函数 ,读者可以想象为创建一个超类 的对象,然后子类就可以像使用 自己的属性和方法一样使用这个 超类对象的属性和方法,对于子 类对象外部是无法知道这样的区 别的。 如果在子类Postgraduate的构造 函数中没有这么一行,在编译中 是无法通过的。 Implicit super constructor Student() is undefined. Must explicitly invoke another constructor。 这句话翻译过来就是,隐含的超类构造函数 Student()并没有定义,程序必须明确的调用 另一个构造函数。错误的原因是因为子类构造 函数中并没有包括一行调用超类构造函数的语 句,导致无法创建一个属于超类的对象。 Implicit super constructor Student() is undefined. Must explicitly invoke another constructor。 一点提示: u通过程序运行结果和图示关系,可以知道 Postgraduate继承了Student类的所有内容,也就 是说,在Postgraduate类的定义中已经把Student 的所有定义,包括属性、方法都给包含了进来,这 时Postgraduate对象所继承的Student的方法处理 的内容已经完全依赖于当前对象(Postgraduate) 。 u在某种程度上,读者可以理解为Postgraduate对 象体内包含了一个完整的Student对象,但这个 Student类型的对象的属性值则有创建子类对象时 来提供。 继承是面向对象编程的主要优点 总的来说,继承是面向对象编程的一个主要优点之 一,它对如何设计Java类有着直接的影响。继承有 如下几点好处:u它可以利用已有的类来创建自己的类,只需要指出 自己的类和已有的其他的类有什么不同即可,而且还 可以动态访问其他有关的类中的信息。u通过继承,可以利用Java类库所提供的丰富而有用 的类,这些类都已经被很好地实现。u当设计很大的程序时,继承可以使程序组织得更加 层次清晰,有利于程序设计和减少错误的发生。7.2.3 覆盖和隐藏机制-override 图7-4显示,子类总是比超类内容要多一些,这反映 了它们之间的扩展关系,主要体现在两个方面:u子类在继承超类定义的同时,可以添加属于子类特有 的属性、方法和构造函数。u子类在继承超类定义的同时,可以重新修改超类中原 有定义的属性和方法,这种现象称为覆盖-override。 在子类中添加新的属性、方法和构造函数读者应该很 熟悉了,它和前面介绍的有关类的定义没有任何区别 。这里需要重点了解的就是在继承的同时,修改继承 于超类的属性和方法。 1.覆盖超类的方法 u基本上,重写继承超类的方法存在以下主要原因: u超类是抽象的,继承的方法也是抽象的,需要在子类中为 之添加必要的实现代码。 u子类中的方法需要完成额外的工作,如toString()。 u提供更好的实现算法,如子类中的某种数据结构发生了变 化,可以采取更好的算法实现优化。 u覆盖超类的方法变化 u变更方法的可见范围,可以不变、扩大可见范围,不可缩 小。例如某个超类的方法的访问控制修饰符是protected, 而子类中为public。 u方法的返回值类型可以改为原方法返回类型的子类(1.5中 可以覆盖) u无法重新定义Static方法 1.覆盖超类的方法 (续)uJava运行时系统根据调用该方法的实例的类型来 决定调用哪个实现。u需要注意的是,子类覆盖了超类的某些方法,并 不意味着继承于超类的原方法就不存在了,实际 上还存在,通过特殊的方法可以使用(参见 5.2.3),但对于通过子类的对象调用这个同名的 方法时,只能使用新的方法。 2.隐藏数据成员u 开发人员除了可以在子类中重写继承自超类的方法外, 也可以在子类中定义和超类同名的属性,这种情况很少 出现,偶尔也会有这样的事情发生,这可能是由于开发 人员不希望继承自超类的成员变量被访问,或者不希望 修改继承于超类的代码,而重新定义属性的新用途。如 果改变了超类属性的含义及用途,最好的办法是定义新 的属性,避免出现误解。u 当子类中定义了和超类同名的成员变量时,在子类引用 该变量名时,使用的总是子类的定义,来自超类的成员 变量被直接隐藏,至于如何使用继承自超类的成员变量 ,请参考5.2.3有关内容。 使用super访问被覆盖的方法或隐藏数据成员u 在子类中调用超类的构造函数u 在子类中调用被重写的超类方法u 在子类中引用被隐藏的超类属性单继承和多继承 在自然界中,一个子类同时继承多个超类是很常 见的现象,多重继承可以更真实的表达现实,但 是它比较复杂,很容易出现属性冲突、重复继承 的情况,使得开发更加困难,因此,Java语言使 用了单继承,每个类只能有一个超类。 在实际中,不要过度使用继承关系,可以通过复 合使用属性来替代,例如在Student中可以添加 status这样的属性表示一个对象是本科生还是研 究生;创建子类的时候,应该明确子类是超类的 一个类型,而不是为了继承而创建;在创建子类 时,应尽量只添加新的特性,而不要隐藏、重新 解释超类特性 课堂练习 类之间的关系除了聚合和关联外,还有继承,请 用UML符号描述下述类之间的关系。u账户和存款帐户u学生和人u水果和橙子u教师和课程u班级和学生 解释方法覆盖和重载的区别.7.3 Object类、抽象类、final类 7.3.1 根类Object public class Object public Object() public final Class getClass() public int hashCode() public boolean equals(Object obj) protected Object clone() throws CloneNotSupportedException public String toString() public final vo
网站客服QQ:2055934822
金锄头文库版权所有
经营许可证:蜀ICP备13022795号 | 川公网安备 51140202000112号