一.
复用类
1. 复用类的两种主要方式:
第一种方法非常直观:只需在新的类中产生现有类的对象。由于新的类是由现有类的对象所组成,所以这种方法称为
组合。该方法只是复用了现有程序代码的功能,而非它的形式。
第二种方法则更细致一些,它按照现有类的类型来创建新类。无需改变现有类的形式,采用现有类的形式并在其中添加新代码。这种神奇的方式称为
继承,而且编译器可以完成其中大部分工作。
当然还有第三种方式,这种方式被称为代理,不过Java并没有提供对它的支持。这是继承与组合之间的中庸之道。使用代理可以拥有更多的控制力,我们可以选择只提供在成员对象中的方法的某个子集。
2. 初始化基类:
如果父类只含有一个不带参数的构造器(编译器会把它当成默认构造器),编译器会自动调用该父类的无参构造器。如果没有默认的基类构造器,或者想调用一个带参数的基类构造器,就必须用关键字
super
显式地编写调用基类构造器的语句,并且配以适当的参数列表。
3.
在组合与继承之间选择:
组合和继承都允许在新类中放置子对象,组合式显式地这样做,而继承则是隐式地做(子类创建一个对象,则该对象也包括了父类的一个对象)。
组合技术通常用于想在新类中使用现有类的功能而非它的接口这种情形。即,在新类中嵌入某个对象,让其实现所需的功能,但新类的用户看到的只是为新类所定义的接口,而非所嵌入对象的接口。为取得此效果,需要在新类中嵌入一个现有类的
private
对象。有时,允许类的用户直接访问新类中的组合成分是极具意义的;也就是说,将成员对象声明为
public
。如果成员对象自身都隐藏了具体实现,那么这种做法是安全的。
在继承的时候,使用某个现有类,并开发一个它的特殊版本。通常,这意味着你在使用一个通用类,并为了某种特殊需要而将其特殊化。略微思考一下就会发现,用一个“交通工具”对象来构成一部“车子”是毫无意义的,因为“车子”并不包含“交通工具”,它仅是一种交通工具(
is-a
关系)。“
is-a
”(是一个)的关系是用继承来表达的,而“
has-a
”(有一个)的关系是用组合来表达的。
在面向对象编程中,生成和使用程序代码最有可能采用的方法就是直接将数据和方法包装进一个类中,并使用该类的对象。也可以运用组合技术使用现有类来开发新的类;而继承技术其实是不太常用的。因此,尽管在教授
OOP
的过程中虽然多次强调继承,但这并不意味着尽可能使用它。相反,应当慎用这样技术,其使用场合仅限于你确信使用该技术确实有效的情况。到底是该用组合还是用继承,一个最清晰的判断办法就是问一问自己是否需要从新类向基类进行向上转型。如果必须向上转型,则继承是必要的;但如果不需要,则应当好好考虑自己是否需要继承。所以,在开始一个设计时,一般优先选择使用组合(或者可能使用代理),只在确实必要时才使用继承。
4.
final
关键字:
一个即是
static
又是
final
的域只占据一段不能改变的存储空间。
使用带
final
的三种情况:数据、方法、类。
当对象引用而不是基本类型运用
final
时,其含义会有一点令人迷惑。对于基本类型,
final
使数值恒定不变;而用于对象引用,
final
使引用恒定不变。一旦引用被初始化指向一个对象,就无法再把它改为指向另一个对象。然而,对象其自身却是可以被修改的,
Java
并未提供使任何对象恒定不变的途径(但可以自己编写类以取得使对象恒定不变的效果)。这样限制同样适用于数组,它也是对象。
如果类的成员变量赋值为
final
并未给它赋值的话,那么必须在构造方法为其赋值,否则会报错!
Java
允许在参数列表中以声明的方式将参数指明为
final
。这意味着你无法在方法中更改参数引用所指向的对象。
使用
final
方法的原因有两个。第一个原因是把方法锁定,以防任何继承类修改它的含义。这是出于设计的考虑:想要确保在继承中使用方法行为保持不变,并且不会被覆盖。过去建议使用
final
方法的第二个原因是效率。
Final
类:当某个类的整体定义为
final
是,就表明了你不打算继承该类,而且也不允许别人这样做。换句话说,出于某种考虑,你对该类的设计永不需要做任何变动,或者出于安全考虑,你不希望它有子类。然而,由于
final
类禁止继承,所以
final
类中所有的方法都隐式指定为
final
的,因为无法覆盖它们。
5.
final
和
private
关键字:
类中所有的
private
方法都隐式地指定为
final
的。由于无法取用
private
方法,所以也就无法覆盖它。可以对
private
方法添加
final
修饰词,但这并不能给该方法增加任何额外的意义。
特别要注意的是子类可以覆盖基类的
private
方法(隐含式
final
的)。其原因是:如果方法为
private
,它就不是基类的接口的一部分。它仅是一些隐藏于类中的程序代码,只不过是具有相同的名称而已。