《Java面向对象编程》PPT课件.ppt_第1页
《Java面向对象编程》PPT课件.ppt_第2页
《Java面向对象编程》PPT课件.ppt_第3页
《Java面向对象编程》PPT课件.ppt_第4页
《Java面向对象编程》PPT课件.ppt_第5页
已阅读5页,还剩101页未读 继续免费阅读

下载本文档

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

文档简介

第3章Java面向对象编程 面向对象的软件开发和相应的面向对象的程序设计方法是当今计算机技术发展的重要成果和趋势之一 Java是一种完全面向对象的程序设计语言 它的所有数据类型和函数都封装在类中 Java所实现的封装 继承 多态性等面向对象的属性 降低了程序的复杂性 实现了代码的可重用性 提高了运行效率 使Java不依赖于机器的结构 具有平台无关性 分布式 可移植性 可重用性 健壮性 安全性等特点 3 1面向对象程序设计基础3 2类与对象3 3成员变量和成员方法的定义与实现3 4类的继承与多态3 5包3 6接口和内部类习题 学习目标 学习目标 了解面向对象编程的基本理论和基本概念 掌握面向对象编程的基本方法 学习后能够编写体现OOP风格的Java程序 本章知识点 类和对象的概念面向对象的特性类变量和类方法的使用封装和修饰符的使用内部类的使用接口的使用包层次的理解和使用 3 1面向对象程序设计基础 3 1 1面向对象概述3 1 2面向对象中的基本概念3 1 3面向对象程序设计方法的优点 3 1 1面向对象概述 早期计算机中运行的程序大都是为特定的硬件系统专门设计的 称为面向机器的程序 这类程序的运行速度和效率都很高 但是可读性和可移植性很差 随着软件开发规模的扩大 这类面向机器的程序逐渐被以C为代表的面向过程的程序所取代 面向过程问题求解的核心组成是数据结构和算法 其中数据结构利用计算机的离散逻辑来量化表达需要解决的问题 而算法则研究如何快捷 高效地组织解决问题的具体过程 面向过程的程序设计是以具体的的解体过程为研究和实现的主体 可以精确 完备地描述具体的求解过程 这里的过程通常是指操作 但却不足以把一个包含了多个相互关联的过程的复杂系统表述清楚 面向对象的程序设计不仅关心孤立的单个过程 还关心包含这些过程的复杂系统 它能够使计算机逻辑来模拟描述系统本身 包括系统的组成 系统的各种可能状态 以及系统中可能产生的各种过程与过程引起的系统状态切换 3 1 2面向对象中的基本概念 1 类与对象对象的概念是面向对象技术的核心所在 实际生活中 我们每时每刻都与 对象 打交道 比如屋顶上的猫 学生用的课桌 老王的彩色电视机等 甚至我们自己本身也是一个对象 我们平时怎样称呼对象呢 我们会以这个对象分类的名称来称呼它 例如城市里有很多猫 大街上有很多车 我要去看电视等等 这里的猫 车 课桌 电视都只是对象的一种分类而已 在Java中 我们称之为类 面向对象技术中另一个重要概念就是类 类是模板也是蓝图 从类中构造一个对象 即创建了一个类的实例 类好比一个建材市场 其中有许多子类 各种各样的装饰材料 而我们装修自己的房子就要选择我们需要的材料 为了建立我们自己的程序 我们必须选择我们需要的类 3 1 2面向对象中的基本概念 对象和类之间是什么关系呢 比如你要买一台电视机 这里的 电视机 只是个类的名称 而你买回家的是电视机的一个实例对象 而不是一个类 所以类是一个抽象的概念 而对象是看得到 听得见 摸得着的实例 在面向对象的程序设计中 将数据与对数据进行的操作合起来定义为类 类是用来定义一组对象共同具有的状态和行为的模板 类 Class 是一种复杂的数据类型 它是将数据和与数据相关的操作封装在一起的集合体 类是普通数据类型的扩展 它不但包含数据 还包含了对数据进行操作的方法 method 方法反映的是数据的行为而不是数据本身 对象 Object 是类的实例 它是类的变量 当程序运行时 对象占用内存单元 对象与类是密切相关的 没有脱离对象的类 也没有不依赖于类的对象 3 1 2面向对象中的基本概念 图3 1表示了类 对象 实体的相互关系和面向对象问题求解的思维方式 使用面向对象的方法解决现实世界的问题时 首先将物理存在的实体抽象成概念世界的抽象数据类型 这个抽象数据类型里面包括了实体中与需要解决的问题相关的数据和属性 然后再用面向对象的工具 如Java语言 将这个抽象数据类型用计算机逻辑表达出来 即构造计算机能够理解和处理的类 最后将类实例化就得到了现实世界实体的面向对象的映射 对象 在程序中对对象进行操作 就可以模拟现实世界中的实体上的问题并解决之 3 1 2面向对象中的基本概念 Java中的所有数据类型都是用类实现的 Java语言是建立在类这个逻辑结构之上的 所以Java是一种完全面向对象的程序设计语言 而我们编写Java程序 主要工作是编写一个个类 然后由类生成对象 实现所需要的功能 图3 1对象 实体与类 3 1 2面向对象中的基本概念 2 成员在Java语言中 一切事物都是对象 实际上 对于每个对象都有一个抽象过程 所谓抽象 就是选取所描述事物在现实世界中相关特征的过程 任何事物一定存在3类信息 属性信息 静态刻画对象特征 操作信息 动态刻画对象特征 约束信息 描述对象可以存在的状态为了使得计算机能够处理客观事物 必须对事物进行抽象 在事物抽象过程中 必须胡略那些抽象事物与当前目的无关的特征 只需要关注与当前需求有直接影响的因素 3 1 2面向对象中的基本概念 例如 人 可以看作一个抽象的类 我们每一个人都是 人 类的一个实例对象 公安机关要了解某一个人的情况 目前所关注的属性有身份证号 姓名 性别 出生日期等 而身高 体重是目前不关心的信息 要尽量去掉 当然以后可以根据需要随时再增加进来 所以有了属性 世界上每个对象都不同 就算是双胞胎 也有不同的地方 每个对象有自己的行为或方法 比如我们可以说 那个人在吃饭 那么吃饭 走路 工作是描述该实例的行为 又比如每台电视都不同 但每台电视一定会有开关机 选台 音量调节等操作的方法 这些都属于操作信息 我们把属性和方法称为这个对象的成员 类中的数据称为成员字段 field 对数据进行的操作称为成员方法 method 注意 字段表示的是类的属性 在Java中其实就是个变量 可以按照一般变量声明的格式进行声明 所以在下文中将字段称为变量 3 1 2面向对象中的基本概念 3 类的三个核心特性 封装 继承 多态 1 封装封装 encapsulation 即信息隐藏 是面向对象程序设计中一个非常重要的概念 封装的目的有 隐藏类的实现细节 以防别人误用 迫使用户通过接口去访问数据 增强代码的可维护性 类封装的概念可以用集成电路芯片作类比 一块集成电路芯片由陶瓷封装起来 其内部电路是不可见的 也是使用者不关心的 芯片的使用者只关心芯片的引脚的个数 引脚的电量参数以及引脚提供的功能 通过这些引脚 硬件工程师对这个芯片有了全面的了解 硬件工程师将不同芯片的引脚连在一起 就可以组成一个具有一定功能的产品 软件工程师通过使用类也可达到这个目的 3 1 2面向对象中的基本概念 2 继承继承是一种由已有类创建新类的机制 为什么要使用继承技术呢 在编写大型应用程序时 如果所定义的类已被使用 应如何增加程序的可维护性 既要保证程序修改后不影响使用 又要能够对程序功能进行不断的补充 有两种传统的解决办法 直接对原代码进行改动 可行 但会对现有使用的其它类造成影响 对原类定义进行复制 对复制的类进行改动 以支持新功能 此方法可行 但也会产生问题 在复制代码的同时 也会复制错误 使得程序的可移植性和重用性差 必然导致工作量的增加 这两种办法并不能最终解决问题 更好的解决办法是使用继承技术 继承机制提供了一种无限重复利用程序资源的途径 通过继承可以扩充旧的程序以适应新的需求 这样不仅节省程序开发时间 而且为未来程序设计增添了新的资源 3 1 2面向对象中的基本概念 3 多态一般来讲 多态就是多种形态的意思 我们已经知道 利用面向对象的语言编程 主要工作是编写一个个类 每一个类中可能有多个成员方法 这些方法各自对应一定的功能 它们之间是不能重名的 否则在用名字调用时 就会产生歧义和错误 但在实际编程过程中 有时却需要利用这样的 重名 现象来提高程序的抽象度和简洁性 这就体现了多态性 所谓多态 是指一个程序中使用相同名字的定义了不同的方法 多态性允许以统一的风格处理已存在的变量及相关的类 多态性使得向系统增加新功能变得容易 继承性和多态性是降低软件复杂性的有效技术 3 1 3面向对象程序设计方法的优点 相对于传统的面向过程的程序设计 面向过程的程序设计更符合人解决问题的思维习惯 它具有如下优点 1 对象的数据封装特性彻底消除了传统结构方法中数据与操作分离所带来的种种问题 提高了程序的可重用性和可维护性 降低了程序员保持数据与操作相容的负担 2 对象的数据封装特性还可以把对象的私有数据和公共数据分离开 保护了私有数据 减少了可能的模块间干扰 达到降低程序复杂性 提高可控制性的目的 3 通过继承和多态 可以很方便地实现应用的扩展和已有代码的重复使用 在保证质量的前提下提高了开发效率 减小软件修改的难度 面向对象编程的难点 掌握面向对象的困难之处在于思路的转换 我们通常习惯于考虑解决问题的方法 而不是考虑将问题抽象成对象再去解决它 3 2类与对象 3 2 1类的声明 类体3 2 2创建对象与构造方法 3 2 1类的声明 类体 修饰符 class类名 extends父类名 implements接口名列表 类成员变量声明 类方法声明 类的声明 修饰符 类名对象名 new类名 实参列表 或 修饰符 类名对象名 对象名 new类名 实参列表 对象的创建和使用 创建对象 对象的引用 引用成员变量对象名 成员变量名引用方法对象名 方法名 参数列表 构造方法和对象的初始化 类中有一种特殊的成员方法 其方法名与类名相同 称为构造方法 当使用new运算符实例化一个对象时 系统为对象创建内存区域并自动调用构造方法初始化成员变量 构造方法的特点 构造方法名与类名相同 构造方法没有返回值 构造方法的主要作用是对对象初始化 构造方法不能显式地直接调用 一个类中可以定义多个构造方法 但各构造方法的参数表不能相同 即各构造方法的参数个数不同或参数类型不同 缺省构造方法 当我们用缺省的构造方法初始化对象时 系统用默认值初始化对象的成员变量 各种数据类型的默认值为 数值型0booleanfalsechar 0 对象null 对象的销毁 通过new运算符实例化对象时 系统为对象分配所需的存储空间 存放其属性值 但内存空间有限 不能存放无限多的对象 为此 Java提供了资源回收机制 自动销毁无用对象 回收其所占用的存储空间 如果需要主动释放对象 或在释放对象时需要执行特定操作 则在类中可以定义finalize 方法 publicvoidfinalize 方法体 数学函数类 Math类库 Java类库中的Math类提供了很多常用数学函数的实现方法 这些方法都是static方法 通过类名Math调用 其调用方式如下 Math 方法名 Math类中的常用方法包括 sin doublex cos doublex log doublex 返回x的自然对数exp doublex 返回exabs doublex 返回x的绝对值max doublex doubley 返回x和y中的较大值sqrt doublex 返回x的平方根random doublex 返回 0 1 区间内的随机数pow doubley doublex 返回yx 3 2 1类的声明 类体 成员变量的声明格式 static final transient 其中 方括号中的项都是可选的 各项的含义如下 static指明变量是一个类成员变量 final指明变量是常量 transient指明变量是临时变量 如 例3 5 方法是完成特定功能的 相对独立的程序段 方法一旦定义 就可以在不同的程序段中多次调用 故方法可以增强程序结构的清晰度 提高编程效率 本章学习方法的声明和调用 3 2 2创建对象与构造方法 类的行为由它的方法实现 其他对象可以调用对象的方法来得到该对象的服务 方法的声明与实现也可分为两部分 方法声明和方法体 成员方法的声明格式 修饰符 参数列表 throws 如 例3 6 说明 方法声明包括方法头和方法体2部分 修饰符可以是公共访问控制符public 私有访问控制符private 保护访问控制符protected等 类型标识符反映方法完成其功能后返回的运算结果的数据类型 方法名要符合标识符的命名规则 不要与Java中的关键字重名 参数表指定在调用该方法时 应该传递的参数的个数和数据类型 对于有返回值的方法 其方法体中至少有一条return语句 方法声明不能嵌套 即不能在方法中再声明其它的方法 4 2方法调用 方法表达式对于有返回值的方法作为表达式或表达式的一部分来调用 其在表达式中出现的形式为 方法名 实际参数表 方法语句方法名 实际参数表 即以独立语句的方式调用方法 4 3参数传递 在调用一个带有形式参数的方法时 必须为方法提供实际参数 完成实际参数与形式参数的结合 称为参数传递 然后用实际参数执行所调用的方法体 在Java中 参数传递是以传值的方式进行 即将实际参数的值传递给形式参数 例 交换两个变量的值 publicclassSwaping staticvoidswap intx inty inttemp System out println BeforeSwapping System out println x x y y temp x x y y temp System out println AfterSwapping System out println x x y y publicstaticvoidmain String args intu 23 v 100 System out println BeforeCalling System out println u u v v swap u v System out println AfterCalling System out println u u v v 3 3 3类的封装 前面我们设计的所有Person类 其中age属性是其他所有类都能直接使用或是修改的 这样的使用方式虽然很直接也很简单 不过有一个很严重的问题 age属性是一个int类型的变量 它的取值范围很大 你可以把它设为 12 也可以把它设为10000 可是世界上没有一个人的年龄为负数 也没有一个人活了10000岁 所以我们必须保护这种属性 防止别人乱用 保护的方式就是把属性隐藏起来 使得其他类只有通过特定的方法才能使用 修改这些属性 在面向对象程序设计中 信息的隐藏就是封装 encapsulation 封装的目的有 隐藏类的实现细节 保护类中的数据不被误用或破坏 迫使用户通过接口去访问数据 增强代码的可维护性 3 3 3类的封装 那么 如何封装呢 根据封装原则 使用者可以访问类中的部分方法 但不能直接访问成员变量 Java中通过设置类的访问权限和类中成员的访问权限 来实现封装的特性 在声明一个类时 可以不用权限修饰符 也可以用public设置类为公有的 不允许使用其他的权限修饰符 对于类中成员的访问权限 Java定义了4种访问权限 公有的 public 保护的 protected 默认 default 的和私有的 private 表3 1说明了每一种权限修饰符允许的访问级别 3 3 3类的封装 表3 1权限修饰符允许的访问级别 3 3 3类的封装 当设置类成员的访问权限时 4种修饰方式的含义如下 公有的 public 说明该类成员可被所有类的对象使用 保护的 protected 说明该类成员能被同一类中的其他成员 或其子类成员 或同一包中的其他类访问 不能被其他包的非子类访问 默认的 default 其实并没有一个叫default的修饰符 如果在声明一个成员时 成员前面没有加上其他三种修饰符 就叫default 它的限制比protected还严格 它使得该类成员能被同一类中的其他成员 或同一包中的其他类访问 但不能被其他包的类访问 私有的 private 说明该类成员只能被同一类中的其他成员访问 不能被其他类的成员访问 也不能被子类成员访问 成员方法和成员变量都是Java类的成员 当声明一个类的成员时 可以使用权限修饰符允许或不允许其他类的对象访问其成员 如 例3 7 3 3 3类的封装 表3 2Java各种类型变量的初值 3 3 4实例成员和类成员 以前我们看到的属性或是方法 都是属于对象等级的 它们是伴随对象的 也就是说只有当对象实例化以后 那些属性和方法才有存在的意义 因此我们称这些属性或方法为实例成员 学校里人很多 为了方便管理 所以我们必须统计出人的总数 有些属性和方法不需要伴随对象 例如学校的总人数 如果我们把它交由上层的类来管理 会比较容易而且效率更高 我们称这种属性或方法为类成员 Java类就包括两种成员 实例成员和类成员 类成员也称为静态成员 使用static修饰的成员称为类成员 3 3 4实例成员和类成员 1 实例变量和类变量类的成员变量有实例变量和类变量两种 没有static修饰的变量称为实例变量 每次创建类的一个实例对象时 系统会为对象的每一个实例变量分配内存单元 用static修饰的变量称为类变量或静态变量 系统运行时 只为该类的第一个对象分配内存单元 其后所有新创建的对象都共享这一个类变量 2 实例方法和类方法类的成员变量有实例方法和类方法两种 没有static修饰的方法称为实例方法 实例方法体中既可以访问类变量 也可以访问实例变量 实例方法只能通过对象来调用 用static修饰的方法称为类方法或静态方法 类方法体中只能访问类变量 类方法既可以通过对象来调用 也可以通过类名调用 如 例3 8 3 3 4实例成员和类成员 注释 许多面向对象语言 如C 要求程序跟踪所以创建的对象 在对象使用完后显式地销毁对象 用这种方式编写管理内存的代码既麻烦有容易出错 而在Java中 程序员只需创建对象 不需要显式地销毁它们 因为Java有垃圾回收机制 能自动判断对象是否在使用 如果不使用 则自动销毁它 收回对象所占的资源 在程序中也可以使用析构方法finalize 随时销毁对象 Java的每个类都有一个析构方法 用于将资源返回给系统 方法finalize 没有参数 也不返回值 3 4类的继承与多态 3 4 1类的继承3 4 2类的多态3 4 3最终类和抽象类 3 4 1类的继承 1 继承的概念根据不同的职业 人可以分为警察 演员等不同的类别 光靠一个Person类来包括各种职业的属性和方法 其结构性是很差的 所以我们必须设计新的类 来管理不同职业的人 所谓继承 inheritance 就是一种由已有类创建新类的机制 利用继承 我们可以先创建一个具有公共属性的一般类 然后根据该一般类再创建具有特殊属性的新类 新类继承一般类的属性和方法 并根据需要增加它自己的属性和方法 由继承而得到的新类称为子类 subclass 被继承的类称为超类 supclass 也被称为父类 3 4 1类的继承 例如 当类sub1继承类super时 就表明sub1是super的子类 super是sub1的超类 如图3 2所示 子类从超类中继承变量和方法 从而可以共享数据和方法 Sub1类由两部分组成 继承部分和增加部分 继承部分是从super继承过来的 把super的成员映射成sub1的继承成员 增加部分是专为sub1编写的新代码 如 例3 9 图3 2继承性 注意 Java不支持多重继承 即子类只能有一个超类 3 4 1类的继承 2 创建子类实现继承在类的声明中 通过使用关键字entends来创建一个类的子类 显式声明格式为 classextends例如 classStudentextendsPerson 3 4 1类的继承 子类继承超类中所有可被子类访问的成员变量 继承原则如下 能够继承声明为public和protected的成员变量 能够继承同一包中的那些默认修饰符的成员变量 不能继承声明为private的成员变量 如果子类声明一个与超类成员变量同名的成员变量 则不能继承超类的成员变量 此时 子类的成员变量称为隐藏了超类的成员变量 子类继承方法的规则类似于继承成员变量的规则 子类继承超类中所有可被子类访问的成员方法 继承原则如下 能够继承声明为public和protected的成员方法 能够继承同一包中的那些默认修饰符的成员方法 不能继承声明为private的成员方法 不能继承超类的构造方法 如果子类方法与超类方法同名 则不能继承 子类方法称为覆盖了超类的同名方法 3 4 1类的继承 注意 Java中每个类都有超类 如果没有显式标明类的超类 则隐含地假设超类为在语言包java lang中说明的Object类 如 例3 10 3 4 1类的继承 归纳注释 继承是软件重用的一种形式 也是自动地实现类中方法和数据共享的机制 如果没有继承机制 那么一个系统中的类是封闭的 相互无关的 多个类实现相似的功能势必造成数据和方法的大量重复 而有了继承机制 多个类就可以相互关联 新类从已存在的类中产生 通过保留它们的属性和方法实现代码重用 又可以根据新类的要求添加新的属性和方法 以支持新功能 在编写大型应用程序时 软件重用可大大缩短软件开发时间 提高系统性能 减少系统在使用过程中出现的问题 3 4 2类的多态 所谓多态 polymorphism 是指一个名字可具有多种语义 即 同名异示 例如 我们经常说 哺乳动物有很多种叫声 描述为 吼 嚎 汪汪 喵喵 等 这就是叫声的多态 如何实现叫声的多态呢 我们写动物类时 写了 叫声 方法 动物类有很多子类 并且这些子类都重写了超类中的 叫声 方法 会产生不同的行为 比如 狗类对象调用 叫声 方法时 产生的行为是 汪汪 而猫类对象调用 叫声 方法时 产生的行为是 喵喵 这就实现了叫声的多态 多态性允许以统一的风格处理已存在的变量及相关的类 多态性使得向系统增加新功能变得容易 继承和多态是降低软件复杂性的有效技术 通常有两种途径实现多态 方法的重载和覆盖 3 4 1类的继承 1 方法的重载所谓方法的重载 methodoverloading 是指一个类中有许多同名的方法带有不同的参数表 方法重载时 要求 参数必须不同 即可以是参数个数不同 也可以是个数相同而类型不同 返回值可以相同 也可以不同 例如 输出语句print的参数可以是Java中的任何基本类型 其实就是对print 方法的重载 publicvoidprint booleanb publicvoidprint charc publicvoidprint inti publicvoidprint longl publicvoidprint floatf publicvoidprint doubled 例3 11构造方法的重载 3 4 1类的继承 归纳注释 重载的价值在于它允许通过使用一个普通的方法名来访问一系列相关的方法 当调用一个方法时 具体执行哪一个方法要根据调用方法的参数决定 Java运行系统仅执行与调用的参数相匹配的重载方法 尽管Java并没有规定重载方法之间必须有联系 但习惯上 为了使程序容易读懂 最好重载相同含义的方法 3 4 1类的继承 2 方法的覆盖在有继承关系的两个类中 如果子类方法与超类方法同名 则该方法不能继承 此时子类的方法称为覆盖 override 了超类中的同名方法 例如 在例3 10中 三个子类Student i Professor i Assistant i类都继承超类Person i 子类中都重写work方法覆盖了超类中的同名方法 各个子类的work方法彼此不同 都实现了与超类不同的行为 特别是在程序中第80行 子类Assistant i中重写work方法覆盖了超类中的同名方法 在89行子类对象a调用的work方法是子类的 所以输出了语句 Talkingwithastudent 而不是超类的work方法中要输出的 Working 所以 方法的覆盖与类的继承有密切的关系 覆盖体现了子类补充或改变超类方法的能力 通过覆盖使一个方法在不同的子类间表现出不同的行为 3 4 1类的继承 在进行覆盖时 应注意以下三点 子类不能覆盖超类中声明为final或static的方法 子类必须覆盖超类中声明为abstract的方法 或者子类也声明为abstract 子类覆盖超类中同名方法时 子类方法声明必须与超类被覆盖方法的声明一样 3 4 3最终类和抽象类 1 最终类最终类是指不能被继承的类 即 最终类不能有子类 如果不希望某个类被继承 可以用关键字final来声明这个类为最终类 例如 finalclassC 合法 C为最终类classLxextendsC 非法 Lx不能为最终类的子类如果想保护类中的方法不被子类覆盖 可以在声明中用关键字final来声明这个方法为最终方法 例如 finalvoidm 合法 m为最终方法2 抽象类为了确保一个方法能被子类的方法覆盖 则使用关键字abstract声明该方法为抽象方法 例如 3 4 3最终类和抽象类 abstractclassD 合法 D为抽象类classLxextendsD 合法 Lx可以为抽象类的子类Dd newD 非法 抽象类不能实例化抽象类的子类必须实现超类中的所以抽象方法 或者将自己也声明为抽象的 一个类不能既是最终类 又是抽象类 即 关键字final和abstract不能合用 当我们定义一个抽象概念时 可以声明一个抽象类只描述其中的结构 而不实现每个方法 这个抽象类可以作为一个超类被它的所有子类所共享 而其中的方法由每个子类去实现具体细节 3 5包 3 5 1包的概念3 5 2引用Java定义的包 3 5 1包的概念 Java允许使用包 package 把类聚集起来 所以包是一种区别类名空间的机制 是类的组织方式 包对应一个文件夹 包中还可以再有子包 称为包等级 为什么要使用包呢 假设有两个程序员不约而同地提供了Student类 只要他们把自己的类放入不同的包中 那么就不会产生冲突 对于其中不同的项目 则使用子包进行区分 包等级的唯一目的是要管理唯一的名字 从编译器的角度来看 包和其中的子包没有任何关系 例如 包java util和java util jar就是彼此无关的 它们每一个都有自己独立的类集合 3 5 2引用Java定义的包 在本书第1章有关Java的API结构的内容中 对Java的常用包作了简单介绍 在此不再赘述 为能使用其他包中的类 或接口 在Java语言中提供了一个包可以使用另一个包中类 或接口 的定义和实现的机制 在一个包中的类共有两种方式定义来自其他包中的类 或接口 1 前缀包名法在每个欲引用的类 或接口 名前简单加上完整的包名 例如 java util Datetoday newjava util Date 显然 这样太繁琐 3 5 2引用Java定义的包 2 使用import关键词在源程序中使用import语句导入Java包中的一个类 或接口 或者包含它们的包 导入一个包后 该包所有的公用类和接口均可使用 import语句的格式为 import 其中import为关键字 多个包名及类名之间用圆点分隔 表示包中的所有类 import语句可以有多个 但必须都在文件顶部package语句后 并且在文件中第一个类或接口定义之前 例如 先有语句importjava util 然后 可以直接使用下面的语句 Datetoday newDate 如果存在名字冲突 必须使用前缀包名法 例如 importjava util importjava sql 其他语句Datetoday newDate 3 5 2引用Java定义的包 该程序在编译时会报错 因为java util包和java sql包中都有Date类 编译器无法确定用哪一个类创建对象today 改为下面的代码就可编译通过 importjava util importjava sql java util Datetoday newjava util Date java sql Dateyesterday newjava sql Date 3 设置包的路径要引用Java包 仅在源码中增加import语句是不够的 还必须告诉系统 程序运行时到哪里才能找到Java的包 这个功能由环境变量classpath完成 在本书第1章JDK的安装过程中已经有关于如何设置环境变量classpath的内容 setclasspath C ProgramFiles Java jdk1 5 0 07 lib如 例3 12 3 5 3自定义包 除了可以引用Java定义的包之外 程序员还可以定义自己的包 1 包的定义格式 1 包的定义格式如下 Package 其中 package是关键字 是标示符 例如 Packageschool PublicclassPerson i 2 包等级的定义格式如下 Package 用圆点 将每个包名分隔就能形成包等级 而包等级中的包名称说明Java类的命名空间的目录层次 例如 Packageschool one two 同时要求one是school的子文件夹 而two是one的子文件夹 要注意的是 如果改变某一个包名 必须同时改变对应的文件夹名 因为包的名字与类存放的文件夹同名 3 5 3自定义包 2 设置包的路径对于程序员自定义的包school 系统如何知道这个包在哪里 其他类如何引用他 我们在D myjava之中创建一个与包同名的文件夹D myjava school 并将编译过的文件 Person i class 放入该文件夹中 注意 该包名与文件夹名应该一致 添加环境变量classpath的路径如下 setclasspath C jdk1 3 0 02 lib D myjava其他类用importschool 语句可以引用school包中的类 程序运行时 系统将在D myjava中寻找school包 JVM在定位一个Java类文件时分为两个步骤 外部定位 根据classpath环境变量定位查找Java类的起始位置 内部定位 根据每个Java类中package关键字所定义层次在Java命名空间中进行再定位 3 5 3自定义包 例3 13包等级的创建及使用 按照下列目录结构 改写例3 9和例3 10中的4个类Person i Student i Professor i Assistant i 把类添加到相应的包中 设计一个信息系学生的新类Is 使之继承Student i类 并在Is中创建包中所有类的对象且调用各个类的move方法 目录结构为 D myjava schoolPerson i javamanagement Assistant i javaAssistant i classstudent Student i javaStudent i classIs javaIs classteacher Professor i javaProfessor i class 3 5 3自定义包 1 设置classpathsetclasspath C ProgramFiles Java jdk1 5 0 lib D myjava 2 修改并编译原有的四个类首先 需要在D myjava中创建三个子文件夹 名字分别为management student teacher 其次 将Person i java拷入文件夹myjava中 然后再将Student i java中的三个类的源代码分开写成三个类文件 将Assistant i java拷入management文件夹中 将Student i java拷入student文件夹中 将Professor i java拷入teacher文件夹中 最后依次改写这四个程序并编译为字节码文件 3 5 3自定义包 Person i java程序改为 packageschool 文件 Person i java说明 Java实用教程 例3 13 publicclassPerson i 类体的代码与例3 9中一样 使用下面的编译命令 可将Person i java编译为Person i class文件 D myjava school javacPerson i java 3 5 3自定义包 Student i java程序改为 packageschool student 把Student i类放入包school的子包student中 文件 Student i java说明 Java实用教程 例3 13 importschool Person i 由于Student i类要继承超类Person i 所以需要先导入该类 子类Student i 继承超类Person ipublicclassStudent iextendsPerson i protectedStringdept 子类变量staticprivateintcount 0 3 5 3自定义包 publicStudent i Stringn inta Stringd super n a dept d setKind Student 调用从超类继承的方法count publicstaticintgetCount returncount publicvoidwork System out println Havingclasses 3 5 3自定义包 使用下面的两种编译命令 都可将Student i java编译为Student i class文件 D myjava school student javacStudent i javaD javacD myjava school student Student i javaAssistant i java程序改为 packageschool management 把Assistant i类放入包school的子包management中 文件 Assistant i java说明 Java实用教程 例3 13 importschool Person i 子类Assistant i 继承超类Person i 3 5 3自定义包 publicclassAssistant iextendsPerson i protectedStringdept staticprivateintcount 0 publicAssistant i Stringn inta Stringd super n a dept d setKind Assistant count publicstaticintgetCount returncount 3 5 3自定义包 publicvoidwork System out println Talkingwithastudent publicvoidsub print super work System out println 子类对象的个数 this count this getCount System out println 超类对象的个数 super count super getCount 如上例所示 使用两种方法 都可将Assistant i java编译为Assistant i class文件 D javacD myjava school management Assistant i java 3 5 3自定义包 Professor i java程序改为 packageschool teacher 把Professor i类放入包school的子包teacher中 文件 Professor i java说明 Java实用教程 例3 13 importschool Person i 子类Professor i 继承超类Person ipublicclassProfessor iextendsPerson i protectedStringdept staticprivateintcount 0 3 5 3自定义包 publicProfessor i Stringn inta Stringd super n a dept d setKind Professor count publicstaticintgetCount returncount publicvoidwork System out println Teaching 3 5 3自定义包 我们使用下面的语句将Professor i java编译为Professor i class文件 D javacD myjava school teacher Professor i java 3 编写信息系学生的新类Is程序代码为 packageschool student 把Is类放入包school的子包student中 文件 Is java说明 Java实用教程 例3 13 由于本类中要调用Person i等四个类 所以需要先导入importschool Person i importschool student 3 5 3自定义包 importschool teacher importschool management 子类Is 继承超类Student ipublicclassIsextendsStudent i staticprivateintcount 0 publicIs Stringn inta super n a 信息系 调用超类的构造方法setKind StudentofInformationDepartment count publicstaticintgetCount returncount 3 5 3自定义包 publicvoidwork System out println Programming publicstaticvoidmain Stringargs 创建school包和其各个子包中的每个类的实例对象Person ip newPerson i Jack 50 p work Student is newStudent i Peter 20 投资系 s work Isi newIs Gates 18 3 5 3自定义包 i work Assistant ia newAssistant i Steven 36 会计系 a work Professor ipr newProfessor i Rose 48 电子系 pr work System out println count Person i getCount 将Is java保存在D myjava school student中 经过编译生成字节码文件Is class 运行程序后 结果如图3 3所示 3 5 3自定义包 图3 3信息系学生类Is的编译与运行 3 5 3自定义包 程序说明 信息系学生的类Is与其超类Student i同时存放在D myjava school student目录中 所以在两个类声明包的代码是一样的 由于要在Is中创建包中所有类的对象 所以在程序的第7行至第10行使用import语句先导入Person i等类 因为各个类的move方法都是用public修饰的 所以都可以调用 Person i getCount 获取的是Person i类的对象的个数 在创建五个类的对象时 由于有继承关系 所以最终都要调用Person i类的构造方法Person i Stringn inta 使得count的值增1 要注意的是 Java编译器使用文件分隔符和 java扩展对文件操作 而Java解释器则使用 分隔符装载类 如图3 3所示 3 5 3自定义包 归纳注释 从这个实例看 把类放入包中 可总结如下的操作步骤 以将公用类Student i放在包school的子包student中为例 1 创建与包结构一致的文件夹D myjava school student 2 为环境变量classpath添加值 setclasspath D myjava 3 在源程序Student i java中 声明Student i类放在包student中 packageschool student importschool Person i publicclassStudent iextendsPerson i声明包的语句放在类的声明前 如果声明的类的超类不在同一包中 必须先使用import语句导入超类 3 5 3自定义包 4 编译类将源程序Student i java编译后生成的Student i class文件拷入D myjava school student文件夹中 5 引用包中的类在其他类中可用import语句引用student包中声明的类Student i importschool student publicclassIsextendsStudent i引用包的语句放在类声明之前 3 5 3自定义包 思考 1 如果在类Is的main 方法体中添加语句System out println p kind 程序能否顺利编译 如果能 运行结果是什么 为什么 若在类Is的main 方法体中又添加语句System out println p name 程序能否顺利编译 为什么 2 若在类Is的main 方法体中添加语句p eat 程序编译时会有什么错误 为什么 如何修改程序使eat 方法中的语句能够输出 3 设计一个的新类School lx 把该类添加到school包中 并在School lx中创建包中除本类外的所有类的实例对象 且所有对象都调用各自类的move方法 3 6接口和内部类 前面的内容 我们已经学习了Java面向对象编程的所有基本工具 在本节 我们简单介绍两种高级技巧 第一项技术叫做接口 interface 用来描述类的功能 而不指明具体的实现方式 一个类可以实现一个或多个接口 只要类实现了接口 就可以在任何需要该接口的地方使用这个类的对象 第一项技术叫做内部类 内部类有些复杂 它们定义在其他类的内部 其方法可以访问外壳类的成员变量 内部类主要用于设计相互协作的类的集合尤其在编写那些除了图形用户界面事件的代码时 使用内部类可以使代码更为简洁和专业 3 6 1接口3 6 2内部类 3 6 1接口 Java不支持多重继承 即一个类只能有一个超类 单继承性使得Java简单 易于管理程序 但在实际应用中 经常需要使用多重继承功能 为了克服单继承的缺点 Java使用了接口 1 接口声明在Java中 接口只含有一些常量和抽象方法 它不是类 而是一组对类的要求 这些类要与接口一致 所以 接口就是一种标准 一些规范 只要大家都使用同一种接口写程序 这些程序之间就很容易互相访问 接口的声明与类的声明相似 格式为 interface extends 声明常量1 声明常量2 方法1 方法2 3 6 1接口 其中 修饰符只有两种情况 public或省略修饰符 定义在接口中的常量全部隐含为final和static 所以不需要自己为常量加final和static修饰符 同时这意味着它们就是类常量 不会被实现接口方法的类改变 这些变量还必须设置初值 接口中的方法都是抽象方法 所以接口可以说是一个完全抽象的类 但一个类中所有的方法都是抽象的 它也不一定是一个接口 因为抽象类中除了抽象方法外 还可能有成员变量 如果接口声明为public 则接口中的方法

温馨提示

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

评论

0/150

提交评论