复用代码是Java众多引人注目的功能之一。但要想成为极具革命性的语言,仅仅能够复制代码并对之加以改变是不够的,它还必须能够做更多的事情。
两种代码重用机制:组合和继承
1.组合语法
组合:将对象引用置于新类中
类中域为基本变量时能够自动被初始化为零。但是对象引用会被初始化为null
初始化引用,可以在代码中下列位置进行:
1.在定义对象的地方。这意味着它们总是能够在构造器之前被初始化
2.在类的构造器中
3.就在正要使用这些对象之前,这种方式称为惰性初始化
4.使用实例初始化。
2.继承语法
继承是所有OOP语言和Java语言不可缺少的部分。当创建一个类时,总是在继承,因为,除非已明确指出要从其他类中继承,
否则就是在隐式地从Java的标准根类Object进行继承。
class A extends B{}
2.1初始化基础类
使用super 关键字
3.组合与继承的结合
许多时候都要求将合成与继承两种技术结合起来使用。
3.1 确保正确的清除
垃圾收集器会在必要的时候自动回收内存。垃圾收集器大多数时候都能很好地工作,但在某些情况下,我们的类可能在自己的存在时期采取一些行动,
而这些行动要求必须进行明确的清除工作。
垃圾收集的顺序:不能指望自己能确切知道何时会开始垃圾收集。垃圾收集器可能永远不会得到调用。即使得到调用,它也可能以自己愿意的任何顺序回收对象。
除此以外,Java 1.0 实现的垃圾收集器机制通常不会调用finalize()方法。除内存的回收以外,其他任何东西都最好不要依赖垃圾收集器进行回收。
若想明确地清除什么,请制作自己的清除方法,而且不要依赖finalize()。然而正如以前指出的那样,可强迫Java1.1 调用所有收尾模块(Finalizer)。
4.再论合成与继承
在面向对象的程序设计中,创建和使用代码最可能采取的一种做法是:将数据和方法统一封装到一个类里,并且使用那个类的对象。有些时候,
需通过“合成”技术用现成的类来构造新类。而继承是最少见的一种做法。因此,尽管继承在学习OOP 的过程中得到了大量的强调,但并不意味着应该尽可能地到处使用它。
相反,使用它时要特别慎重。只有在清楚知道继承在所有方法中最有效的前提下,才可考虑它。为判断自己到底应该选用合成还是继承,一个最简单的办法就是考虑是否
需要从新类上溯造型回基础类。若必须上溯,就需要继承。但如果不需要上溯造型,就应提醒自己防止继承的滥用。
5.protected
意思是“它本身是私有的,但可由从这个类继承的任何东西或者同一个包内的其他任何东西访问”。也就是说,Java 中的protected 会成为进入“友好”状态。
6.累积开发
继承的一个好处是它支持“累积开发”,允许我们引入新的代码,同时不会为现有代码造成错误。这样可将新错误隔离到新代码里。通过从一个现成的、功能性的类继承,
同时增添成员新的数据成员及方法(并重新定义现有方法),我们可保持现有代码原封不动(另外有人也许仍在使用它),不会为其引入自己的编程错误。一旦出现错误,
就知道它肯定是由于自己的新代码造成的。这样一来,与修改现有代码的主体相比,改正错误所需的时间和精力就可以少很多。
7.上溯造型
继承最值得注意的地方就是它没有为新类提供方法。继承是对新类和基础类之间的关系的一种表达。可这样总结该关系:“新类属于现有类的一种类型”。
何谓“上溯造型”?之所以叫作这个名字,除了有一定的历史原因外,也是由于在传统意义上,类继承图的画法是根位于最顶部,再逐渐向下扩展。
8.final 关键字
意思就是声明“这个东西不能改变”。之所以要禁止改变,可能是考虑到两方面的因素:设计或效率。我们将讨论final 关键字的三种应用场合:数据、方法以及类。
8.1 final数据
许多程序设计语言都有自己的办法告诉编译器某个数据是“常数”。常数主要应用于下述两个方面:
(1) 编译期常数,它永远不会改变
(2) 在运行期初始化的一个值,我们不希望它发生变化
对于基本数据类型,final 会将值变成一个常数;但对于对象句柄,final 会将句柄变成一个常数。进行声明时,必须将句柄
初始化到一个具体的对象。而且永远不能将句柄变成指向另一个对象。然而,对象本身是可以修改的
空白final:它们属于一些特殊的字段。尽管被声明成final,但却未得到一个初始值。无论在哪种情况下,空白final 都必须在实际使用前得到正确的初始化。
而且编译器会主动保证这一规定得以贯彻。然而,对于final 关键字的各种应用,空白final 具有最大的灵活性。现在强行要求我们对final 进行赋值处理——
要么在定义字段时使用一个表达 式,要么在每个构建器中。这样就可以确保final 字段在使用前获得正确的初始化。
final 自变量:Java 1.1 允许我们将自变量设成final 属性,方法是在自变量列表中对它们进行适当的声明。这意味着在一个方法的内部,我们不能改变自变量
句柄指向的东西。
8.2 final方法
之所以要使用final 方法,可能是出于对两方面理由的考虑。第一个是为方法“上锁”,防止任何继承类改变它的本来含义。设计程序时,若希望一个方法的行为
在继承期间保持不变,而且不可被覆盖或改写,就可以采取这种做法。采用final 方法的第二个理由是程序执行的效率.
8.3 final类
如果说整个类都是final(在它的定义前冠以final 关键字),就表明自己不希望从这个类继承,或者不允许其他任何人采取这种操作。
9.初始化和类装载
在许多传统语言里,程序都是作为启动过程的一部分一次性载入的。随后进行的是初始化,再是正式执行程序。在这些语言中,必须对初始化过程进行慎重的控制,
保证static 数据的初始化不会带来麻烦。比如在一个static 数据获得初始化之前,就有另一个static 数据希望它是一个有效值,那么在C++中就会造成问题。
Java 则没有这样的问题,因为它采用了不同的装载方法。由于Java 中的一切东西都是对象,,每个对象的代码都存在于独立的文件中。除非真的需要代码,
否则那个文件是不会载入的。
JAVA---类再生
最新推荐文章于 2024-06-17 09:39:48 发布