自定义博客皮肤VIP专享

*博客头图:

格式为PNG、JPG,宽度*高度大于1920*100像素,不超过2MB,主视觉建议放在右侧,请参照线上博客头图

请上传大于1920*100像素的图片!

博客底图:

图片格式为PNG、JPG,不超过1MB,可上下左右平铺至整个背景

栏目图:

图片格式为PNG、JPG,图片宽度*高度为300*38像素,不超过0.5MB

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

-+
  • 博客(31)
  • 收藏
  • 关注

转载 6 . 8 . 2 f i n a l 方法 和 6 . 8 . 3 f in a l 类

6 . 8 . 2 f i n a l 方法之所以要使用final 方法,可能是出于对两方面理由的考虑。第一个是为方法“上锁”,防止任何继承类改变它的本来含义。设计程序时,若希望一个方法的行为在继承期间保持不变,而且不可被覆盖或改写,就可以采取这种做法。采用final 方法的第二个理由是程序执行的效率。将一个方法设成final 后,编译器就可以把对那个方法的所有调用都置入“嵌入

2014-04-15 17:21:04 662

转载 6.8 final 关键字 和 6 . 8 . 1 f i n a l 数据

6.8 final 关键字由于语境(应用环境)不同,final 关键字的含义可能会稍微产生一些差异。但它最一般的意思就是声明“这个东西不能改变”。之所以要禁止改变,可能是考虑到两方面的因素:设计或效率。由于这两个原因颇有些区别,所以也许会造成final 关键字的误用。在接下去的小节里,我们将讨论final 关键字的三种应用场合:数据、方法以及类。6 . 8 . 1 f

2014-04-15 17:01:14 657

转载 6 . 7 上溯造型

继承最值得注意的地方就是它没有为新类提供方法。继承是对新类和基础类之间的关系的一种表达。可这样总结该关系:“新类属于现有类的一种类型”。这种表达并不仅仅是对继承的一种形象化解释,继承是直接由语言提供支持的。作为一个例子,大家可考虑一个名为Instrument 的基础类,它用于表示乐器;另一个衍生类叫作Wind。由于继承意味着基础类的所有方法亦可在衍生出来的类中使用,所以我们发给基础

2014-04-01 15:37:38 356

转载 6 . 6 累积开发

继承的一个好处是它支持“累积开发”,允许我们引入新的代码,同时不会为现有代码造成错误。这样可将新错误隔离到新代码里。通过从一个现成的、功能性的类继承,同时增添成员新的数据成员及方法(并重新定义现有方法),我们可保持现有代码原封不动(另外有人也许仍在使用它),不会为其引入自己的编程错误。一旦出现错误,就知道它肯定是由于自己的新代码造成的。这样一来,与修改现有代码的主体相比,改正错误所

2014-04-01 15:37:17 394

转载 6 . 5 p r o t e c t e d

现在我们已理解了继承的概念,protected 这个关键字最后终于有了意义。在理想情况下,private 成员随时都是“私有”的,任何人不得访问。但在实际应用中,经常想把某些东西深深地藏起来,但同时允许访问衍生类的成员。protected 关键字可帮助我们做到这一点。它的意思是“它本身是私有的,但可由从这个类继承的任何东西或者同一个包内的其他任何东西访问”。也就是说,Java 中的pr

2014-04-01 15:36:57 4106

转载 6 . 4 到底选择合成还是继承

无论合成还是继承,都允许我们将子对象置于自己的新类中。大家或许会奇怪两者间的差异,以及到底该如何选择。如果想利用新类内部一个现有类的特性,而不想使用它的接口,通常应选择合成。也就是说,我们可嵌入一个对象,使自己能用它实现新类的特性。但新类的用户会看到我们已定义的接口,而不是来自嵌入对象的接口。考虑到这种效果,我们需在新类里嵌入现有类的private 对象。有些时候,我们想让类用

2014-04-01 15:36:31 448

转载 6 . 3 . 2 名字的隐藏

只有C++程序员可能才会惊讶于名字的隐藏,因为它的工作原理与在C++里是完全不同的。如果Java 基础类有一个方法名被“过载”使用多次,在衍生类里对那个方法名的重新定义就不会隐藏任何基础类的版本。所以无论方法在这一级还是在一个基础类中定义,过载都会生效://: Hide.java// Overloading a base-class method name// in a der

