目录
第1章 成为程序员 1.1 选择编程语言 1.2 告诉计算机做什么 1.3 程序的工作原理 1.4 为什么程序不能正常工作 1.5 选择 Java编程工具 1.6 安装 Java开发工具 1.7 总结 1.8 问与答 1.9 测验 1.9.1 问题 1.9.2 答案 1.10 练习 第2章 编写第一个程序 2.1 编写程序所需的工具 2.2 创建 Saluton 程序 2.3 开始输入程序 2.3.1 class语句 2.3.2 main语句的作用 2.3.3 大括号 2.4 在变量中存储信息 2.5 保存编写好的程序 2.6 将程序编译为 class文件 2.7 修复错误 2.8 运行 Java程序 2.9 总结 2.10 问与答 2.11 测验 2.11.1 问题 2.11.2 答案 2.12 练习 第3章 Java之旅 3.1 第一站:Oracle 3.2 去 Java学校 3.3 在 JavaWorld 用午餐 3.4 在 NASA仰望天穹 3.5 回归正题 3.6 到 Java Boutique 去问路 3.7 在手机上运行 Java 3.8 总结 3.9 问与答 3.10 测验 3.10.1 问题 3.10.2 答案 3.11 练习 第4章 理解Java程序的工作原理 4.1 创建应用程序 4.2 向应用程序传递参数 4.3 创建 applet 4.4 总结 4.5 问与答 4.6 测验 4.6.1 问题 4.6.2 答案 4.7 练习 第5章 在程序中存储和修改信息 5.1 语句和表达式 5.2 指定变量类型 5.2.1 整数和浮点数 5.2.2 字符和字符串 5.2.3 其他数值类型的变量 5.2.4 布尔型变量 5.3 给变量命名 5.4 在变量中存储信息 5.5 运算符 5.5.1 变量的递增与递减 5.5.2 运算符优先级 5.6 使用表达式 5.7 总结 5.8 问与答 5.9 测验 5.9.1 问题 5.9.2 答案 5.10 练习 第6章 使用字符串来交流 6.1 在字符串中存储文本 6.2 在程序中显示字符串 6.3 在字符串中使用特殊字符 6.4 拼接字符串 6.5 将其他变量用于字符串中 6.6 字符串的高级处理 6.6.1 比较两个字符串 6.6.2 确定字符串的长度 6.6.3 改变字符串的大小写 6.6.4 查找字符串 6.7 导演及演员名单 6.8 总结 6.9 问与答 6.10 测验 6.10.1 问题 6.10.2 答案 6.11 练习 第7章 使用条件测试进行判断 7.1 if语句 7.1.1 小于和大于的比较 7.1.2 相等和不等 7.1.3 使用块语句组织程序 7.2 if-else 语句 7.3 switch语句 7.4 条件运算符 7.5 观察时钟 7.6 总结 7.7 问与答 7.8 测验 7.8.1 问题 7.8.2 答案 7.9 练习 第8章 使用循环重复执行操作 8.1 for循环 8.2 while 循环 8.3 do-while 循环 8.4 退出循环 8.5 给循环命名 8.6 测试计算机的运行速度 8.7 总结 8.8 问与答 8.9 测验 8.9.1 问题 8.9.2 答案 8.10 练习 第9章 使用数组存储信息 9.1 创建数组 9.2 使用数组 9.3 多维数组 9.4 对数组进行排序 9.5 对字符串中的字符计数 9.6 总结 9.7 问与答 9.8 测验 9.8.1 问题 9.8.2 答案 9.9 练习 第10章 创建第一个对象 10.1 面向对象编程的工作原理 10.2 对象示例 10.3 什么是对象 10.4 理解继承 10.5 建立继承层次 10.6 转换对象和简单变量 10.6.1 简单变量的类型转换 10.6.2 对象类型转换 10.6.3 在简单变量和对象之间进行转换 10.6.4 自动封装和拆封 10.7 创建对象 10.8 总结 10.9 问与答 10.10 测验 10.10.1 问题 10.10.2 答案 10.11 练习 第11章 描述对象 11.1 创建变量 11.2 创建类变量 11.3 用方法来创建行为 11.3.1 声明方法 11.3.2 参数不同的类似方法 11.3.3 构造函数 11.3.4 类方法 11.3.5 方法中变量的作用域 11.4 将一个类放在另一个类中 11.5 使用关键字this 11.6 使用类方法和类变量 11.7 总结 11.8 问与答 11.9 测验 11.9.1 问题 11.9.2 答案 11.10 练习 第12章 充分利用现有对象 12.1 继承的威力 12.1.1 继承行为和属性 12.1.2 覆盖方法 12.2 建立继承 12.3 使用现有的对象 12.4 将相同类型的对象存储到 Vector 中 12.5 创建子类 12.6 总结 12.7 问与答 12.8 测验 12.8.1 问题 12.8.2 答案 12.9 练习 第13章 创建简单的用户界面 13.1 Swing 和抽象窗口工具包 13.2 使用组件 13.2.1 窗口和框架 13.2.2 按钮 13.2.3 标签和文本框 13.2.4 复选框 13.2.5 组合框 13.2.6 文本区域 13.2.7 面板 13.3 创建自己的组件 13.4 总结 13.5 问与答 13.6 测验 13.6.1 问题 13.6.2 答案 13.7 练习 第14章 用户界面的布局 14.1 使用布局管理器 14.1.1 GridLayout管理器 14.1.2 BorderLayout管理器 14.1.3 BoxLayout管理器 14.1.4 使用Insets将组件隔开 14.2 应用程序的界面布局 14.3 总结 14.4 问与答 14.5 测验 14.5.1 问题 14.5.2 答案 14.6 练习 第15章 响应用户输入 15.1 让程序监听 15.2 设置要监听的组件 15.3 处理用户事件 15.3.1 复选框和组合框事件 15.3.2 键盘事件 15.3.3 启用和禁用组件 15.4 完善图形应用程序 15.5 总结 15.6 问与答 15.7 测验 15.7.1 问题 15.7.2 答案 15.8 练习 第16章 创建复杂的用户界面 16.1 滚动窗格 16.2 滑块 16.3 变更监听器 16.4 使用图像图标和工具栏 16.5 总结 16.6 问与答 16.7 测验 16.7.1 问题 16.7.2 答案 16.8 练习 第17章 创建交互式Web程序 17.1 标准applet方法 17.1.1 在applet窗口中绘画 17.1.2 初始化applet 17.1.3 启动和停止applet 17.1.4 销毁applet 17.2 将applet放到Web页面中 17.3 创建applet 17.3.1 在applet窗口中绘画 17.3.2 测试SalutonApplet程序 17.4 从Web页面传递参数 17.5 在applet中接收参数 17.6 在applet中处理参数 17.7 使用object标记 17.8 总结 17.9 问与答 17.10 测验 17.10.1 问题 17.10.2 答案 17.11 练习 第18章 处理程序中的错误 18.1 异常 18.1.1 在try-catch块中捕获异常 18.1.2 捕获多种不同的异常 18.1.3 出现异常后进行处理 18.1.4 抛出异常 18.1.5 忽略异常 18.2 抛出和捕获异常 18.3 总结 18.4 问与答 18.5 测验 18.5.1 问题 18.5.2 答案 18.6 练习 第19章 创建线程程序 19.1 线程 19.1.1 降低程序的速度 19.1.2 创建线程 19.2 使用线程 19.2.1 声明类 19.2.2 创建变量 19.3 从init( )开始 19.4 在创建URL时捕获错误 19.5 在paint( )方法中处理屏幕更新 19.6 启动线程 19.6.1 运行线程 19.6.2 停止线程 19.7 处理鼠标单击 19.8 循环显示链接 19.9 总结 19.10 问与答 19.11 测验 19.11.1 问题 19.11.2 答案 19.12 练习 第20章 读写文件 20.1 流 20.1.1 文件 20.1.2 从流中读取数据 20.1.3 缓冲输入流 20.2 将数据写入流中 20.3 读写配置属性 20.4 总结 20.5 问与答 20.6 测验 20.6.1 问题 20.6.2 答案 20.7 练习 第21章 读写XML数据 21.1 创建XML文件 21.2 读取XML文件 21.3 读取 RSS 聚合内容(Syndication Feeds) 21.4 总结 21.5 问与答 21.6 测验 21.6.1 问题 21.6.2 答案 21.7 练习 第22章 利用JAX-WS开发Web服务 22.1 定义服务端点接口 使用注解来简化Java代码 22.2 创建服务实现Bean 22.3 发布Web服务 22.4 使用Web服务描述语言文件 22.5 创建Web服务客户端 22.6 总结 22.7 问与答 22.8 测验 22.8.1 问题 22.8.2 答案 22.9 练习 第23章 创建Java2D图形 23.1 使用Font类 23.2 使用Color类 23.3 创建自定义颜色 23.4 绘制直线和形状 23.4.1 绘制直线 23.4.2 绘制矩形 23.4.3 绘制椭圆和圆 23.4.4 绘制弧线 23.5 绘制饼图 23.6 总结 23.7 问与答 23.8 测验 23.8.1 问题 23.8.2 答案 23.9 练习 第24章 编写Android app 24.1 Android简介 24.2 创建 Android app 24.2.1 剖析一个Android新项目 24.2.2 创建app 24.2.3 安装Android模拟器 24.2.4 创建调试配置 24.3 运行app 24.4 设计真实的app 24.4.1 组织资源 24.4.2 配置app的Manifest文件 24.4.3 设计用户界面 24.4.4 编写Java代码 24.5 总结 24.6 问与答 24.7 测验 24.7.1 问题 24.7.2 答案 24.8 练习 附录A 使用NetBeans IDE A.1 安装NetBeans A.2 创建新项目 A.3 创建新的Java类 A.4 运行应用程序 A.5 修复错误 附录B Java资源 B.1 可以考虑的其他书 B.2 Oracle公司的 Java官方站点 B.3 其他Java站点 B.3.1 本书英文版的配套网站 B.3.2 Café au Lait B.3.3 Workbench B.3.4 Java 7 Developer Blog B.3.5 其他Java博客 B.3.6 InformIT B.3.7 Stack Overflow B.3.8 Java Review Service B.3.9 JavaWorld杂志 B.3.10 Developer.com’s Java Directory 附录C 本书站点 附录D 设置Android开发环境 D.1 起步 D.2 安装Eclipse D.3 安装 Android SDK D.4 安装在Eclipse中使用的Android插件 D.5 设置你的手机 其他 版权

