接口和抽象类的区别(7大区别)

关键字不同

接口使用interface关键字定义,如下所示:

interface Animal {
    void eat();
    void sleep();
}

抽象类使用abstract class关键字定义:

abstract class Animal {
    abstract void eat();
    abstract void sleep();
}

 

实现关键字不同

接口:类通过implements关键字实现接口:

class Dog implements Animal {
    @Override
    public void eat() {
        System.out.println("Dog is eating");
    }

    @Override
    public void sleep() {
        System.out.println("Dog is sleeping");
    }
}

抽象类:类通过extends关键字继承抽象类:

class Dog extends Animal {
    @Override
    void eat() {
        System.out.println("Dog is eating");
    }

    @Override
    void sleep() {
        System.out.println("Dog is sleeping");
    }
}

 

类型扩展不同

接口:支持多继承,一个类可以实现多个接口。

interface Runnable {
    void run();
}

interface Swimmable {
    void swim();
}

class Dog implements Animal, Runnable, Swimmable {
    @Override
    public void eat() {
        System.out.println("Dog is eating");
    }

    @Override
    public void sleep() {
        System.out.println("Dog is sleeping");
    }

    @Override
    public void run() {
        System.out.println("Dog is running");
    }

    @Override
    public void swim() {
        System.out.println("Dog is swimming");
    }
}

抽象类:单继承,一个类只能继承一个抽象类。

abstract class Mammal {
    abstract void makeSound();
}

class Dog extends Animal {
    @Override
    void eat() {
        System.out.println("Dog is eating");
    }

    @Override
    void sleep() {
        System.out.println("Dog is sleeping");
    }
}

class Labrador extends Dog {
    @Override
    void makeSound() {
        System.out.println("Labrador is barking");
    }
}

 

方法访问控制符不同

接口中的方法默认是public,不能是privateprotected。

interface Animal {
    void eat(); // 默认是public
}

抽象类:可以包含所有访问修饰符的方法和字段(public, protected, private)。

abstract class Animal {
    public abstract void eat();
    protected abstract void sleep();
    private void breathe() {
        System.out.println("Animal is breathing");
    }
}

 

属性方法控制符不同

接口:接口中的属性默认是public static final,方法默认是public

interface Animal {
    int AGE = 5; // public static final

    void eat(); // 默认是public
}

抽象类:可以包含任何访问控制符的属性和方法。

abstract class Animal {
    protected int age; // 实例字段,可以是任意访问控制符

    public abstract void eat();

    protected void setAge(int age) {
        this.age = age;
    }
}

 

方法实现不同

接口:接口中的方法默认不能有实现,除非是defaultstatic方法。

interface Animal {
    void eat(); // 抽象方法
    void sleep(); // 抽象方法

    // 默认方法
    default void breathe() {
        System.out.println("Animal is breathing");
    }

    // 静态方法
    static void info() {
        System.out.println("Animal interface");
    }
}

抽象类:抽象方法没有实现,具体方法必须有实现。

abstract class Animal {
    abstract void eat(); // 抽象方法

    void sleep() { // 具体方法
        System.out.println("Animal is sleeping");
    }
}

 

静态代码块的使用不同

接口:不能有静态代码块。

抽象类:可以有静态代码块。

abstract class Animal {
    static {
        System.out.println("Static block in Animal class");
    }

    abstract void eat();
}

mikechen

mikechen睿哥,10年+大厂架构经验,资深技术专家,就职于阿里巴巴、淘宝、百度等一线互联网大厂。

关注「mikechen」公众号,获取更多技术干货!

后台回复架构即可获取《阿里架构师进阶专题全部合集》,后台回复面试即可获取《史上最全阿里Java面试题总结

评论交流
    说说你的看法