抽象类与接口的区别

什么是抽象类

在java中,使用abstract修饰的类就是一个抽象类。如下就是一个抽象类:


/**
 * 抽象类
 */
public abstract class A {
    /**
     * 抽象类中可以有成员变量,可以有常量
     */
    private int a;
    public int b;
    int c;
    String str;
    public static final String STR = "abstract";

    //抽象类中可以有构造方法
    public A() {

    }

    public void funA() {
        System.out.println("抽象类中可以有普通方法");
    }

    //抽象方法
    abstract void funB();
}

抽象类可以有成员变量,可以有常量,可以有构造方法,可以有普通方法(包括静态方法),只要是普通的类中可以有的,抽象类都可以有。但还是需要注意几点:

  • 抽象类不可以被实例化,即使抽象类有构造方法,但在抽象类中可以有构造方法,只是不能直接创建抽象类的实例对象。在实例化子类的时候,就会初始化父类,不管父类是不是抽象类都会调用父类的构造方法,此时如果是抽象类就会调用抽象类的构造方法;
  • 方法被abstract修饰后,该方法即为抽象方法,此时该方法无方法体,即不能加{}进行实现,且该方法不能再加private、final进行修饰;
  • 抽象类中可以没有抽象方法,但类中只要存在一个抽象方法,该类即为抽象类,不能被实例化;
  • 继承抽象类的子类可以是普通类,如果为普通类,则必须重写抽象类中所有的抽象方法,只要有一个没重写(仍为抽象方法),则该子类仍为抽象类。
  • 抽象类不能被final修饰。因为final修饰的类无法被继承
  • 抽象类不能被static修饰,但内部抽象类可以
public abstract class F {

    abstract static  class G {
        abstract void funGA();

    }
    abstract void funA();

}

//继承内部抽象类
class H extends F.G {
    @Override
    void funGA() {
        System.out.println("实现F.G抽象类中的方法");
    }

    public static void main(String[] args) {
        F.G g = new H();
        g.funGA();
    }
}

运行结果:

实现F.G抽象类中的方法

什么是接口

在java中,接口使用interface修饰,接口是一种规范,是一系列方法的声明,是一些方法特征的集合,一个接口只有方法的特征没有方法的实现,因此这些方法可以在不同的地方被不同的类实现,而这些实现可以具有不同的行为(功能)。如下就是一个接口:

/**
 * 接口
 */
public interface B {
    //接口里可以有常量。默认都是加了public final static
    //由于是常量,所以必须初始化
    //通过接口名.常量访问 如B.a
    int a = 2;
    public final static String str = "interface";

    //接口中的方法默认都是public abstract修饰
    void funA();

    public abstract void funB();

}

接口可以说是一中特殊的抽象类,接口里的方法都是抽象方法(默认使用了public abstract修饰)。

  • 子类实现接口必须实现接口中的所有方法;
  • 接口中不能有成员变量,只能有常量,即默认都是public final static修饰;
  • 接口不能被实例化;
  • 接口不能有构造方法;
  • 接口可以继承接口,使用extends并且可以继承多个接口:
interface C extends B {
    int aa = 3;
}

interface D extends B,C {
    int dd = 4;
}
  • jdk1.8中,接口允许有静态方法(用static修饰),也允许接口有默认实现(用default修饰)。子类实现接口时可以不重写 default修饰的方法。也可以重写覆盖。
class E implements D {

    @Override
    public void funA() {
        System.out.println("实现接口A");
    }

    @Override
    public void funB() {
        System.out.println("实现接口B");
    }

    /*@Override
    public void funD() {
        System.out.println("覆盖默认实现");
    }*/

    public static void main(String[] args) {
        E e = new E();
        System.out.println("访问接口B中的常量...");
        //访问接口B中的常量
        System.out.println(B.a);
        System.out.println(E.a);
        System.out.println(C.a);

        //接口中的静态方法
        System.out.println("访问接口中的静态方法...");
        B.funC();

        System.out.println("访问类E中重写接口的方法...");
        e.funA();
        e.funB();

        System.out.println("访问接口中的默认方法...");
        e.funD();

    }
}

运行结果:

访问接口B中的常量…
2
2
2
访问接口中的静态方法…
jdk1.8新增的接口中的静态方法
访问类E中重写接口的方法…
实现接口A
实现接口B
访问接口中的默认方法…
jdk1.8新增的接口中的默认方法实现

抽象类和接口的区别

  • 抽象类和接口都不能实例化
  • 抽象类和接口中的抽象方法都只能有方法声明,不能有方法体(jdk1.8后接口中的默认方法可以有方法体)
  • 抽象类和接口的概念有所不同,抽象类是对根源的抽象,接口是对动作的抽象。通俗点讲就是,抽象类常用于表示这个对象是什么,而接口表示的是这个对象能做什么。
  • 继承抽象类的子类可以不必实现全部抽象方法,此时该子类仍为抽象类;而实现接口的类则必须实现全部的方法(jdk1.8后新特性的默认方法除外)
  • 类只能单继承,接口可以继承接口,并且可以多继承
  • 接口是设计的结果 ,抽象类是重构的结果
  • 抽象类可以有构造方法,接口不能有构造方法
  • 抽象类中的变量没有要求,而接口中的变量必须是public static final即常量

抽象类和接口的使用场景

  • 在既需要统一的接口,又需要实例变量来协调或标记状态等情况下,可以使用抽象类;
  • 不想要每个实现类都重写所有的抽象方法的情况下可以使用抽象类;
  • 类与类之间关系比较紧密且需要共享代码或方法,考虑使用抽象类;
  • 仅强调动作,而不在乎其如何实现,考虑使用接口;
  • 需要实现特定的多项功能,且功能之间无比较紧密的联系,考虑使用接口;

参考链接:抽象类和接口的使用场景介绍
                  接口和抽象类有什么区别

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值