《深入面向对象的程序设计》由会员分享,可在线阅读,更多相关《深入面向对象的程序设计(59页珍藏版)》请在金锄头文库上搜索。
1、第六章 深入面向对象的程序设计6.1 继承与重载 6.1.1 继承关系的定义 Java中的继承是通过extends关键字来实现的。 新定义的类称为子类,它可以从父类那里继承所 有的非private的属性和方法作为自己的成员。 见例类Employee、CommonEmployee、 ManagerEmployee6.1.2 属性的继承与隐藏1.属性的继承 子类可以继承父类非私有的所有属性。 子类可以自己新建一个属于自己的属性。 子类的全部属性父类继承下来的自己新建的 。 说明: 父类的所有非私有属性实际是各子类都拥有的属 性的集合。 子类从父类继承属性不需要把父类属性的定义部 分再复制一遍。 优
2、点:减少程序的维护量。2.属性的隐藏子类从父类继承来的属性变量重新加以定 义,称为属性的隐藏。 见例6.1 TestHide.java6.1.3 方法的继承、重载和覆盖1.方法的继承 父类的非私有方法作为类的非私有成员, 也可以被子类所继承。 见例6.2 InheritMethod.java2.方法的覆盖在子类中定义与父类相同的方法名称,称为方法 的覆盖。 见例6.3 OverrideMethod.java 注: 在方法的覆盖中,由于同名方法隶属于不同的类 ,所以要解决调用如何区分他们的问题,只需 要在方法名前面使用不同的类名或不同类的对 象名即可。 子类在重新定义父类已有的方法时,应保持与父
3、 类完全相同的方法头声明,即应与父类有完全 相同的方法名、返回值和参数列表。3.方法的重载子类定义同名方法来覆盖父类的方法是面向 对象方法中多态技术的一种实现。 所谓多态是指同名的不同方法共存。有助于 隐藏对象内部的细节,提高程序的抽象程度, 是面向对象程序设计中经常使用的方法。 实现多态技术的另一种重要的手段就是方法的 重载。 重载:类对自身已有的同名方法的重新定义。 重载与覆盖不同,重载不是子类对父类同名方 法的重新定义。方法的重载是同类中同名方法共存的情况 ,不能像方法的覆盖那样采用类名前缀 来区分,而应该采用通过参数列表来区 分不同的方法。 同类中同名的不同方法需要有不同的参数 列表,
4、包括参数顺序的不同和参数类型 的不同。6.1.4 父类对象与子类对象的使用与 转化super 和this是常用来指代父类对象和 子类对象的关键字。 Java系统默认,每个类都缺省地具有 null、this和super三个量,所以在任意 类中都可以不加说明而直接使用它们。 null代表“空”,代表一个什么也没有的“ 空”值,一般用null来代表尚未存在的对 象,在定义一个对象但尚未为其开辟内 存单元时可以指定这个对象为null。1.thisthis表示的是当前对象本身,更准确 地说,this代表了当前对象的一个引用 。 对象的引用可以理解为对象的另一个名 字,通过引用可以顺利地访问到对象, 包括
5、修改对象的属性、调用对象的方法 。this通常用来把当前对象的引用作为参数 传递给其他的对象或方法。如: class SecretaryEmployee extends CommonEmployee /一般雇员的子类:秘书类SecretaryEmployee(ManagerEmployee boss) /秘书的构造函数m_EmpSalary=boss.getSalary()/3; /秘书的薪金是上司的三分之一 /雇员的子类2:主管 class ManagerEmployee extends Employee SecretaryEmployee m_Secretary; /主管的秘书 Manag
6、erEmployee(Date mgrdate) /主管的构造函数 m_Secretary=new SecretaryEmployee(this); /每新任 命一位主管,都为他指派一名秘书 说明:每新建一个ManagerEmployee对象时,都同时创 建一个SecretaryEmployee对象作为其秘书。2.supersuper表示的是当前对象的直接父类对象 ,是当前对象的直接父类对象的引用。 所谓直接父类是相对于当前对象的其他“祖 先”类而言。注意: this和super是属于类的所有特指的属性(即类 的成员),只能用来代表当前对象和当前对象 的父对象,而不能像其他类的属性一样随意引
7、用。下列都是错误的代码: ManagerEmployee MgrEmp=new ManagerEmployee(); MgrEmp.this.getMinSalary();/Error MgrEmp.super.workDays();/Error3.父类对象与子类对象的转换父类对象和子类对象的转化需要注意如下的原则 : 子类对象可以被视为是其父类的一个对象; 父类对象不能被当作是其某一个子类的对象; 如果一个方法的形式参数定义的是父类对象,那 么调用这个方法时,可以使用子类对象作为实 际参数; 如果父类对象引用指向的实际是一个子类对象, 那么这个父类对象的引用可以用强制类型转换 成子类对象的引
8、用。例: class superClass /定义父类int x;. class SubClass extends SuperClass /定义子类int y;char ch;.public class UseSuperSub /使用父类与子类SuperClass sc,sc_ref;SubClass sb,sb_ref;sc=new SuperClass();sb=new SubClass();sc_ref=sb; /父类引用可以指向子类对象sb_ref=(SubClass)sc_ref; /父类引用转换成子 类引用6.1.5 构造函数的继承与重载构造函数是类的一种特殊函数,它也可以从父类
9、那里继承,也可以互相重载。 1.构造函数的重载 构造函数的重载是指同一个类中存在着若干个具 有不同参数列表的构造函数。 当一个类因构造函数的重载而存在着若干个构造 函数时,创建该类对象的语句会自动根据给出 的实际参数的数目、类型和顺序来确定调用哪 个构造函数来完成新对象的初始化工作。当一个构造函数需要调用另一个构造函数时,应 使用关键字this,同时这个调用语句应该是整 个构造函数的第一个可执行语句。如: Employee()m_EmpNo=m_NextEmpNo+; Employee(String name) this();m_EmpName=new String(name); 2.构造函数
10、的继承子类可以继承父类的构造函数,遵循以下的原则 : 1,子类无条件地继承父类的不含参数的构造函 数; 2,如果子类自己定义了构造函数,则它在创建 新对象时,它将先执行继承自父类的无参数构 造函数,然后再执行自己的构造函数; 3,对于父类的含参数构造函数,子类可以通过 在自己构造函数中使用super关键字来调用它 ,但这个调用语句必须是子类构造函数的第一 个可执行语句。在父类已有构造函数的基础上,子类的构造函数 可以有如下的几种设计方法: 1,不专门定义自己的构造函数,每当创建对象 时,系统自动调用父类的无参数构造函数 2,定义自己的构造函数并调用父类的含参数构 造函数,在父类构造函数的初始化
11、操作的基础 上定义子类自己的初始化操作。 3,实现构造函数的重载,满足多层次的对象初 始化需要6.2 包(package)包: 1,把各种类组织在一起,使得程序功能 清楚、结构分明。 2,包是一种松散的类的集合。同一包中 的类之间可以是任意的关系,在缺省情 况下可以互相访问。 3,使用包有利于实现不同程序间类的复 用。1.创建包缺省:系统为每一个.java源文件创建一个 无名包。 (1)该.java文件中定义的所有类都隶属 于这个无名包,它们之间可以相互引用 。 (2)无名包不能被其他包所引用,即无 名包中的类不能被其他包中的类所利用 和复用。创建包的语句需要用关键字package,而且是整个
12、.java 文件的第一个语句。 格式: package 包名; package pkg1.pkg2.pkg3; 例:package EmpClasses;package EmpSystem.EmpClasses;/创建两个子 文件夹 注:实际上,创建包就是在当前文件夹下创建一个子文 件夹,以便存放这个包中包含的所有类的.class文件 。 命令行创建包:Javac d . *.java2.包的引用将类组织成包的目的是为了更好地利用包中的类 。 引用不在同一个包中的其它(非)public类,可以 使用下面几种方法: (1)使用包名、类名前缀 对于同一个包中的其他类,只需在要使用的属性 或方法名前
13、加上类名作为前缀即可; 对于其他包中的类,则需要在类名前缀的前面加 上包名前缀。(2)加载需要使用的类在程序的开始部分利用import语句将需要 使用的整个类加载到当前程序中,这样 在程序中需要引用这个类的地方就不需 要再使用包名作为前缀即可。 可以直接利用import语句引入整个包。 Import java.awt.*;(4)CLASSPATH环境变量CLASSPATH类似于DOS操作系 统中的PATH,它指明了所有缺省的类 字节码文件路径。当一个程序找不到它 所需使用的其他类的.class文件时,系 统会自动到CLASSPATH环境变量所指 明的路径中去寻找。6.3 接口接口在有些资料上被
14、称为界面,英文名称 为interface。 接口与包相似,也是用来组织应用中的各 类并调节它们的相互关系的一种结构。 接口是用来实现类间多重继承功能的结构 。6.3.1 接口的基本概念Java中的接口定义了若干的抽象方法和常 量,形成一个属性集合,该属性集合通 常代表了某一组功能的实现,其主要作 用是可以帮助我们实现类似于类的多重 继承的功能。 多重继承是指一个子类可以有一个以上的 直接父类,该子类可以继承它所有直接 父类的成员。说明: Java中的接口中的属性都是常量,接口中的方 法都是没有方法体的抽象方法。 接口定义的仅仅是实现某一特定功能的一组功能 的对外接口和规范。 接口并没有真正地实
15、现这个功能,这个功能的真 正实现是在“继承”了这个接口的各个类中完成 的,由这些类来具体定义接口中各抽象方法的 方法体。 因此,在Java中,通常把对接口功能的“继承”称 为“实现”。6.3.2 接口的声明Java中声明接口的语法如下: public interface 接口名 extends 父接口名列表 /接口体/常量域声明 publicstaticfinal域类型 域名常量值; /抽象方法声明 publicabstractnative返回值 方法名(参数列 表)throw 异常列表; 接口实际上就是一种特殊的类; 接口是由常量和抽象方法组成的特殊类。 一个类只能有一个父类,但是可以同时实
16、 现若干个接口。 用public修饰的接口是公共接口,可以被 所有的类和接口使用,而没有public修 饰符的接口则只能被同一个包中的其他 类和接口利用。接口也具有继承性。定义一个接口时可以 通过extends关键字声明该新接口是某个 已经存在的父接口的派生接口,它将继 承父接口的所有属性和方法。 一个接口可以有一个以上的父接口,它们 之间用逗号分隔,形成父接口列表。新 接口将继承所有父接口中的属性和方法 。接口体的声明是定义接口的重要部分,接 口体由两部分组成,一部分是对接口中 属性的声明,另一部分是对接口中方法 的声明。 属性都是用final修饰的常量 方法都是用abstract修饰的抽象方法,在 接口中只能给出这些抽象方法的方法名 、返回值和参数列表,而不能定义方法 体。接口中的所有属性都必须是public static final,这是系统默认的规定