JAVA的四種內部類及爲什麼要用內部類

        最近在看java的源碼,但是時長能看一個類中都會有幾個內部類比如LinkedList中
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();
        }
    }
這個內部類+接口就很好的實現了多繼承
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章