java中为什么Set接口的对象可以调用接口的方法?

HJMing123 2017-02-06 09:43:47
eg.

Map<String,String> map = new HashMap<>();
//...添加元素
Set<String> set = map.keySet();
Iterator it =set.iterator();


为什么这里set是一个接口为什么接口的一个对象可以调用接口里的方法,接口不是没有被实现吗?
...全文
192 6 打赏 收藏 转发到动态 举报
写回复
用AI写文章
6 条回复
切换为时间正序
请发表友善的回复…
发表回复
HJMing123 2017-02-07
  • 打赏
  • 举报
回复
引用 1 楼 baidu_34630879 的回复:

public Set<K> keySet() {
        Set<K> ks;
        return (ks = keySet) == null ? (keySet = new KeySet()) : ks;
    }

    final class KeySet extends AbstractSet<K> {
        public final int size()                 { return size; }
        public final void clear()               { HashMap.this.clear(); }
        public final Iterator<K> iterator()     { return new KeyIterator(); }
        public final boolean contains(Object o) { return containsKey(o); }
        public final boolean remove(Object key) {
            return removeNode(hash(key), key, null, false, true) != null;
        }
        public final Spliterator<K> spliterator() {
            return new KeySpliterator<>(HashMap.this, 0, -1, 0, 0);
        }
        public final void forEach(Consumer<? super K> action) {
            Node<K,V>[] tab;
            if (action == null)
                throw new NullPointerException();
            if (size > 0 && (tab = table) != null) {
                int mc = modCount;
                for (int i = 0; i < tab.length; ++i) {
                    for (Node<K,V> e = tab[i]; e != null; e = e.next)
                        action.accept(e.key);
                }
                if (modCount != mc)
                    throw new ConcurrentModificationException();
            }
        }
    }



学会看源码,这是HashMap类里的keySet()源码。
所以说是返回了一个内部类的对象,但是这算是用外部类的引用去接收内部类的一个对象吗
雨上小公举 2017-02-07
  • 打赏
  • 举报
回复
引用 楼主 HJMing123 的回复:
eg.
Map<String,String> map = new HashMap<>();
//...添加元素
Set<String> set = map.keySet();
Iterator it =set.iterator();
为什么这里set是一个接口为什么接口的一个对象可以调用接口里的方法,接口不是没有被实现吗?
接口里面的方法只要被定义(就算改方法没有被实现),只要用改接口对象去调用改接口方法,不会报错。 就好比ssM框架里面,在service层接口Interfacedemo 里面定义了一个方法 save(); 尽管serviceImpl里面没有重写save()方法,只要你在action层 Interfacedemo demo;//实例了 就可以调用save方法 demo.save();而action层不会报错。只是在service层会提示要去重写save方法而已
baidu_34630879 2017-02-07
  • 打赏
  • 举报
回复

public Set<K> keySet() {
        Set<K> ks;
        return (ks = keySet) == null ? (keySet = new KeySet()) : ks;
    }

    final class KeySet extends AbstractSet<K> {
        public final int size()                 { return size; }
        public final void clear()               { HashMap.this.clear(); }
        public final Iterator<K> iterator()     { return new KeyIterator(); }
        public final boolean contains(Object o) { return containsKey(o); }
        public final boolean remove(Object key) {
            return removeNode(hash(key), key, null, false, true) != null;
        }
        public final Spliterator<K> spliterator() {
            return new KeySpliterator<>(HashMap.this, 0, -1, 0, 0);
        }
        public final void forEach(Consumer<? super K> action) {
            Node<K,V>[] tab;
            if (action == null)
                throw new NullPointerException();
            if (size > 0 && (tab = table) != null) {
                int mc = modCount;
                for (int i = 0; i < tab.length; ++i) {
                    for (Node<K,V> e = tab[i]; e != null; e = e.next)
                        action.accept(e.key);
                }
                if (modCount != mc)
                    throw new ConcurrentModificationException();
            }
        }
    }



学会看源码,这是HashMap类里的keySet()源码。
baidu_34630879 2017-02-07
  • 打赏
  • 举报
回复
引用 3 楼 HJMing123 的回复:
[quote=引用 1 楼 baidu_34630879 的回复:]

public Set<K> keySet() {
        Set<K> ks;
        return (ks = keySet) == null ? (keySet = new KeySet()) : ks;
    }

    final class KeySet extends AbstractSet<K> {
        public final int size()                 { return size; }
        public final void clear()               { HashMap.this.clear(); }
        public final Iterator<K> iterator()     { return new KeyIterator(); }
        public final boolean contains(Object o) { return containsKey(o); }
        public final boolean remove(Object key) {
            return removeNode(hash(key), key, null, false, true) != null;
        }
        public final Spliterator<K> spliterator() {
            return new KeySpliterator<>(HashMap.this, 0, -1, 0, 0);
        }
        public final void forEach(Consumer<? super K> action) {
            Node<K,V>[] tab;
            if (action == null)
                throw new NullPointerException();
            if (size > 0 && (tab = table) != null) {
                int mc = modCount;
                for (int i = 0; i < tab.length; ++i) {
                    for (Node<K,V> e = tab[i]; e != null; e = e.next)
                        action.accept(e.key);
                }
                if (modCount != mc)
                    throw new ConcurrentModificationException();
            }
        }
    }



学会看源码,这是HashMap类里的keySet()源码。
所以说是返回了一个内部类的对象,但是这算是用外部类的引用去接收内部类的一个对象吗 [/quote] 不是,跟着看源码,内部类KeySet 继承了 AbstractSet类,而AbstractSet类又实现了Set接口。内部类KeySet就是多态的,所以返回的对象可以被类型Set接收。
逗泥丸的平方 2017-02-07
  • 打赏
  • 举报
回复
你这个例子中是想说set.iterator(); 吗? 接口的好处就是为了让你不再关心实现. 即,无论这是哪种set,只要遵循Set的规范,都可以使用迭代器.
逗泥丸的平方 2017-02-07
  • 打赏
  • 举报
回复
这句话说反了... 不能叫可以调用接口的方法 而是,你在使用接口声明的对象只能使用该接口中声明的方法 接口总是要实现的.. 如果你在当前类中看不到 可以去找他的父类.

62,628

社区成员

发帖
与我相关
我的任务
社区描述
Java 2 Standard Edition
社区管理员
  • Java SE
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