组合语法
将对象引用置于新类中即可。
编译器并不是简单地为每一个引用都创建默认对象,因为若真要那样做的话,就会在许多情况下增加不必要的负担。
初始化引用,可以在以下位置:
- 在定义对象的地方。
- 在类的构造器中。
- 就在正要使用这些对象之前,这种方式成为惰性初始化。
- 使用实例初始化。
继承语法
继承是所有OOP语言和Java语言不可或缺的组成部分。
继承的一般访问权限规则:将所有的数据成员都指定为private,将所有的方法指定为public。
初始化基类(父类)
当创建一个导出类时,该对象包含了一个基类的子对象。这个子对象与你用的基类对象直接创建是一样的。
基类在构建过程是从基类向外扩散的,所以基类在导出类构造器可以访问它之前,就已经完成了初始化。
注意:当基类只有带参数的构造器,没有无参构造器,或者子类想调用带参数的构造器,就必须用super显式地调用基类构造器,并且配以适当的参数。
代理
Java并没有提供对代理的直接支持,这是继承和组合之间的中庸之道。使用代理时可以具有更多的控制力,因为代理可以选择只提供在成员对象中的方法的某个子集。
代理模式:为其它对象提供一种代理以控制对这个对象的访问。在某些情况下,一 个客户不想直接引用另一个对象,而代理对象可以在客户端和目标对象之间起到中介作用。
结合使用组合和集成
确保正确清理。Java中没有析构函数的概念,有时候一些类在其生命周期内需要执行一些必要的清理活动。
注意:一般Java将这一清理动作置于finally子句中,以预防异常的出现。
名称屏蔽:如果Java 的基类拥有某个已被多次重载的方法名称,那么在导出类中重新定义该方法名称并不会屏蔽其在基类中的任何版本。
在组合和继承之间选择(区别)
组合和继承的区别:
- 组合和继承都允许在新的类中放置子对象,组合是显式地这样做,而继承则是隐式地做。
- 组合技术通常用于想在新类中使用现有类的功能而非它的接口。需要在新类中嵌入现有类的private对象。
- 继承技术通常意味着使用一个通用的类,并为了某种特殊需要而将其特殊化。
例子:车是一种交通工具,车有四个轮子。
“is-a”(是一个)关系是用继承来表达的,而“has-a”(有一个)关系是用组合来表达。
protected关键字
就类用户而言,这是private的,但是对于任何继承于此类的导出类或其他任何位于用一个包内的类来说,它却是可以访问的。
规则:将域保持private,然后通过protected方法来控制类的继承者的访问权限。
向上转型(导出类转基类)
继承技术最重要的方面是用来表现新类和基类之间的关系,即是新类是现有类的一种类型。
Instrument乐器基类---Wind导出类,由于继承可以确保基类中所有的方法在导出类中也有同样有效,意味着可以说
Wind对象也是一种Instrument类型。
Instrument i = new Wind();
这种将Wind引用转换为Instrument引用的动作,称为向上转型。
由导出类转型成基类,在继承图上是向上移动的,因此称为向上转型。由于向上转型是从一个较为专用类型转向较为通用类型,所以转型总是很安全的。
转型过程中,类接口唯一可能发生的事情就是丢失方法,而不是获取它们。
final关键字
运用情况:
- 一个永不改变的编译时常量。
- 一个在运行时被初始化的值,而你不希望它被改变。
- 编译器常量:编译器可以将该常量值直接代入任何可能用到它的计算式中。Java中,这类常量要求必须是基本数据类型,且用final关键字修饰。
针对引用数据类型使用final修饰,一旦引用被初始化指向一个对象,就无法再把它改为指向另外一个对象。
注意:
- 一个既是static又是final的域只占据一段不能改变的存储空间。
- 定义为static,只是强调只有一份,内存中只有一个数据域;定义为final,则说明它是一个常量;
- 带有恒定初始值的final static基本类型全用大写字母命名,并且字与字之间用下划线隔开。
static final域与final域的区别:
- 当在类中具有static final域和final域时,创建两个对象A1和A2时,在两个对象中,final域是不同的,但是static final域是唯一的。
即final针对对象中的域唯一,static针对是类中域唯一
final类型
-
空白final:
必须在域定义处或者每个构造器中用表达式对final进行赋值,这正是final域在使用前总是被初始化的原因所在。 -
final参数:
final参数意味着无法在方法中更改参数引用所指向的对象。 -
final方法:
使用final方法的原因:A.出于设计考虑,把方法锁定,以防任何集成类修改它的含义。
B.效率高,编译器将针对该方法的调用转为内嵌调用。(目前交由JVM处理效率问题)
最终,只有在想要明确禁止覆盖时,才将方法设置为final的。final和private关键字
类中所有的private方法都是隐式地指定为是final的,由于无法取用private方法,所以也就无法覆盖它。 -
final类:
当将某个类的整体定义为final时,就表明这个类不能被继承,不需要做任何变动。
在final类中的所有方法都隐式指定为final的,但是final类中的域并没有。
初始化及类的加载
每个类的编译代码都存在于它自己的独立的文件中,该文件只在需要使用程序代码时才会被加载。加载发生于创建类的第一个对象时,或者当访问static域或者static方法时,也会发生加载。更准确的说,
类是在任何static成员被访问时加载的。
继承与初始化
包含继承的初始化过程:
- 类中Java中运行时,发生第一件事情就是访问main()方法;
- 于是加载器开始启动并找出类的编译代码;
** 加载过程中,编译器发现该类还有基类,于是它继续加载基类的static初始化; - 类加载完后,对象就可以被创建,对象中所有的基本类型都会被设为默认值,对象引用被设为null--通过将对象内存设为二进制零值而产生的。
初始化顺序:
- 父类staic变量和static代码块。
- 子类staic变量和static代码块。
- 父类普通变量和代码块。
- 父类构造函数。
- 子类普通变量和代码块。
- 子类构造函数。