Java初级教程

Java入门经典
第12章 充分利用现有对象

本章介绍如下内容:

超类和子类的设计;

建立继承层次;

覆盖方法。

Java 对象非常适合繁殖。当创建了一个对象(一组属性和行为)时,实际上你设计了可遗传给后代的品质。这些子对象将继承父对象的属性和行为,而且它们还可以添加父对象没有的属性和行为。

这种规律称为继承,也就是超类(父母)遗传给子类(孩子)。继承是面向对象编程最有用的方面,本章将详细介绍它。

面向对象编程的另一个有用的方面是能够创建可在不同程序中使用的对象。可重用性使得开发没有错误的可靠程序更加容易。

12.1 继承的威力

每当读者使用标准Java类(如String或Integer)时,你使用的就是继承。Java类被组织成金字塔型的类层次结构,其中所有的类都是从Object类派生而来的。

类继承其上面所有的超类。要了解其中的原理,来看看JApplet类。这个类是所有applet的超类,后者是使用图形用户界面框架(称之为 Swing)而且基于浏览器的 Java 程序。JApplet是Applet的子类。

图 12.1 显示了 JApplet 的部分家谱,其中每个方块都是一个类,超类与其下面的子类用直线连接。

最顶端是Object类。在继承层次结构中,JApplet有5个超类:Applet、Panel、Container、Component、Object。

