JAVA的四種內部類及為什麼要用內部類
阿新 • • 發佈:2018-12-26
最近在看java的原始碼,但是時長能看一個類中都會有幾個內部類比如LinkedList中 可以訪問外部類中所有的成員,包含私有。
四 匿名內部類
1.沒有名字的區域性內部類。
2.沒有class,interface,implements,extends關鍵字
3.沒有構造器。
private class ListItr implements ListIterator<E> { private Node<E> lastReturned; private Node<E> next; private int nextIndex; private int expectedModCount = modCount; ListItr(int index) { // assert isPositionIndex(index); next = (index == size) ? null : node(index); nextIndex = index; } public boolean hasNext() { return nextIndex < size; } public E next() { checkForComodification(); if (!hasNext()) throw new NoSuchElementException(); lastReturned = next; next = next.next; nextIndex++; return lastReturned.item; } public boolean hasPrevious() { return nextIndex > 0; } public E previous() { checkForComodification(); if (!hasPrevious()) throw new NoSuchElementException(); lastReturned = next = (next == null) ? last : next.prev; nextIndex--; return lastReturned.item; } public int nextIndex() { return nextIndex; } public int previousIndex() { return nextIndex - 1; } public void remove() { checkForComodification(); if (lastReturned == null) throw new IllegalStateException(); Node<E> lastNext = lastReturned.next; unlink(lastReturned); if (next == lastReturned) next = lastNext; else nextIndex--; lastReturned = null; expectedModCount++; } public void set(E e) { if (lastReturned == null) throw new IllegalStateException(); checkForComodification(); lastReturned.item = e; } public void add(E e) { checkForComodification(); lastReturned = null; if (next == null) linkLast(e); else linkBefore(e, next); nextIndex++; expectedModCount++; } public void forEachRemaining(Consumer<? super E> action) { Objects.requireNonNull(action); while (modCount == expectedModCount && nextIndex < size) { action.accept(next.item); lastReturned = next; next = next.next; nextIndex++; } checkForComodification(); } final void checkForComodification() { if (modCount != expectedModCount) throw new ConcurrentModificationException(); } } private static class Node<E> { E item; Node<E> next; Node<E> prev; Node(Node<E> prev, E element, Node<E> next) { this.item = element; this.next = next; this.prev = prev; } }
然後就開始想為什麼java本身中要用內部類呢?
首先介紹下四種內部類
- 成員內部類
- 靜態內部類
- 區域性內部類
- 匿名內部類
一 成員內部類
1.沒有使用static修飾的內部類。
2.在成員內部類中不允許出現靜態變數和靜態方法的宣告。static只能用在靜態常量的宣告上。
3.成員內部類中可以訪問外部類中所有的成員(變數,方法),包含私有成員,如果在內部類中定義有和外部類同名的例項變數,訪問:OuterClass.this.outerMember;
4.構建內部類的例項,要求必須外部類的例項先存在
外部類的外部/外部類的靜態方法:new Outer().new Inner();
外部類的例項方法:new Inner();this.new Inner();
二 靜態內部類
1.宣告在類體部,方法體外,並且使用static修飾的內部類
2.訪問特點可以類比靜態變數和靜態方法
3.脫離外部類的例項獨立建立
在外部類的外部構建內部類的例項 new Outer.Inner();
在外部類的內部構建內部類的例項 new Inner();
4.靜態內部類體部可以直接訪問外部類中所有的靜態成員,包含私有
三 區域性內部類
1.定義在方法體,甚至比方法體更小的程式碼塊中
2.類比區域性變數。
3.區域性內部類是所有內部類中最少使用的一種形式。
4.區域性內部類可以訪問的外部類的成員根據所在方法體不同。
如果在靜態方法中:可以訪問外部類中所有靜態成員,包含私有
如果在例項方法中:
區域性內部類可以訪問所在方法中定義的區域性變數,但是要求區域性變數必須使用final修飾。
四 匿名內部類
1.沒有名字的區域性內部類。2.沒有class,interface,implements,extends關鍵字
3.沒有構造器。
4.一般隱式的繼承某一個父類或者實現某一個介面
介紹完四種內部類後來說下我理解的為什麼要用內部類
1 起到更好的封裝作用,不讓你知道具體實現細節,神祕感很足,比如:
private static class Node<E> {
E item;
Node<E> next;
Node<E> prev;
Node(Node<E> prev, E element, Node<E> next) {
this.item = element;
this.next = next;
this.prev = prev;
}
}
這個就是LinkedList中的內部類,也是連結串列結果的實現所需要的類
2 能巧妙躲過java中只能單繼承的弊端,比如:
private class DescendingIterator implements Iterator<E> {
private final ListItr itr = new ListItr(size());
public boolean hasNext() {
return itr.hasPrevious();
}
public E next() {
return itr.previous();
}
public void remove() {
itr.remove();
}
}
這個內部類+介面就很好的實現了多繼承