【程序员】看了这篇你将彻底了解组合模式( 三 )

boss.addSubordinate(RDManger); boss.addSubordinate(marketingManager); RDManger.addSubordinate(group1); RDManger.addSubordinate(group2); group1.addSubordinate(programmer1); group1.addSubordinate(programmer2); group2.addSubordinate(programmer3); group2.addSubordinate(programmer4); boss.notifyStaff("今晚加班","来开会");// System.out.println(boss.getInfo);// System.out.println(getAllInfo(boss)); } public static String getAllInfo(Manager manager){ ArrayList subordinateList = manager.getSubordinate; String info = ""; for(Staff s:subordinateList){ if(s instanceof Programmer){ info = info + s.getInfo +"\n"; }else { info = info +s.getInfo +"\n" + getAllInfo((Manager)s); } } return info; }} 程序运行结果:
张三,研发部经理,来开会王五,研发部组长一,来开会小强,java程序员,今晚加班小华,java程序员,今晚加班赵六,研发部组长二,来开会小甲,python程序员,今晚加班小乙,c++程序员,今晚加班李四,市场部经理,来开会 上面程序的类图如下:
【程序员】看了这篇你将彻底了解组合模式
本文插图

【程序员】看了这篇你将彻底了解组合模式
本文插图
有何问题?
上面的程序乍一看似乎没有什么问题 , 而且我们也把管理者和普通员工类里的共性封装起来了 , 但有基础的同学或许看出来了 , 程序没有很好的进行代码复用 , 虽然把获取个人信息的getInfo方法和接收通知的doSomething方法在顶层接口中封装了 , 但它们在不同的实现类中代码完全一样(只是将个人信息和接收到的通知打印出来) , 为什么不抽象出来用抽象类实现呢?在这里就要了解一下接口和抽象类的异同点 , 以及它们分别在什么情况下使用 。
1.相同点:
(1) 都是上层的抽象层
(2)都不能被实例化
(3 )都能包含抽象方法
(4)抽象类中的抽象方法必须全部被子类实现 , 如果没有全部实现 , 那么子类也必须是抽象类 。 接口中的方法也必须全部被子类实现 , 如果没有全部实现 , 子类必须是抽象类 。
2.不同点:
(1)方法不同:在抽象类中除了抽象方法之外还可以写非抽象方法(但至少要有一个抽象方法) , 从而避免在实现类中重复写 , 提高代码复用性 。 接口中只能有抽象类(只是方法的声明 , 没有实现) 。
(2)实现方法不同:java中只能单继承 , 即一个类只能继承一个抽象类 。 但一个类可以实现多个接口 。
(3)抽象程度不同:由高到低 , 接口>抽象类>实现类 。 可以说抽象类是接口的中庸之道 , 我们在使用的时候应该优先选择抽象类 。
(4)接口是对动作的抽象 , 而抽象类是对根源类别的抽象 , 接口强调的是有没有的关系 , 抽象类强调的是是不是的关系 。 例如猴子都会爬树和吃香蕉 , 这是猴子的共性 , 可以抽象出抽象类 , 每个子类都会实现这两个方法 。 但只有经过训练的猴子才会骑自行车 , 骑自行车这个方法就不能放在抽象类中 , 因为子类需要实现所有的抽象方法 , 明显不是所有猴子都会骑自行车 , 所有要将这个方法放在一个接口中 , 让那些会骑自行车的猴子实现这个接口 。