图12.1 Applet类的家谱

JApplet从这些类继承属性和行为,因为在继承层次结构中,它们都在JApplet的正上方。JApplet不继承图12.1中用阴影标识的5个类,包括Dialog和Frame,因为在继承层次结构中,它们不在JApplet的上方。

如果感到迷惑,可将层次结构视为家谱。JApplet继承父亲、祖父,不断向上直到太祖父Object类。然而,JApplet不会从兄弟或堂兄那里继承。

创建一个新的类可以归结为执行如下任务:你指需要定义其不同于现有类的地方即可,其他工作都已经为你做好。

12.1.1 继承行为和属性

类的行为和属性由两部分组成:自己的行为和属性以及从超类继承的行为和属性。

下面是Applet的一些行为和属性:

equals( )方法确定 JApplet 对象的值是否与另一个对象相同;

setBackground( )方法设置 applet 窗口的背景颜色;

add( )方法给applet 添加用户界面组件,如按钮和文本框等;

setLayout( )方法定义如何组织 applet 的图形用户界面。

JApplet 类可以使用所有这些方法,即使 setLayout( )方法不是从其他类继承来的。equals( )方法是在 Object 类中定义的,setBackground( )方法来自 Component 类,而 add( )方法来自Container类。

12.1.2 覆盖方法

