9.5.6 自己写算法

9.5.6 自己写算法

当你要写一个接收一个集合类对象作为参数的方法的时候,在方法中要尽量操作接口而不是具体实现。例如,假设你想要用一系列menu item去填充一个JMenu。自然而然的想法会是这样:

void fillMenu(JMenu menu, ArrayList<JMenuItem> items){
	for(JMenuItem item: items)
		menu.add(item);
	}

这样的实现对该方法的调用者施加了不必要的约束:调用者必须提供一个ArrayList。如果调用者需要处理另一个容器,就只能把它重新包装成ArrayList才能使用你的方法。让你的方法接收一个更通用的容器就好得多。
你应该问问你自己:能够完成这项操作的最通用的接口是什么?在这个例子中,你只需要能够访问所有元素而已,这是基本的Collection接口就能提供的功能。考虑过这些之后,你应该重写fillMenu方法来接收任何一个集合类:

void fillMenu(JMenu menu, Collection<JMenuItem> items){
	for(JMenuItem item: items)
		menu.add(item);
	}

现在,任何人都能使用ArrayList或者LinkedList来调用该方法。甚至是使用Arrays.asList包装的数组也能作为该方法的参数。

Note
如果使用接口作为方法参数这么好,为什么标准库不总是这么干呢?例如JComboBox有两个构造方法:
JComboBox(Object[] items)
JComboBox(Vector<?> items)
原因在时间上,Swing库创建的时间要早于集合类库。所以一开始只有第一条构造方法,在集合类库加入后,又有了第二条构造方法。

当你编写返回一个集合类对象的方法时,你也希望能返回一个接口而不是类,这样在将来你可以更改这个方法的实现并返回一个不同的类。
例如,我们编写方法getAllItems返回一个menu中的所有item:

List<JMenuItem> getAllItems(JMenu menu){
	List<JMenuItem> items = new ArrayList<>();
	for(int i = 0; i < menu.getItemCount(); i++)
		items.add(menu.getItem(i));
	return items;
}

之后,你可能决定不再复制menu中的Item到新的内存,而仅仅提供一个视窗来查看这些Item。这可以通过返回一个AbstractList的匿名子类来实现:

List<JMenuItem> getAllItems(final JMenu menu){
	return new AbstractList<>(){
		public JMenuItem get(int i){return menu.getItem(i);}
		public int size(){return menu.getItemCount();}
	};
}

你就需要在方法的说明文档中明确指出哪些操作是可行的。在本例中,你必须告知调用者,该方法返回的List对象是不可修改的。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值