1、编译器并不简单地为每一个引用都创建缺省对象,因为若真要那样做,会在许多情况下增加不必要的负担。如果想初始化这些引用,可以在代码中的下列位置进行:
(1)在定义对象的地方。这意味着它们总是能够在构造器被调用之前被初始化。
(2)在类的构造器中。
(3)就在正在使用这些对象之前,这种方式称“惰性初始化”。在生成对象不值得及不必每次都生成对象的情况下,这种方式可以减少额外的负担。
2、虽然编译器强制你去初始化基类,并且要求要在构造器起始处就要这么做,但是它并不监督你必须将成员对象也初始化。
在清理方法中,还必须注意对基类清理方法和成员对象清理方法的调用顺序,以防某个子对象依赖于另一个子对象情形的发生。
首先,执行类的所有特定的清理动作,其顺序同生成顺序相反,然后,就如我们所示范的那样,调用基类的清理方法。
3、组合技术通常用于想在新类中使用现有类的功能而非它的接口这种情形。即,在新类中嵌入某个对象,让其实现所需要的功能 ,但是新类的用户看到的只是新类所定义的接口,而非所嵌入对象的接口。为取得此效果,需要在新类中嵌入一个现有类的private对象。
有时,允许类的用户直接访问新类中的组合成分是极具有意义的;也就是说,当成员对象声明public,如果成员对象自身都隐藏了具体实现,那么这种做法是安全 。当用户能够了解到你正在组装一组部件时,会使得端口更加易于理解。
4、protected关键字
“就类用户而言,这是private的,但对于任何继承于此类的导出类或其他任何位于同一个包内的类来说,它却是可以访问的。”
最好的方式是将字段保持为private;你应当一直保留“更改底层实现”的权利。然后通过protected方法来控制类的继承者访问权限。
5、增量开发
程序开发是一种增量过程。继承技术的优点之一,就是它支持增量开发模式。
6、向上转型
继承技术最重要的方面,是用来表现新类和基类之间的关系,可以表示成“新类是现有类的一种类型“。
7、final关键字
(1)final数据。
一个既是static又是final的字段只占据一段不能改变的存储空间。
对于基本类型,final使数值恒定不变;而对于对象引用,final使引用恒定不变。一旦引用被初始化指向一个对象,就无法再把它改为指向另一个对象。然而,对象其自身却是可以被修改的,Java并未提供使任何对象恒定不变的途径(但可以自己编写类似取得使对象恒定 不变的效果)。
(2)final方法
使用原因:一是把方法锁定,以防任何继承类修改它的含义。这是出于设计的考虑:想要确保在继承中使方法行为保持不变,并且不会被覆盖。
二是效率。如果将一个方法指明为final,就是同意编译器将针对该方法的所有调用都转为内嵌调用。当编译器发现一个final方法调用偏偏时,它会根据自己的谨慎判断,跳过插入程序代码这种方式而执行方法调用机制(将参数压入栈,跳至方法代码处并执行,然后跳回并清理栈中的参数,处理反回值),并且以方法体中的实际代码的复本来替代方法调用。
类中所有的private方法都是隐式地指定为final的。由于无法取用它,也就无法覆盖它。可以对private方法添加final修饰词,但这并不能给该方法增加任何额外的意义 。
“覆盖”只有在某方法是基类的接口的一部分时才会出现。即,必须能将一个对象向上转型为它的基本类型并调用相同的方法。如果某方法为private,它就不是基类的接口的一部分。它仅是一些隐藏于类中的程序代码,只不过是具有相同的名称而已。但如果在导出类中以相同的名称生成一个public、protected或包访问权限方法的话,该方法就不会产生在基类中出现的“仅具有相同名称的情况。此时你并没有该方法,仅是生成了一个新的方法。由于private方法无法触及而且能有效隐藏,所以除了把它看成是因为它所归属的类的组织结构的原因而存在外,其他任何事物都不需要考虑到它。
(2)final类
当某个类的整体定义为final时,就表明了你不打算继承该类,而且也不允许别人这样做。
8、初始化及类的加载
JAVA在不到需要的时候,是不会加载这个文件的--“类的代码会在它们第一次使用的时候加载”。类的加载通常都发生在第一次创建那个类的对象的时候,但是访问static数据或static方法的时候也会加载。
依旧遵循:静态变量、非静态变量、构造器的顺序进行初始化。
先将所有的静态变量(基类,继承类)进行初始化,其次是基类的非静态变量和构造器,最后才是继承类的非静态变量和构造器的初始化。
总结:
合成是把已有的类当作新类底层实现的一部分来复用,而继承则是复用其接口。由于派生类拥有基类的接口,因此它可以被上传(upcast)到基类,这点对多态性是非常重要的。
尽管面向对象的编程会反复强调继承,但当你着手设计的时候,通常情况下还是应该先考虑合成,只有在必要的时候才使用继承。合成会更灵活。此外,还可以让成员使用继承类的对象,这样你就能在运行时更换这些成员的具体类型及其行为了。于是,合成后的对象的行为方式也能得以改变了。
设计系统的时候,你的目标是要找到或者创建一组这样的类,它们每个都有具体的用途,并且都不是太大(塞了太多功能,复用起来就不方便了),当然也不能太小(功能不足就不能独立完成任务了)。
(1)在定义对象的地方。这意味着它们总是能够在构造器被调用之前被初始化。
(2)在类的构造器中。
(3)就在正在使用这些对象之前,这种方式称“惰性初始化”。在生成对象不值得及不必每次都生成对象的情况下,这种方式可以减少额外的负担。
2、虽然编译器强制你去初始化基类,并且要求要在构造器起始处就要这么做,但是它并不监督你必须将成员对象也初始化。
在清理方法中,还必须注意对基类清理方法和成员对象清理方法的调用顺序,以防某个子对象依赖于另一个子对象情形的发生。
首先,执行类的所有特定的清理动作,其顺序同生成顺序相反,然后,就如我们所示范的那样,调用基类的清理方法。
3、组合技术通常用于想在新类中使用现有类的功能而非它的接口这种情形。即,在新类中嵌入某个对象,让其实现所需要的功能 ,但是新类的用户看到的只是新类所定义的接口,而非所嵌入对象的接口。为取得此效果,需要在新类中嵌入一个现有类的private对象。
有时,允许类的用户直接访问新类中的组合成分是极具有意义的;也就是说,当成员对象声明public,如果成员对象自身都隐藏了具体实现,那么这种做法是安全 。当用户能够了解到你正在组装一组部件时,会使得端口更加易于理解。
4、protected关键字
“就类用户而言,这是private的,但对于任何继承于此类的导出类或其他任何位于同一个包内的类来说,它却是可以访问的。”
最好的方式是将字段保持为private;你应当一直保留“更改底层实现”的权利。然后通过protected方法来控制类的继承者访问权限。
5、增量开发
程序开发是一种增量过程。继承技术的优点之一,就是它支持增量开发模式。
6、向上转型
继承技术最重要的方面,是用来表现新类和基类之间的关系,可以表示成“新类是现有类的一种类型“。
7、final关键字
(1)final数据。
一个既是static又是final的字段只占据一段不能改变的存储空间。
对于基本类型,final使数值恒定不变;而对于对象引用,final使引用恒定不变。一旦引用被初始化指向一个对象,就无法再把它改为指向另一个对象。然而,对象其自身却是可以被修改的,Java并未提供使任何对象恒定不变的途径(但可以自己编写类似取得使对象恒定 不变的效果)。
(2)final方法
使用原因:一是把方法锁定,以防任何继承类修改它的含义。这是出于设计的考虑:想要确保在继承中使方法行为保持不变,并且不会被覆盖。
二是效率。如果将一个方法指明为final,就是同意编译器将针对该方法的所有调用都转为内嵌调用。当编译器发现一个final方法调用偏偏时,它会根据自己的谨慎判断,跳过插入程序代码这种方式而执行方法调用机制(将参数压入栈,跳至方法代码处并执行,然后跳回并清理栈中的参数,处理反回值),并且以方法体中的实际代码的复本来替代方法调用。
类中所有的private方法都是隐式地指定为final的。由于无法取用它,也就无法覆盖它。可以对private方法添加final修饰词,但这并不能给该方法增加任何额外的意义 。
“覆盖”只有在某方法是基类的接口的一部分时才会出现。即,必须能将一个对象向上转型为它的基本类型并调用相同的方法。如果某方法为private,它就不是基类的接口的一部分。它仅是一些隐藏于类中的程序代码,只不过是具有相同的名称而已。但如果在导出类中以相同的名称生成一个public、protected或包访问权限方法的话,该方法就不会产生在基类中出现的“仅具有相同名称的情况。此时你并没有该方法,仅是生成了一个新的方法。由于private方法无法触及而且能有效隐藏,所以除了把它看成是因为它所归属的类的组织结构的原因而存在外,其他任何事物都不需要考虑到它。
(2)final类
当某个类的整体定义为final时,就表明了你不打算继承该类,而且也不允许别人这样做。
8、初始化及类的加载
JAVA在不到需要的时候,是不会加载这个文件的--“类的代码会在它们第一次使用的时候加载”。类的加载通常都发生在第一次创建那个类的对象的时候,但是访问static数据或static方法的时候也会加载。
依旧遵循:静态变量、非静态变量、构造器的顺序进行初始化。
先将所有的静态变量(基类,继承类)进行初始化,其次是基类的非静态变量和构造器,最后才是继承类的非静态变量和构造器的初始化。
总结:
合成是把已有的类当作新类底层实现的一部分来复用,而继承则是复用其接口。由于派生类拥有基类的接口,因此它可以被上传(upcast)到基类,这点对多态性是非常重要的。
尽管面向对象的编程会反复强调继承,但当你着手设计的时候,通常情况下还是应该先考虑合成,只有在必要的时候才使用继承。合成会更灵活。此外,还可以让成员使用继承类的对象,这样你就能在运行时更换这些成员的具体类型及其行为了。于是,合成后的对象的行为方式也能得以改变了。
设计系统的时候,你的目标是要找到或者创建一组这样的类,它们每个都有具体的用途,并且都不是太大(塞了太多功能,复用起来就不方便了),当然也不能太小(功能不足就不能独立完成任务了)。