骨格実装 (Skeletal Implementation)
骨格実装 (Skeletal Implementation) とは何か
- 抽象クラスのうち、interface を implements し、このメソッド内容を定義したもの
目的は何か
- 骨格実装継承クラスの interface メソッド実装定義を手助けすること
骨格実装の構築方法, 利用方法
骨格実装 提供側
- 抽象クラスに interface を N 個 (N >= 1) implements する(A)
- override した interface のメソッドにて
- ドキュメンテーションを明確に記載する
- メソッド内容を定義する
- メソッド内容を実装者に委任したい場合は abstract メソッドにしておく
骨格実装 利用側
- (A) を継承したクラスを宣言する
- メソッド内容が定義されているものについて
- 必要があれば override して(ドキュメンテーションに従い) 実装を再定義する
- メソッドが abstract の場合
- ドキュメンテーションに従って実装を定義する
AbstractList.java より 骨格実装の一例
jdk1.8 src.zip 展開後の java/util/(List | AbstractList | ArrayList).java
より
E get(int index)
メソッド(骨格実装利用者にて実装委任)
と
void clear()
メソッド(骨格実装利用者にて実装再定義)
の内容確認
List.java (interface) X (implement) | AbstractList.java (骨格実装) Y (inherit) | ArrayList.java (骨格実装 利用者)
java/util/List.java (単純なインターフェース)
public interface List<E> extends Collection<E> { . . /** * Returns the element at the specified position in this list. * * @param index index of the element to return * @return the element at the specified position in this list * @throws IndexOutOfBoundsException if the index is out of range * (<tt>index < 0 || index >= size()</tt>) */ E get(int index); . . /** * Removes all of the elements from this list (optional operation). * The list will be empty after this call returns. * * @throws UnsupportedOperationException if the <tt>clear</tt> operation * is not supported by this list */ void clear(); }
java/util/AbstractList.java (骨格実装)
public abstract class AbstractList<E> extends AbstractCollection<E> implements List<E> { . . /** * {@inheritDoc} * * @throws IndexOutOfBoundsException {@inheritDoc} */ abstract public E get(int index); . . /** * Removes all of the elements from this list (optional operation). * The list will be empty after this call returns. * * <p>This implementation calls {@code removeRange(0, size())}. * * <p>Note that this implementation throws an * {@code UnsupportedOperationException} unless {@code remove(int * index)} or {@code removeRange(int fromIndex, int toIndex)} is * overridden. * * @throws UnsupportedOperationException if the {@code clear} operation * is not supported by this list */ public void clear() { removeRange(0, size()); } // ドキュメンテーション省略 protected void removeRange(int fromIndex, int toIndex) { ListIterator<E> it = listIterator(fromIndex); for (int i=0, n=toIndex-fromIndex; i<n; i++) { it.next(); it.remove(); } } }
(ここまで 骨格実装提供者の領分)
(ここから 骨格実装利用者の領分)
java/util/ArrayList.java (骨格実装 利用者が実装するクラス)
public class ArrayList<E> extends AbstractList<E> implements List<E>, RandomAccess, Cloneable, java.io.Serializable /** * Returns the element at the specified position in this list. * * @param index index of the element to return * @return the element at the specified position in this list * @throws IndexOutOfBoundsException {@inheritDoc} */ public E get(int index) { rangeCheck(index); return elementData(index); } // ドキュメンテーション省略 private void rangeCheck(int index) { if (index >= size) throw new IndexOutOfBoundsException(outOfBoundsMsg(index)); } . . /** * Removes all of the elements from this list. The list will * be empty after this call returns. */ public void clear() { modCount++; // clear to let GC do its work for (int i = 0; i < size; i++) elementData[i] = null; size = 0; } }