组合与继承

来源:互联网 发布:上班记录软件 编辑:程序博客网 时间:2024/05/20 20:02

    组合和继承,都是在新类中直接复用旧类的方法,实现系统功能重用。但是各有不同的特点。继承会破坏封装。组合能提供更好的封装性。各有优缺点,总得来说,多用组合,少用继承。

继承:

    子类扩展父类,继承父类的字段和方法,如果访问权限允许,子类可以直接访问父类的字段和方法,很方便,但也破坏了父类的封装性。每个类都应该封装内部信息和实现,只暴漏必要的方法给其他类使用。但继承子类可以直接访问父类内部信息。


    保证父类良好封装性的设计原则

        1.尽量隐藏父类内部数据

        2.不要让子类可以随意访问,修改父类方法

            Private:子类无法访问

            Protected:非子类不能自由访问

            Final:子类不能重写

         3.尽量不要在父类的构造器中调用将要被子类重写的方法


    何时从父类派生新的子类:

         1.子类需要额外增加属性,而不仅仅是属性值的改变。

         2.子类需要增加自己独特的行为方式。


    继承是在编译时刻静态定义的,即是静态复用


组合:

    该类当成另一个类的组合成分,允许新类直接复用该类的Public方法。


    组合把旧类对象作为新类的Field嵌入,实现新类的功能,用户看到的是新类的方法。新类中使用private修饰嵌入的旧类对象。


    组合是在运行时才确定的,增加了程序的灵活性。



用EA生成的代码框架

public class Animal {public Animal(){}private void beat(){}public void breath(){}}public class Bird {<strong>public Animal m_Animal;</strong>public Bird(){}public void breath(){}public void fly(){}}public class Wolf {<strong>public Animal m_Animal;</strong>public Wolf(){}public void breath(){}public void run(){}}

完善代码:
class Animal{private void beat(){System.out.println("心脏跳动。。。");}public void breath(){beat();System.out.println("吸一口气,吐一口气,呼吸中");}}class Bird{//原来父类嵌入子类,作为子类的组合成分;private Animal a;public Bird(Animal a){this.a=a;}//定义自己的breath方法;public void breath(){//直接复用父类的Breath来实现子类的Breath;a.breath();}public void fly(){System.out.println("我在天空自在的飞翔");}}class Wolf{//原来父类嵌入子类,作为子类的组合成分;private Animal a;public Wolf(Animal a){this.a=a;}//定义自己的breath方法;public void breath(){//直接复用父类的Breath来实现子类的Breath;a.breath();}public void run(){System.out.println("我在陆地上快速奔跑");}}public class CompositeTest {public static void main(String[] args){//显示创建嵌入的对象Animal a1 = new Animal ();Bird b = new Bird(a1);b.breath();b.fly();//显示创建嵌入的对象Animal a2 = new Animal();Wolf w = new Wolf(a2);w.breath();w.run();}}
运行结果:


总结:

       多用组合,少用继承。组合将对象作为新类的Field,运行时创建对象,增加程序的灵活性,但是整体类创建时,需要创建所有的局部对象。继承让子类很便捷的拥有父类的信息,破坏了父类的封装性。组合和继承各有优缺点,在实际开发中应落实实际情况,发展的眼光,选择相对合适的。

0 0