2014-04-01 15:35:38 288

转载 6 . 3 . 1 确保正确的清除

Java 不具备象C++的“破坏器”那样的概念。在C++中,一旦破坏(清除)一个对象,就会自动调用破坏器方法。之所以将其省略,大概是由于在Java 中只需简单地忘记对象,不需强行破坏它们。垃圾收集器会在必要的时候自动回收内存。垃圾收集器大多数时候都能很好地工作,但在某些情况下,我们的类可能在自己的存在时期采取一些行动,而这些行动要求必须进行明确的清除工作。正如第4 章已经指出的那样

2014-04-01 15:35:06 378

转载 6 . 3 合成与继承的结合

许多时候都要求将合成与继承两种技术结合起来使用。下面这个例子展示了如何同时采用继承与合成技术,从而创建一个更复杂的类,同时进行必要的构建器初始化工作://: PlaceSetting.java// Combining composition & inheritanceclass Plate {Plate(int i) {System.out.println("Plate c

2014-04-01 15:34:42 376

转载 6 . 2 . 1 初始化基础类

由于这儿涉及到两个类——基础类及衍生类,而不再是以前的一个,所以在想象衍生类的结果对象时,可能会产生一些迷惑。从外部看,似乎新类拥有与基础类相同的接口,而且可包含一些额外的方法和字段。但继承并非仅仅简单地复制基础类的接口了事。创建衍生类的一个对象时,它在其中包含了基础类的一个“子对象”。这个子对象就象我们根据基础类本身创建了它的一个对象。从外部看,基础类的子对象已封装到衍生类的对象

2014-04-01 15:33:54 338

转载 6 . 2 继承的语法

继承与Java (以及其他OOP 语言)非常紧密地结合在一起。我们早在第1 章就为大家引入了继承的概念,并在那章之后到本章之前的各章里不时用到,因为一些特殊的场合要求必须使用继承。除此以外,创建一个类时肯定会进行继承,因为若非如此,会从Java 的标准根类Object 中继承。142用于合成的语法是非常简单且直观的。但为了进行继承,必须采用一种全然不同的形式。需要继承的时候,我

2014-04-01 15:32:58 340

转载 6 . 1 合成的语法

就以前的学习情况来看,事实上已进行了多次“合成”操作。为进行合成,我们只需在新类里简单地置入对象句柄即可。举个例子来说,假定需要在一个对象里容纳几个String 对象、两种基本数据类型以及属于另一个类的一个对象。对于非基本类型的对象来说,只需将句柄置于新类即可;而对于基本数据类型来说,则需在自己的类中定义它们。如下所示(若执行该程序时有麻烦,请参见第3 章3.1.2 小节“赋值”):

2014-04-01 15:30:56 320

转载 第6 章 类再生

“Java 引人注目的一项特性是代码的重复使用或者再生。但最具革命意义的是,除代码的复制和修改以外,我们还能做多得多的其他事情。”在象C 那样的程序化语言里,代码的重复使用早已可行,但效果不是特别显著。与Java 的其他地方一样,这个方案解决的也是与类有关的问题。我们通过创建新类来重复使用代码,但却用不着重新创建,可以直接使用别人已建好并调试好的现成类。但这样做必须保证不会干扰

2014-04-01 15:30:09 349

转载 5 . 5 总结

对于任何关系,最重要的一点都是规定好所有方面都必须遵守的界限或规则。创建一个库时,相当于建立了同那个库的用户(即“客户程序员”)的一种关系——那些用户属于另外的程序员,可能用我们的库自行构建一个应用程序,或者用我们的库构建一个更大的库。如果不制订规则,客户程序员就可以随心所欲地操作一个类的所有成员,无论我们本来愿不愿意其中的一些成员被直接操作。所有东西都在别人面前都暴露无遗。本

2014-04-01 15:29:30 364

转载 5 . 4 类访问