在 JApplet 类中定义的有些方法也在其超类中定义了,例如,update( )方法在 JApplet 和Component 类中都有定义。当方法在子类和超类中都定义了时,将使用子类中的定义;因此子类可以修改、替换或完全删除超类的行为和属性。就 update( )方法而言,它旨在删除超类中的一些行为。

在子类中创建新方法以修改从超类继承来的行为被称为“覆盖”(overriding)方法。如果继承的行为不能获得所需的结果,则需要覆盖相应的方法。

12.2 建立继承

使用关键字extends将一个类指定为另一个类的子类,如下所示:

上述语句创建AnimatedLogo类,并将其指定为JApplet的子类。读者在第17章将会看到,所有的 Swing applet 都必须是 JApplet 的子类,因为在 Web 页面中运行时,它们需要这个类提供的功能。

AnimatedLogo 必须覆盖方法 paint( ),该方法用于绘制要在程序窗口中显示的所有内容。paint( )方法是由 Component 类实现的,并向下传递给 AnimatedLogo 类,但 paint( )不做任何事情,Component类提供该方法旨在让其子类需要显示内容时可使用它。

要覆盖该方法,必须以与超类相同的方式声明它,即public方法仍必须是public的,方法的返回值类型必须相同,且参数的数量和类型都不能变。

在 Component 类中,paint( )方法的声明如下:

在AnimatedLogo中覆盖该方法时,也使用类似于下面的语句:

唯一的差别是Graphics对象的名称,这对于判断创建方法的方式是否相同没有影响。这两个语句是相同的,因为下面几项相同:

两个 paint( )方法都是 public 的;

两个方法都没有返回值,因为声明时使用了关键字void;

都接受Graphics对象作为唯一的参数。

在子类中使用this和super

在子类中this和super是两个很有用的关键字。

前一章讲到,关键字this用于引用当前对象。创建类时,要引用根据该类创建的特定对象,可使用this,如下面的语句所示:

这条语句将对象的title变量设置为文本Cagney。

关键字super的用途与此类似:引用对象的上一级超类。可以下面几种方式使用super:

引用超类的构造函数,如 super("Adam", 12);

引用超类的变量,如 super.hawaii = 50;

引用超类的方法,如 super.dragnet( )。

使用关键字 super 的方式之一是在子类的构造函数中。子类从其超类继承所有的行为和属性,因此将子类的构造函数与超类的构造函数关联起来,否则有些行为和属性可能不能正确设置,导致子类不能正常工作。

为此,在子类的构造函数中,第一条语句必须调用超类的构造函数,因此需要使用关键字super,如下面的语句所示:

这是子类的构造函数,它使用 super(name, length)调用超类相应的构造函数。

如果不使用super来调用超类的构造函数,则在子类构造函数执行时,Java将自动调用无参数的超类构造函数。如果该超类构造函数不存在或提供了意料之外的行为,将导致错误,因此最好手工调用超类的构造函数。

12.3 使用现有的对象

面向对象编程鼓励代码重用。如果在某个Java编程项目中开发了一个对象,可以将其用于其他项目中,而无需做任何修改。

如果Java类是设计良好的,完全可以在其他程序中使用它。在程序中可以使用的对象越多,编写软件需要做的工作就越少。如果有优秀的拼写检查对象能够满足你的需要,便可以使用它而不用自己编写。这甚至可以给老板错觉:将拼写检查功能添加到程序中需要做很多的工作,这样你就有更多的时间在办公室打长途电话。

注意:

本书作者像很多人一样,是个自由职业者,在家办公。评估其上述建议时,别忘了考虑工作环境。

Java刚面世时,共享对象的系统很不正规。程序员尽可能独立地开发其对象,并且通过使用私有变量和读写变量的公有方法来进行保护,以防误用。

有了开发可重用对象的标准后,共享对象变得功能强大。

标准的好处体现在下面几个方面:

可以更少地编写关于对象工作原理的文档,因为知道标准的人都对其工作原理很清楚;

可以根据标准来设计开发工具,使得使用对象更容易;

两个遵循标准的对象可以相互交互,而无需通过特殊编程使其互相兼容。

12.4 将相同类型的对象存储到 Vector 中

编写计算机程序时,需要做出的一个重要决策是,将数据存储在哪里。在本书的前半部分,介绍了3种存储信息的地方:基本数据类型(如int和char)、数组和String对象。

任何Java类都能够存储数据。最有用的一种是Vector,它是一种存储相同类对象的数据结构。

Vector类似于数组,也存储相关的数据,但其长度可动态地增减。

