7.41慎重な使用方法のリロード(overloading)

2016 ワード

次のクラスは、異なるコレクションタイプを分類し、classify()メソッドを再ロードします.
 
public class CollectionClassifier {
	public static String classify(Set<?> s){
		return "Set";
	}
	
	public static String classify(Collection<?> c){
		return "Collection";
	}
}

 
 
次のテストは失敗します.
	@Test
	public void testCollectionClassifier(){
		Collection<String>  c=new HashSet<String>();
		
		// c Collection , ,
		// classify(Collection<?> c)
		Assert.assertEquals(CollectionClassifier.classify(c), "Set");
	}

 
リロードメソッドの選択は、コンパイル時に決定され(すなわち静的選択であり、オーバーライドメソッドの選択は実行時に選択された、すなわち動的選択である)、リロードされたメソッドが同じパラメータ個数を有し、パラメータタイプ間に継承関係(例えば、前述のパラメータタイプSetがCollectionを継承する)がある場合、問題になる可能性がある.
 
Listのremove(int)、remove(Object)にはリロードが使用されており、Listタイプについては、remove()メソッドを呼び出す際に区別に注意してください.
	@Test
	public void testList(){
		List<Integer> list=new ArrayList<Integer>();
		
		//-1,0,1 Integer 
		list.add(-1);
		list.add(0);
		list.add(1);
		
		// int 1, list.remove(int)
		Assert.assertEquals(list.remove(1), Integer.valueOf(0));
		
		// Integer , list.remove(Object)
		Assert.assertEquals(list.remove(Integer.valueOf(1)), true);
	}

 
使用方法の再ロードの基本原則:
1.リロードの方法は異なるパラメータの個数を持つべきである
 
2.リロード方法が同じパラメータ個数を持つ場合、パラメータのデータ型間に継承関係があるべきではない
 
3.複数のリロードされたコンストラクション関数を回避するために、異なる名前の静的ファクトリメソッドを使用する
 
4.再ロードを回避できないメソッドのパラメータの数が同じで、パラメータ間に継承関係がある場合.では、同じリロードメソッドを呼び出して、すべてのリロードメソッドが同じ機能を実現することを保証する必要があります.JDK 5がCharSequenceインタフェースを追加した場合、StringはcontentEquals(StringBuffer)、contentEquals(CharSequence)をリロードする方法が避けられない.しかし前者は後者を直接呼び出して比較する(String,StringBufferともにCharSequenceインタフェースを実現する)
 
5.変長パラメータを持つ方法をリロードしない