Java:复用类

组合+继承是两种常用的复用代码的方法,本文结合《编程思想》的内容,对java的代码复用做点小小的分析和总结。

一、组合

skipped!

二、继承

skipped!

三、代理

代理:继承与组合的一种折中。因为:我们将一个成员对象放在要构造的类中(就像组合),同时在新类中暴露了该类成员变量的所有方法(就像继承)

借用《编程思想》造飞船的例子:
我们定义了一个SpaceShipControls(飞船控制模块),显然SpaceShip(飞船)应具有这个模块对应的功能,但是二者不具有父子关系,用继承来SpaceShip具有模块的行为显然不合适,此时,应使用组合的方式,同时SpaceShipControls向Spaceship暴露了所有的方法,很像继承;这种方式就是“代理”!

public class SpaceShipControls {
    void up(int velocity) {}
    void down(int velocity) {}
    void left(int velocity) {}
}

/**
 * 这不是真正的“飞船”对象,而是“控制模块”的代理,这个代理具有“飞船”的部分特征。
 * 由于有了“控制模块“的引用,代理也能有”控制“的功能
 */
 public class SpaceShipDelegation {
    
    private SpaceShipControls spaceShipControls;

    public SpaceShipDelegation(SpaceShipControls spaceShipControls) {
        this.spaceShipControls = spaceShipControls;
    }

    void up(int velocity) {
        spaceShipControls.up(velocity);
    }
    void down(int velocity) {
        spaceShipControls.down(velocity);
    }
    void left(int velocity) {
        spaceShipControls.left(velocity);
    }
}

四、组合与继承

组合和继承都允许在新的类中放子对象(subObjects),组合是显式这样做,而继承是隐式如此。
1、组合
组合通常用于想在新类中使用现有类的功能而不是它的接口这种场景。就是说:在新类中持有原有类的引用,让其实现所需功能,但新类用户只能看到为新类所定义的接口,而不是原有类对象的接口。

一言以蔽之:组合表达的是“ has a” 的关系

2、继承
继承时,实际是父类向子类暴露了接口,这也是继承的目的!
一言以蔽之: 继承表达的是“ is a” 的关系。

如何甄选?
总体上,使用组合更合适,继承不太常用。讲OOP的时候,我们强调继承,但使用时应审慎。一个最清晰的判断: 是否需要从新类 upcast 成基类。若必须upcast,则继承是必要的,若不需要,则应三思继承的必要性。

五、protected

protected : 子类或者包内可见。

more details ,skipped !

六、Final关键字

存在意义:告诉编译器有块数据是恒定不变的。
比如:
a)一个永不改变的编译时常量 --> static final 修饰的变量
b)一个运行时被初始化的值,我们不希望它被改变。

1、final域
一个static final的域 占据一段不能改变的存储空间,不然怎么叫常量呢?
final修饰的域只能赋值一次,对于基本数据类型,final使数值恒定;而对于引用类型,final使引用恒定不变。
不过呢,final 变量只要求在使用前被初始化就可以了,并不是必须在声明的时候就必须初始化。比如在构造函数中初始化。

2、final 参数
比如将方法定义成:
void f(final String s ){}
这样表示无法在方法中更改引用所指向的对象。

3、final 方法
final修饰的方法被override,但是可以被overload。
可见,private方法肯定都是final(隐式)的。

七、初始化及类的加载

Java中所有事物都是对象。每个类的编译代码都存在于它自己的独立文件中。该文件只在需要使用代码时才会被加载。简单说就是:类的代码在初次使用时才加载,这通常指加载发生于创建类的第一个对象之时,且当访问static 域或 方法时,也会发生加载。

八、总结

  • 组合、继承都能生成新类型。
    不过,组合:将现有类型作为新类型底层实现的一部分来复用;
    继承:复用接口。
  • 继承是OOP的特性,但实际写代码时,组合灵活性更高,应优先选择。
  • 设计系统时,目标应是找到或创建某些类,每个类各有用途,不会太大(功能太多),不会太小(不添加功能就没法用)。对于一个过于复杂的设计,将类拆分分更小的部分而添加更多的对象通常会有帮助。

猜你喜欢

转载自blog.csdn.net/qq_30118563/article/details/83066672