在Java 中,亦可用访问指示符判断出一个库内的哪些类可由那个库的用户使用。若想一个类能由客户程序员调用,可在类主体的起始花括号前面某处放置一个public 关键字。它控制着客户程序员是否能够创建属于这个类的一个对象。为控制一个类的访问,指示符必须在关键字class 之前出现。所以我们能够使用:public class Widget {也就是说,假若我们的库名是mylib,那么

2014-04-01 15:29:10 319

转载 5 . 3 接口与实现

我们通常认为访问控制是“隐藏实施细节”的一种方式。将数据和方法封装到类内后,可生成一种数据类型,它具有自己的特征与行为。但由于两方面重要的原因,访问为那个数据类型加上了自己的边界。第一个原因是规定客户程序员哪些能够使用,哪些不能。我们可在结构里构建自己的内部机制,不用担心客户程序员将其当作接口的一部分,从而自由地使用或者“滥用”。这个原因直接导致了第二个原因:我们需要将接口同实施细

2014-04-01 15:28:37 292

转载 5 . 2 . 4 p r o t e c t e d:“友好的一种”

protected(受到保护的)访问指示符要求大家提前有所认识。首先应注意这样一个事实:为继续学习本书一直到继承那一章之前的内容,并不一定需要先理解本小节的内容。但为了保持内容的完整,这儿仍然要对此进行简要说明,并提供相关的例子。protected 关键字为我们引入了一种名为“继承”的概念,它以现有的类为基础,并在其中加入新的成员,同时不会对现有的类产生影响——我们将这种现有的类称

2014-04-01 15:27:59 747

转载 5 . 2 . 3 p r i v a t e :不能接触!

private 关键字意味着除非那个特定的类,而且从那个类的方法里,否则没有人能访问那个成员。同一个包内的其他成员不能访问private 成员,这使其显得似乎将类与我们自己都隔离起来。另一方面,也不能由几个合作的人创建一个包。所以private 允许我们自由地改变那个成员,同时毋需关心它是否会影响同一个包内的另一个类。默认的“友好”包访问通常已经是一种适当的隐藏方法;请记住,对于包的用

2014-04-01 15:27:32 1615

转载 5 . 2 . 2 p u b l i c:接口访问

使用public 关键字时,它意味着紧随在public 后面的成员声明适用于所有人,特别是适用于使用库的客户程序员。假定我们定义了一个名为dessert 的包,其中包含下述单元(若执行该程序时遇到困难,请参考第3 章3.1.2 小节“赋值”)://: Cookie.java// Creates a librarypackage c05.dessert;public clas

2014-04-01 15:27:00 918

转载 5 . 2 . 1 “友好的”

如果根本不指定访问指示符,就象本章之前的所有例子那样,这时会出现什么情况呢?默认的访问没有关键字,但它通常称为“友好”(Friendly )访问。这意味着当前包内的其他所有类都能访问“友好的”成员,但对包外的所有类来说,这些成员却是“私有”(Private)的,外界不得访问。由于一个编译单元(一个文件)只能从属于单个包,所以单个编译单元内的所有类相互间都是自动“友好”的。因此,我们也说

2014-04-01 15:26:16 380

转载 5 . 2 J a v a 访问指示符

针对类内每个成员的每个定义,Java 访问指示符poublic,protected 以及private 都置于它们的最前面——无论它们是一个数据成员,还是一个方法。每个访问指示符都只控制着对那个特定定义的访问。这与C++存在着显著不同。在C++中,访问指示符控制着它后面的所有定义,直到又一个访问指示符加入为止。通过千丝万缕的联系,程序为所有东西都指定了某种形式的访问。在后面的小节里,大

2014-04-01 15:25:53 418

转载 5 . 1 . 4 包的停用

大家应注意这样一个问题:每次创建一个包后,都在为包取名时间接地指定了一个目录结构。这个包必须存在(驻留)于由它的名字规定的目录内。而且这个目录必须能从CLASSPATH 开始搜索并发现。最开始的时候,package 关键字的运用可能会令人迷惑,因为除非坚持遵守根据目录路径指定包名的规则,否则就会在运行期获得大量莫名其妙的消息,指出找不到一个特定的类——即使那个类明明就在相同的目录中。若

2014-04-01 15:24:18 273

转载 5 . 1 . 3 利用导入改变行为

Java 已取消的一种特性是C 的“条件编译”,它允许我们改变参数,获得不同的行为,同时不改变其他任何代码。Java 之所以抛弃了这一特性,可能是由于该特性经常在C 里用于解决跨平台问题:代码的不同部分根据具体的平台进行编译,否则不能在特定的平台上运行。由于Java 的设计思想是成为一种自动跨平台的语言,所以这种特性是没有必要的。然而,条件编译还有另一些非常有价值的用途。一种很常见

2014-03-19 19:05:08 321

转载 5 . 1 . 2 自定义工具库

掌握前述的知识后,接下来就可以开始创建自己的工具库,以便减少或者完全消除重复的代码。例如,可为System.out.println()创建一个别名,减少重复键入的代码量。它可以是名为tools 的一个包(package)的一部分://: P.java127// The P.rint & P.rintln shorthandpackage com.bruceeckel.too

2014-03-19 19:04:41 367

转载 5 . 1 . 1 创建独一无二的包名

大家或许已注意到这样一个事实:由于一个包永远不会真的“封装”到单独一个文件里面,它可由多个.class 文件构成,所以局面可能稍微有些混乱。为避免这个问题,最合理的一种做法就是将某个特定包使用的所有.class 文件都置入单个目录里。也就是说,我们要利用操作系统的分级文件结构避免出现混乱局面。这正是Java 所采取的方法。它同时也解决了另两个问题:创建独一无二的包名以及找出那些可能

2014-03-19 19:03:32 586

转载 5 . 1 包:库单元

我们用import 关键字导入一个完整的库时,就会获得“包”(Package)。例如:import java.util.*;它的作用是导入完整的实用工具(Utility)库,该库属于标准Java 开发工具包的一部分。由于Vector 位于java.util 里,所以现在要么指定完整名称“java.util.Vector”(可省略import 语句),要么简单地指定一个“Vector

2014-03-19 19:02:55 349

转载 第5 章 隐藏实施过程

“进行面向对象的设计时,一项基本的考虑是:如何将发生变化的东西与保持不变的东西分隔开。”这一点对于库来说是特别重要的。那个库的用户(客户程序员)必须能依赖自己使用的那一部分,并知道一旦新版本的库出台,自己不需要改写代码。而与此相反,库的创建者必须能自由地进行修改与改进,同时保证客户程序员代码不会受到那些变动的影响。为达到这个目的,需遵守一定的约定或规则。例如,库程序员在修改库内的一

2014-03-19 19:02:14 382

转载 4 . 6 总结

作为初始化的一种具体操作形式,构建器应使大家明确感受到在语言中进行初始化的重要性。与C++的程序设计一样,判断一个程序效率如何,关键是看是否由于变量的初始化不正确而造成了严重的编程错误(臭虫)。这些形式的错误很难发现,而且类似的问题也适用于不正确的清除或收尾工作。由于构建器使我们能保证正确的初始化和清除(若没有正确的构建器调用,编译器不允许对象创建),所以能获得完全的控制权和安全性

2014-03-19 19:01:37 312

转载 4 . 5 . 1 多维数组

在Java 里可以方便地创建多维数组://: MultiDimArray.java// Creating multidimensional arrays.import java.util.*;public class MultiDimArray {static Random rand = new Random();static int pRand(int mod) {r

2014-03-19 19:00:36 276

转载 4 . 5 数组初始化

在C 中初始化数组极易出错,而且相当麻烦。C++通过“集合初始化”使其更安全(注释⑥)。Java 则没有象C++那样的“集合”概念,因为Java 中的所有东西都是对象。但它确实有自己的数组,通过数组初始化来提供支持。数组代表一系列对象或者基本数据类型,所有相同的类型都封装到一起——采用一个统一的标识符名称。数组的定义和使用是通过方括号索引运算符进行的([])。为定义一个数组,只需在

2014-03-19 18:59:50 388

转载 4 . 4 . 2 构建器初始化

可考虑用构建器执行初始化进程。这样便可在编程时获得更大的灵活程度,因为我们可以在运行期调用方法和采取行动,从而“现场”决定初始化值。但要注意这样一件事情:不可妨碍自动初始化的进行,它在构建器进入之前就会发生。因此,假如使用下述代码:class Counter {int i;Counter() { i = 7; }// . . .那么i 首先会初始化成零,然后变成7。对于

2014-03-18 15:57:03 387

空空如也

空空如也

TA创建的收藏夹 TA关注的收藏夹

TA关注的人

提示
确定要删除当前文章?
取消 删除