標籤:java 介面 抽象類別
今天看到一道題問下面哪一個是抽象類別,給出四個選項:
InputStream, PrintStream, Reader, FileWriter
然後我覺得這太簡單了,顯然是InputStream和Reader,都是處在接近頂尖的東西。但同時我覺得應該總結下對於介面和抽象類別的理解。
一. Java 抽象類別
下面貼出 AbstractCollection的抽象類別源碼,大家不必看細節;
package java.util;public abstract class AbstractCollection<E> implements Collection<E> { protected AbstractCollection() {} public abstract Iterator<E> iterator(); public abstract int size(); public boolean isEmpty() { return size() == 0; } public boolean contains(Object o) { Iterator<E> it = iterator(); if (o==null) { while (it.hasNext()) if (it.next()==null) return true; } else { while (it.hasNext()) if (o.equals(it.next())) return true; } return false; } public Object[] toArray() { // Estimate size of array; be prepared to see more or fewer elements Object[] r = new Object[size()]; Iterator<E> it = iterator(); for (int i = 0; i < r.length; i++) { if (! it.hasNext()) // fewer elements than expected return Arrays.copyOf(r, i); r[i] = it.next(); } return it.hasNext() ? finishToArray(r, it) : r; } public <T> T[] toArray(T[] a) { // Estimate size of array; be prepared to see more or fewer elements int size = size(); T[] r = a.length >= size ? a : (T[])java.lang.reflect.Array .newInstance(a.getClass().getComponentType(), size); Iterator<E> it = iterator(); for (int i = 0; i < r.length; i++) { if (! it.hasNext()) { // fewer elements than expected if (a == r) { r[i] = null; // null-terminate } else if (a.length < i) { return Arrays.copyOf(r, i); } else { System.arraycopy(r, 0, a, 0, i); if (a.length > i) { a[i] = null; } } return a; } r[i] = (T)it.next(); } // more elements than expected return it.hasNext() ? finishToArray(r, it) : r; } private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8; private static <T> T[] finishToArray(T[] r, Iterator<?> it) { int i = r.length; while (it.hasNext()) { int cap = r.length; if (i == cap) { int newCap = cap + (cap >> 1) + 1; // overflow-conscious code if (newCap - MAX_ARRAY_SIZE > 0) newCap = hugeCapacity(cap + 1); r = Arrays.copyOf(r, newCap); } r[i++] = (T)it.next(); } // trim if overallocated return (i == r.length) ? r : Arrays.copyOf(r, i); } private static int hugeCapacity(int minCapacity) { if (minCapacity < 0) // overflow throw new OutOfMemoryError ("Required array size too large"); return (minCapacity > MAX_ARRAY_SIZE) ? Integer.MAX_VALUE : MAX_ARRAY_SIZE; } public boolean add(E e) { throw new UnsupportedOperationException(); } public boolean remove(Object o) { Iterator<E> it = iterator(); if (o==null) { while (it.hasNext()) { if (it.next()==null) { it.remove(); return true; } } } else { while (it.hasNext()) { if (o.equals(it.next())) { it.remove(); return true; } } } return false; } public boolean containsAll(Collection<?> c) { for (Object e : c) if (!contains(e)) return false; return true; } public boolean addAll(Collection<? extends E> c) { boolean modified = false; for (E e : c) if (add(e)) modified = true; return modified; } public boolean removeAll(Collection<?> c) { boolean modified = false; Iterator<?> it = iterator(); while (it.hasNext()) { if (c.contains(it.next())) { it.remove(); modified = true; } } return modified; } public boolean retainAll(Collection<?> c) { boolean modified = false; Iterator<E> it = iterator(); while (it.hasNext()) { if (!c.contains(it.next())) { it.remove(); modified = true; } } return modified; } public void clear() { Iterator<E> it = iterator(); while (it.hasNext()) { it.next(); it.remove(); } } public String toString() { Iterator<E> it = iterator(); if (! it.hasNext()) return "[]"; StringBuilder sb = new StringBuilder(); sb.append(‘[‘); for (;;) { E e = it.next(); sb.append(e == this ? "(this Collection)" : e); if (! it.hasNext()) return sb.append(‘]‘).toString(); sb.append(‘,‘).append(‘ ‘); } }}
AbstractCollection實現了Collection介面,並且定義了很多方法和變數,具體觀察會發現:
1. 抽象類別中有抽象方法和非抽象方法;抽象方法會有abstract修飾,同時必須為public或者protected(因為如果為private,則不能被子類繼承,子類便無法實現該方法),預設情況下預設為public。沒有大括弧和具體實現。
2. 抽象類別中的成員變數可以是各種類型。
3. 抽象類別不能執行個體化,如果一個類繼承於一個抽象類別,則子類必須實現父類的抽象方法。如果子類沒有實現父類的抽象方法,則必須將子類也定義為為abstract類
二. Java 介面
下面貼出Collection介面源碼,可以和上面AbstractCollection進行對照:
package java.util;public interface Collection<E> extends Iterable<E> { int size(); boolean isEmpty(); boolean contains(Object o); Iterator<E> iterator(); Object[] toArray(); <T> T[] toArray(T[] a); boolean add(E e); boolean remove(Object o); boolean containsAll(Collection<?> c); boolean addAll(Collection<? extends E> c); boolean removeAll(Collection<?> c); boolean retainAll(Collection<?> c); void clear(); boolean equals(Object o); int hashCode(); }
Collection介面負責聲明一些常用的方法,由此我們總結出:
1. 介面中只有抽象方法,並且會被隱式地指定為public abstract方法且只能是public abstract方法;介面中不能含有靜態代碼塊以及靜態方法
2. 介面中的變數會被隱式地指定為public static final變數。
3. 介面同樣不能執行個體化,一個類只可以繼承一個抽象類別,同時可以實現多個介面。而介面可以繼承其他介面。
public class ArrayList<E> extends AbstractList<E> implements List<E>, RandomAccess, Cloneable, java.io.Serializable{}public abstract class AbstractList<E> extends AbstractCollection<E> implements List<E> {}public interface List<E> extends Collection<E> {}
通過分析Java的源碼,比如常用的ArrayList,它繼承於AbstractList,實現了List等介面;AbstractList繼承於AbstractCollection實現了List介面;介面List繼承了Collection介面。 所以能夠發現這是一個非常好的設計模式,介面負責聲明Java類的一些方法,然後定義一個抽象類別去實現這個介面;介面在最頂層,下面是抽象類別。根據功能不同繼承某一介面或實現某些抽象類別。
著作權聲明:本文為博主原創文章,未經博主允許不得轉載。
Java 介面與抽象類別