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类的一些方法,然后定义一个抽象类去实现这个接口;接口在最顶层,下面是抽象类。根据功能不同继承某一接口或实现某些抽象类。

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2024-08-03 16:11:07

Java 接口与抽象类的相关文章

Java接口和抽象类有什么区别,哪些时候用接口,哪些时候用抽象类?

Java接口和抽象类有什么区别,哪些时候用接口,哪些时候用抽象类? 2013-01-05 17:16:09|  分类: JAVA |  标签:java  |举报|字号 订阅 下面比较一下两者的语法区别:1.抽象类可以有构造方法,接口中不能有构造方法.2.抽象类中可以有普通成员变量,接口中没有普通成员变量3.抽象类中可以包含非抽象的普通方法,接口中的所有方法必须都是抽象的,不能有非抽象的普通方法.4. 抽象类中的抽象方法的访问类型可以是public,protected和(默认类型,虽然eclips

初探设计:Java接口和抽象类何时用?怎么用?

今天犯了个错: “接口变动,伤筋动骨,除非你确定只有你一个人在用”.哪怕只是throw了一个新的Exception.哈哈,这是我犯的错误. 一.接口和抽象类 类,即一个对象. 先抽象类,就是抽象出类的基础部分,即抽象基类(抽象类).官方定义让人费解,但是记忆方法是也不错的 — 包含抽象方法的类叫做抽象类. 接口就是把抽象的深度更深,它就像用简短的非逻辑的一些规则表示类之间的关系.可以比作协议,比如通信使用的UDP/TCP协议等. 小结:类与接口是Java语言的基本抽象单元. 二.为什么有接口的两

浅谈Java接口和抽象类的区别

面向对象的设计,服用的重点其实应该是抽象层的复用,而不是具体某一个代码块的复用. 说到了抽象,就不得不提到Java接口和Java抽象类了,这也是我这里想要谈论的重点. Java接口和抽象类代表的就是抽象类型,就是我们需要提出的抽象层的具体表现.OOP面向对象编程,如果要提高程序的复用率,增加程序的可维护性,可扩展性,就必须是面向接口编程,面向抽象编程,正确地使用接口,抽象类这些有用的抽象类型作为你结构层次上的顶层. Java接口和Java抽象类有太多相似的地方,又有太多特别的地方,究竟在什么地方

Java 接口和抽象类小记

Java 接口和抽象类小记 @author ixenos 接口 1.接口没有构造函数,因为接口是不能被实例化的2.匿名对象如果使用接口的构造器也只是表示了一个协变的实现了接口的匿名对象3.接口里面的成员变量默认都是public static final类型的.必须被显示的初始化.4.接口里面的方法默认都是public abstract类型的.隐式声明.5.接口不能实现另一个接口,但可以继承多个接口.6.类如果实现了一个接口,那么必须实现接口里面的所有抽象方法 抽象类 1.若果在父类中(这里就是你

Java 接口和抽象类区别

1.概述 一个软件设计的好坏,我想很大程度上取决于它的整体架构,而这个整体架构其实就是你对整个宏观商业业务的抽象框架,当代表业务逻辑的高层抽象层结构 合理时,你底层的具体实现需要考虑的就仅仅是一些算法和一些具体的业务实现了.当你需要再开发另一个相近的项目时,你以前的抽象层说不定还可以再次利用 .面对对象的设计,复用的重点其实应该是抽象层的复用,而不是具体某一个代码块的复用. 说到了抽象,我就不能不提到曾让我头痛的Java接口和Java抽象类了,这也是本文我想说的重点. 既然面向对象设计的重点在于

java接口和抽象类

(一)接口和抽象类 作用: 1 利于设计和实现分工: 2 体现代码的层次性: (二)钩子方法或者叫模板方法方式 概念:23中设计模式中的一种,在代码执行的中间阶段,加入钩子,使得我们根据需要调用子类的不同方法,就行我们日常生活中的插座一样,如果你插上去的是电饭煲,那当然这个钩子就充当了煮饭的作用:如果你用来冲热水袋,你们它就充当了加热取暖的作用,我们在我们的某一个功能实现的过程中加入这样的钩子,那么这就是模板方法模式,它可以根据子类对这个方法(比如对于奔跑这个方法,不同子类不一样)来动态调用不同

浅谈JAVA接口和抽象类

一.什么是抽象方法.抽象类 抽象方法: 1.背景(为什么要有抽象方法):有一些方法,一出生就是用来让别人继承重写使用的,自己完全没有去实现的必要,只用定义就可以了,于是JAVA里就专门将这种方法称为抽象方法. 2.定义:用abstract修饰符来声明一种方法,而且这种方法只有声明,没有实现. 例如: public abstract test();//只做了声明,没有实现,连"{}"都不写. 抽象类: 1.背景:因为抽象方法是定义在类里面的,抽象方法是只有声明没有实现的方法,即是残缺不全

Java 接口和抽象类--缺省模式

一个软件设计的好坏,我想很大程度上取决于它的整体架构,而这个整体架构其实就是你对整个宏观商业业务的抽象框架,当代表业务逻辑的高层抽象层结构 合理时,你底层的具体实现需要考虑的就仅仅是一些算法和一些具体的业务实现了.当你需要再开发另一个相近的项目时,你以前的抽象层说不定还可以再次利用 .面对对象的设计,复用的重点其实应该是抽象层的复用,而不是具体某一个代码块的复用. 说到了抽象,我就不能不提到曾让我头痛的Java接口和Java抽象类了,这也是本文我想说的重点. 既然面向对象设计的重点在于抽象,那J

Effective Java - 接口还是抽象类

Java有两种机制可以为某个抽象提供多种实现——Interface和abstract class. Interface 和 abstract class, 除了比较明显的区别(也就是能否提供基本实现), 比较重要的区别是—— 接口的实现类可以处于类层次的任何一个位置,而抽象类的子类则受到这一限制. Existing classes can be easily retrofitted to implement a new interface. 即,如果一个类要实现某个接口,只需要加上impleme

Java接口和抽象类的理解

接口和抽象类的相同之处就是 都会有抽象方法 抽象方法就是一个没有方法体 等待继承的子类完成的方法 然而接口比较严格 它的方法必须是抽象方法且是公开的 抽象类 可以有自己的属性 和 实体方法 首相用面向对象的思想来理解,类其实就是将生活中客观存在的对象,将对象的属性和特性封装起来 而接口与类不同,它不可以被实例化(这里指单独将接口实例化),因为它不可以当作一个对象 接口可以被理解为一种技能,功能.比如一扇门门可以有防盗及这个技能也可以同时拥有报警的功能 也就是说 一个类可以实现多个接口 然而每个子