复用类
复用的方式包括组合和继承。
组合:在新的类中产生现有类的对象。
继承:采用现有类的形式,并添加新的代码。
7.1组合语法
将对象引用置于新类中即可。对象引用初始化的位置可以有:
1.在定义对象的地方。
2.在类构造器中。
3.在就要使用这些对象之前,这种当时被称为惰性初始化。
4.使用实例初始化。
7.2继承语法
当创建一个类时,总是在继承,如果没有明确指出要从其他类中继承,则隐式地继承Object类。
1.初始化基类
当创建了一个导出类对象的时候,该对象包含了一个基类的子对象。Java会自动在导出类的构造器中插入对基类构造器的调用。
基类构造器:总会被调用;在导出类构造之前别调用。
带参构造器:调用基类带参构造器,要用super(参数列表)形式。
/** * 调用基类默认构造器 * @author Administrator * */
public class Cartoon extends Drawing{
public Cartoon() {
System.out.println("Cartoon Constructed");
}
public static void main(String[] args) {
Cartoon cartoon = new Cartoon();
}
}
class Art{
Art() {
System.out.println("Art Constructed");
}
}
class Drawing extends Art{
Drawing() {
System.out.println("Drawing Constructed");
}
}
/** * 调用基类带参构造器 * @author Administrator * */
public class Chess extends BoardGame{
Chess() {
super(111);
System.out.println("Chess Constructed");
}
public static void main(String[] args) {
Chess chess = new Chess();
}
}
class Game{
Game(int i) {
System.out.println("Game Constructed");
}
}
class BoardGame extends Game{
BoardGame(int i) {
super(i);
System.out.println("BoardGame Constructed");
}
}
7.3代理
代理是组合和继承的折中,利用组合语法,来实现类似继承的功能。可以有选择性的对外暴露要继承类的方法。
/** * 代理--组合与继承的折中 * @author Administrator * */
public class SpaceShipDelegation {
private String name;
private SpaceShipControls controls =
new SpaceShipControls();
public SpaceShipDelegation(String name) {
this.name = name;
}
public void up(int velocity){
controls.up(velocity);
}
public void down(int velocity){
controls.up(velocity);
}
public static void main(String[] args) {
SpaceShipDelegation shipDelegation =
new SpaceShipDelegation("MyShip");
shipDelegation.up(100);
}
}
class SpaceShipControls{
void up(int velocity){
System.out.println("up"+velocity);
}
void down(int velocity){}
}
7.5在组合和继承之前选择
组合和继承都允许在新类中放置子对象,组合是显示地,而继承则是隐式地。
组合技术通常用于向在新类中使用现有类的功能而非它的接口这种情形。
继承是使用某个现有类,并开发它的一个特殊版本。
“is-a”表达继承关系。“has-a”表达组合关系。
7.6 protected关键字
前面说过,关键字protected通常用在继承中。
就类用户而言,这是private的,但对于任何继承于此类的导出类或其他任何位于同一个包内的类来说确实可以访问的。
最好将域保持为private,然后通过protected方法类控制类的继承者的访问权限。
7.7 向上转型
继承不仅为新类提供方法,其最重要的方面是用来表现新类和基类之间的关系。
把基类引用当做子类引用来使用的动作,称为向上转型。
组合和继承的选择:如果必须向上转型,则继承是必要的;如果不需要,就要考虑是否可以用组合代替。
7.8 final关键字
可能使用final的三种情况:数据,方法和类。
1.final数据
恒定不变的数据可以有:
- 一个永不改变的编译时常量。
- 一个再运行时初始化的值,而你不希望它被改变。
final修饰基本数据类型,表示数值恒定不变。
final修饰对象引用,表示引用指向永不改变(但是对象本身可以变化)。
一个既是static又是final的域只占据一段不能改变的空间。
/** * public 可以用于包外 * static 强调只有一份 * final 则说它是一个常量 */
public static final int value_Three = 39;
可以声明空白final,但使用时必须要初始化。
final参数:参数列表可以将参数声明为final,意味着无法再方法中更改参数引用所指向的对象。
2.final方法
将方法声明为final的原因有连个:
* 把方法锁定。想要确保在继承中使用方法行为保持不变,并且不会被覆盖。
* 效率。
类中所有的private方法都隐式地指定为final。
3.fina类
当将某个类定义为final时,就表明类永不需要变动,也不会有子类。
final类的方法都隐式指定为final。
7.9 初始化及加载类
Java中加载发生于创建类的第一个对象之时,访问static域或static方法时,也会发生加载。
首先访问静态方法,加载基类(如果有继承链,依次向上加载),然后加载自身类。
创建对象过程:数据初始化——调用基类构造器——初始化实例变量——调用本类构造器。