定义:
- 组合:在新类中new 另外一个类的对象,以添加该对象的特性。
- 继承:从基类继承得到子类,获得基类的特性。
- 代理:在代理类中创建某功能的类,调用类的一些方法以获得该类的部分特性
场合:
组合:各部件之间没什么关系,只需要组合即可。like组装电脑,需要new CPU(),new RAM(),new Disk()……
public class Computer { public Computer() { CPU cpu=new CPU(); RAM ram=new RAM(); Disk disk=new Disk(); } } class CPU{ } class RAM{ } class Disk{ }
-
- 优点: 当前对象只能通过所包含的那个对象去调用其方法,所以所包含的对象的内部细节对当前对象时不可见的。
当前对象与包含的对象是一个低耦合关系,如果修改包含对象的类中代码不需要修改当前对象类的代码。
当前对象可以在运行时动态的绑定所包含的对象。可以通过set方法给所包含对象赋值。
-
缺点:①:容易产生过多的对象。②:为了能组合多个对象,必须仔细对接口进行定义。
- 优点: 当前对象只能通过所包含的那个对象去调用其方法,所以所包含的对象的内部细节对当前对象时不可见的。
- 继承:子类需要具有父类的功能,各子类之间有所差异。like Shape类作为基类,子类有Rectangle,CirCle,Triangle……
- 优点:子类可以重写父类的方法来方便地实现对父类的扩展
- 缺点:父类的内部细节对子类是可见的。
子类从,,父类继承的方法在编译时就确定下来了,所以无法在运行期间改变从父类继承的方法的行为。
如果对父类的方法做了修改的话(比如增加了一个参数),则子类的方法必须做出相应的修改。所以说子类与父类是一种高耦合,违背了面向对象思想。
- 代理:飞机控制类,我不想暴露太多飞机控制的功能,只需部分前进左右转的控制(而不需要暴露发射导弹功能)。通过在代理类中new一个飞机控制对象,然后在方法中添加飞机控制类的各个需要暴露的功能
public class PlaneDelegation{ private PlaneControl planeControl; //private外部不可访问 /* * 飞行员权限代理类,普通飞行员不可以开火 */ PlaneDelegation(){ planeControl=new PlaneControl(); } public void speed(){ planeControl.speed(); } public void left(){ planeControl.left(); } public void right(){ planeControl.right(); } } final class PlaneControl {//final表示不可继承,控制器都能继承那还得了。。 protected void speed() {} protected void fire() {} protected void left() {} protected void right() {} }
代理可参考:https://www.cnblogs.com/machine/archive/2013/02/21/2921345.html - 组合可以被说成“我请了个老头在我家里干活” ,继承则是“我父亲在家里帮我干活"。
建议在同样可行的情况下,优先使用组合而不是继承。
因为组合更安全,更简单,更灵活,更高效。
- 继承要慎用,其使用场合仅限于你确信使用该技术有效的情况。一个判断方法是,问一问自己是否需要从新类向基类进行向上转型。如果是必须的,则继承是必要的。反之则应该好好考虑是否需要继承。《Java编程思想》
- 只有当子类真正是超类的子类型时,才适合用继承。换句话说,对于两个类A和B,只有当两者之间确实存在is-a关系的时候,类B才应该继续类A。《Effective Java》
-
参考:http://blog.csdn.net/yangquanhui1991/article/details/49684309