抽象类与接口比较(Java)

84 阅读3分钟

抽象类介绍

一个方法要么有方法体,要么是一个抽象方法,抽象方法不是一个完整的方法,他只有一个声明,没有方法体。

public class Animal {
    public void eat ();
}

上面这种是不行的,因为eat既不是一个抽象方法,也没有{ },也就是没有方法体,编译器就会报错。

并且,如果一个类中存在抽象方法,那么这个类一定也是一个抽象类。

// 正确形式
abstract public class Animal {
    public abstract void eat ();
    // abstract写在返回值类型之前
}

抽象类同样无法被实例化,你根本就无法安全创建一个抽象类的对象(本身抽象类就没有方法体,就算实例化也无法调用方法),你会受到来自编译器的错误消息,这保证了抽象类的纯粹,不用担心它会被误用。

要想创建一个可实例化的类,就需要先创建一个继承抽象父类的子类,然后为所有的抽象方法提供定义。

使用场景(抽象类的意义): 当父类定义一个方法时,每个子类对该方法的具体实现逻辑都不同,那么父类定义该方法时就可以定义成抽象方法。

接口(Interface)介绍

interface关键字创建了一个完全抽象的类,他不代表任何实现。接口描述了一个类应该是什么样子和做什么,而不是应该如何做。它确定了方法名、参数列表和返回类型,但不提供方法主体。因此,任何使用了特定接口的代码都知道可以为该接口调用哪些方法,仅此而已。所以接口是用来在类之间建立“协议”的。

接口作用最重要的两个字——约束,接口没有具体的方法代码,并且实现接口时必须要实现其内部所有的方法。

interface Iperson {
    public void f1();
    public void f1(int age);
    public void f1(String info);

}
class UserInfo implements Iperson{
    public void f1(){
        System.out.println("f1");
    };
    public void f1(int age){
        System.out.println("f11");
    };
    public void f1(String info){
        System.out.println("f111");
    };

    public static void main(String[] args) {
        UserInfo uu = new UserInfo();
        uu.f1();
        uu.f1(11);
        uu.f1("xxx");
    }

二者区别总结

想象一下现实生活中的接口,接口本身没有什么用,但它是有规范的,USB,Type-c,HDMI等等,如果数据线跟接口有一点点不匹配,就不能用。

抽象类介于普通类和接口之间,普通类的继承无法强制约束子类中有什么方法,而接口无法提供“公共方法”,因此抽象类跟接口本身不是无关的概念,接口是“增强”的抽象类。

但是如果在一个抽象类中既添加抽象类方法,又添加普通方法,那么就可以结合普通类继承和接口二者的优点。

abstract class Base {
    // 抽象方法(约束子类中必须有这个方法)
    public abstract void play(String name);
    // 普通方法
    public void stop(){
        System.out.println("Stop");
    }
}
class Son extends Base {
    //既可以定义抽象方法,又可以调用普通方法
    @Override
    public void play(String name) {
        System.out.println("play");
    }

    public static void main(String[] args) {
        Son son = new Son();
        son.play("xxx");
        son.stop();
    }
}
//输出play Stop