Vector类位于java.util包中,这是Java类库中最有用的一个包。在程序中使用它,可使用一条import语句:

Vector 存储的对象要么属于同一个类,要么有相同的超类。要创建 Vector,需要引用两个类:Vector和要存储在Vector的类。

将要在Vector中存储的类的名称放在“<”和“>”之间,如下述语句所示:

上述语句创建一个存储字符串的Vector。以这种方式指定的存储在Vector中的类使用了通用类型,通用类型用来指示数据结构(比如Vector)可以存储的对象类型。在以前的Java版本中,要使用Vector,需要调用构造函数,如下所示:

虽然仍可以这样做,但通用类型使代码更可靠,因为它向编译器提供了一种防止程序员误用Vector的方法。如果试图将一个Integer对象存储到本应存储String对象的Vector中,编译器将报错。

与数组不同,Vector存储的元素数量并非固定的。Vector默认包含10个元素,如果你知道需要存储更多的存储,可通过构造函数的参数指定长度。下面的语句创建一个包含300个元素的Vector:

要将对象加入到 Vector中,可调用 Vector 的 add( )方法,并将对象作为其唯一的参数:

对象按照顺序加入到Vector中,因此如果这是加入到victoria中的前3个元素,则元素0为“Vance”,元素1为“Vernon”,元素2为“Velma”。

要从 Vector中检索元素,可使用方法 get( )并将元素的索引号作为其参数:

该语句将“Vernon”存储到字符串变量name中。

要查看 Vector 的元素中是否包含某个对象,可调用 contains( )方法并将该对象作为参数:

要将对象从 Vector 中删除,可调用 remove( )方法并将该对象或其索引号作为参数:

这两条语句导致Vector中只留下“Velma”。

遍历Vector

Java新增了一种for循环以方便载入Vector以及依次检查其每个元素。

该循环由两部分组成,比第8章介绍的for循环少一部分。

第一部分是初始化部分:变量的类及其名称,该变量用于存储从Vector中取出的每个对象。该对象与Vector中存储的对象必须属于同一个类。

第二部分指出要遍历的Vector。

下面的代码遍历 Vector victoria,并将其中的每个对象的名字显示到屏幕上:

本章将要创建的第一个应用程序使用Vector和特殊的for循环将一系列字符串按字母顺序显示到屏幕上。这些字符串来自一个数组和命令行参数。

在 NetBeans中打开 Java24 项目,然后选择 File->New File,创建一个新的 Java 空文件,并将其命名为StringLister。然后在源代码编辑器中输入程序清单12.1中的所有文本,并保存。

程序清单12.1 StringLister.java程序的完整代码

在运行该应用程序时(通过 Run->Run File 来运行),应该先选择 Run->Set Project Con figuration->Customize 命令,将 main class 设置为StringLister,并将参数设置为名字,当有多个名字时,需要使用空格分开,比如 Jackie Nickey Farina Woim。

命令行中指定的名字将添加到第 4~5 行的字符串数组中。由于在程序运行之前无法得知名字的个数,因此使用Vector来存储这些字符串比数组更合适。

使用Collection类的一个方法对存储在Vector中的字符串按字母顺序排序:

Collections.sort(list);

和Vector一样,这个类也位于java.util包中。在Java中,Vector以及其他有用的数据结构被称为集合。

当运行该程序时,输出结果应该是一组按字母排序的名字(见图12.2)。Vector在存储空间上的灵活性可以让你将额外的名字添加到数据结构中,并与其他名字一起排序。

图12.2 StringLister程序的输出结果

12.5 创建子类

为了看一个关于继承的示例,现在创建一个名为Point3D的类,它代表三维空间中的一个点。二维点可用坐标(x, y)表示。applet 使用(x, y)坐标来决定在哪里显示文本和图形,而三维空间添加第三个坐标,可将其称为z。

Point3D对象需要做下面3件事:

记录对象的(x, y, z)坐标;

需要时将对象移到新坐标(x, y, z)处;

需要时沿x、y和z轴移动特定的距离。

Java有一个表示二维点的标准类,名为Point。它有两个整型变量x和y,用于存储Point对象(x, y)坐标。它还有名为 move( )的方法,用于将一个点放在指定的位置,还有一个名为translate( )的方法,将对象沿 x 和 y轴移动特定的距离。

在NetBeans中的Java24项目中,创建一个新的空文件,将其命名为Point3D,然后在源代码编辑器窗口中输入程序清单12.2中的全部文本,并保存。

