7.41慎重な使用方法のリロード(overloading)
2016 ワード
次のクラスは、異なるコレクションタイプを分類し、classify()メソッドを再ロードします.
次のテストは失敗します.
リロードメソッドの選択は、コンパイル時に決定され(すなわち静的選択であり、オーバーライドメソッドの選択は実行時に選択された、すなわち動的選択である)、リロードされたメソッドが同じパラメータ個数を有し、パラメータタイプ間に継承関係(例えば、前述のパラメータタイプSetがCollectionを継承する)がある場合、問題になる可能性がある.
Listのremove(int)、remove(Object)にはリロードが使用されており、Listタイプについては、remove()メソッドを呼び出す際に区別に注意してください.
使用方法の再ロードの基本原則:
1.リロードの方法は異なるパラメータの個数を持つべきである
2.リロード方法が同じパラメータ個数を持つ場合、パラメータのデータ型間に継承関係があるべきではない
3.複数のリロードされたコンストラクション関数を回避するために、異なる名前の静的ファクトリメソッドを使用する
4.再ロードを回避できないメソッドのパラメータの数が同じで、パラメータ間に継承関係がある場合.では、同じリロードメソッドを呼び出して、すべてのリロードメソッドが同じ機能を実現することを保証する必要があります.JDK 5がCharSequenceインタフェースを追加した場合、StringはcontentEquals(StringBuffer)、contentEquals(CharSequence)をリロードする方法が避けられない.しかし前者は後者を直接呼び出して比較する(String,StringBufferともにCharSequenceインタフェースを実現する)
5.変長パラメータを持つ方法をリロードしない
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
@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.変長パラメータを持つ方法をリロードしない