程序清单12.2 Point3D.java的完整源代码

Point3D 类没有 main( )块语句,所以不能使用 Java 解释器运行它。但是你可以在需要三维空间点的Java程序中使用它。

Point3D 类只需完成其超类 Point 不能完成的工作,主要是记录整型变量 z,将 z 作为move( )方法、translate( )方法和 Point3D( )构造函数的参数。

这些方法都使用关键字supper和this。this用于引用当前的Point3D对象,因此第8行的this.z=z;语句将变量z设置为第6行作为参数传入的z的值。

super语句引用当前对象的超类Point,用于设置Point3D类继承的变量和调用继承的方法。第 7 行的语句 super(x, y)调用超类的构造函数 Point(x, y),该构造函数用来设置 Point3D对象的(x, y)坐标。由于 Point 类能够处理坐标轴 x 和 y,如果 Point3D 类也这样做将多余。

要测试编译后的Point3D类,可以创建一个使用Point对象和Point3D对象的程序,并在屏幕上移动它们。在NetBeans中创建一个名为PointTester的新文件,然后输入程序清单12.3中的全部文本。当保存该文件时,将会自动对其编译。

程序清单12.3 PointTester.java程序的完整源代码

通过选择Run->Run File运行该文件时,如果该程序已经成功编译,则会看到如图12.3所示的输出。否则,查看源代码编辑器窗口旁边的红色图标,它可以指示是哪一行代码触发了错误。

图12.3 PointTester 程序的输出

12.6 总结

当人们谈论生育奇迹时,他们谈论的可能不是从Java超类派生子类的方式或在类层次结构中继承行为和属性的方式。

如果现实世界与面向对象编程的工作方式相同,则莫扎特的每个子孙都可以选择成为一名卓越的作曲家,马克吐温的所有子孙都能写出密西西比河边生活的诗歌。所有从祖先那里继承的技能都可以由你直接支配,不需要通过任何努力。

从奇迹的程度看,继承不能同物种延续和减免大笔税款相比。然而,这是一种设计软件的高效方法,可最大限度地减少重复工作。

12.7 问与答

问:到目前为止,所创建的大多数Java程序都没有使用extends来从超类继承,这是否就意味着它们不在层次结构中?

答:使用 Java 创建的所有类都是 Java 类层次结构的一部分,因为编写程序时如果不使用关键字 extends,则默认超类为 Object 对象。所有类的方法 equals( )和 toString( )都是自动从Object类继承而来的行为。

12.8 测验

为测试读者从本章继承了什么知识,请回答下列问题。

12.8.1 问题

1.如果在子类中要以不同于超类的方式处理方法,应该如何做?

a.删除超类中的方法。

b.覆盖超类中的方法。

c.给《San Jose Mercury News》的编辑写信,希望 Java 的开发者能看到这封信。

2.哪个方法用于检索存储在Vector中的元素?

a.get( )。

b.read( )。

c.elementAt( )。

3.可以使用哪个关键字来引用当前对象的方法和变量?

a.this。

b.that。

c.theOther。

12.8.2 答案

1.b.由于可以覆盖方法,所以无需修改超类的任何方面。

2.a.方法get( )接受一个参数——元素的索引号。

3.a.this关键字引用当前对象。

12.9 练习

如果你脑海中出现了学习更多知识的强烈愿望,可以通过下面的练习来获得更多有关继承的知识。

创建一个 Point4D 类,在Point3D 类创建的(x, y, z)坐标系的基础上再加上 t 坐标。t坐标代表时间,因此必须确保它不会被设置为负值。

使用足球队的进攻成员——边锋、外接手、阻挡线队员、跑锋、四分卫,设计一个代表这些球员技能的类层次结构,将通用技能放在层次结构的较上层。例如,阻挡行为应由边锋和阻挡线队员继承,速度应由外接手和跑锋继承。

有关为完成这些练习而编写的Java程序,请访问本书的配套网站www.java24hours.com。

没有精选讨论主题。

全部讨论主题 查看精选主题

没有讨论主题。
😃 😅 😆 😁 😂 😊 😄 😠 😩 😲 😞 😵 😰 😒 😍 😤 😜 😝 😋 😘 😚 😷 😳 😢 😭 😨 😣 😡 😌 😖 😔 😱 😪 😏 😓 😥 😫 😉 👊 👍 👆 👇 👈 👉 👋 👏 👌 👎 👐 💓 💔 💕 💖 💗 💘 💙 💚 💛 💜 💝 💞 💟