栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

【八股文】一分钟掌握抽象类与接口两者之间的区别

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

【八股文】一分钟掌握抽象类与接口两者之间的区别

目录

抽象类-Abstract Class

抽象类特点 

代码示例

接口-Interface

接口的特点

代码示例

接口与抽象类的区别总结

语法上的区别

语义上的区别

代码示例

执行结果


        在初中级程序员面试中这是一道很常见的面试题,这题不难但是要想有亮点还是有一定的难度。

接口和抽象类都提供了一个将接口和实现分离的结构化的方法

抽象类-Abstract Class

        在Java中被abstract关键字修饰的类称为抽象类,被abstract关键字修饰的方法称为抽象方法,抽象方法只有方法的声明,没有方法体。下面是抽象方法的语法:

abstract void method();

        如果一个类包含一个或多个抽象方法则这个类必须限定为抽象类,反过来一个抽象类中不一定包含抽象方法。

抽象类特点 

1、抽象类不能被实例化,即不能使用new关键字来实例化对象,只能被继承;

2、包含抽象方法的一定是抽象类,但是抽象类不一定含有抽象方法;

3、抽象类中的抽象方法的修饰符只能为public或者protected,默认为public;

4、抽象类中的抽象方法只有方法体,没有具体实现;

5、如果一个子类实现了父类(抽象类)的所有抽象方法,那么该子类可以不必是抽象类,否则就是抽象类;

6、抽象类可以包含属性、方法、构造方法,但是构造方法不能用于实例化,主要用途是被子类调用。

代码示例

        动物都有名字,叫声以及叫;动物在叫时,输出 xxx 的叫声是:xxx;

这样我们就可以抽象一个动物类,并定一个一个模版方法speak和一个抽象方法 getCry();让不同的动物去实现这个叫声。

    
    public abstract class AbstractAnimal {

        private String name;


        
        public abstract String getCry();

        
        public void speak() {
            System.out.println(name + "的叫声是:" + getCry());
        }

        public String getName() {
            return name;
        }

        public void setName(String name) {
            this.name = name;
        }
}

   public class Dog extends AbstractAnimal {
        public Dog(String name) {
            super(name);
        }

        @Override
        public String getCry() {
            return "汪汪";
        }
    }

    public class Cat extends AbstractAnimal{
        public Cat(String name) {
            super(name);
        }

        @Override
        public String getCry() {
            return "喵喵";
        }
    }

接口-Interface

Java中接口使用interface关键字修饰就是接口,它是一个完全“抽象方法”的集合

接口的特点

1、接口可以包含变量、方法;变量被隐士指定为public static final,方法被隐式指定为public abstract(JDK1.8之前);

2、接口支持多继承,即一个接口可以extends多个接口,间接的解决了Java中类的单继承问题;

3、一个类可以实现多个接口;

4、JDK1.8中对接口增加了新的特性:

4.1、默认方法(default method):JDK 1.8允许给接口添加非抽象的方法实现,但必须使用default关键字修饰;定义了default的方法可以不被实现子类所实现,但只能被实现子类的对象调用;如果子类实现了多个接口,并且这些接口包含一样的默认方法,则子类必须重写默认方法;

4.2、静态方法(static method):JDK 1.8中允许使用static关键字修饰一个方法,并提供实现,称为接口静态方法。接口静态方法只能通过接口调用(接口名.静态方法名)。

代码示例
 public interface Flyable {
        String A = "常量1";
        String B = "常量2";
        public static final String C = "常量3";

        void fly();

        default String getTest() {
            return "test";
        }

        static void staticMethod(){
            System.out.println("接口中静态方法");
        }

    }

接口与抽象类的区别总结

语法上的区别
抽象类接口
实例化不可以不可以
构造器支持不支持
方法实现

抽象类可以有抽象方法也可以有具体方法实现

有抽象方法的类一定是抽象类,但是抽象类不一定是抽象类

在JDK1.8之前接口不支持具体方法实现,从1.8开始支持默认方法和静态方法
访问修饰符抽象类可以是public, protected,default接口只能是public
成员变量抽象类支持普通成员变量接口中的成员变量都是常量,即使没有使用 public static final 修饰也会被隐式的声明为常量
继承抽象类只支持单继承接口可以继承多个接口
main方法抽象类可以有main 方法,可以允许接口不可以
新增方法抽象类新增方法必须有实现,这样可以向下兼容JDK1.8之前接口新增方法不支持向下兼容,自1.8开始新增默认方法则可以向下兼容

语义上的区别

         这道面试题的重点在这里,主要考察的面试者的架构设计能力。

        第一点:抽象类是is-a的关系,接口是has-a的关系。我们具体举个例子来说明这个问题,有一个独角兽,我们可以抽象出一个抽象类 Animal ,我们可以说独角兽是动物;我们还可以抽象一个Flyable,因为独角兽具有飞行能力。我们是不会可以将Animal 定义为接口呢?如果设计为接口,那么可以说独角兽有动物能力吗?这样就很难理解和沟通。

        第二点:从设计模式角度来讲抽象类是模版方法模式,接口是一个约束范式。

   

代码示例

     上文说了这些区别点,是不是真的是这样呢,下面我们通过一段demo来看一下

public class InterfaceAndAbstract {


    public static class Dog extends AbstractAnimal {
        public Dog(String name) {
            super(name);
        }

        @Override
        public String getCry() {
            return "汪汪";
        }
    }

    public static class Cat extends AbstractAnimal {
        public Cat(String name) {
            super(name);
        }

        @Override
        public String getCry() {
            return "喵喵";
        }
    }

    public static class Unicorn extends AbstractAnimal implements Flyable {
        public Unicorn(String name) {
            super(name);
        }

        @Override
        public String getCry() {
            return "灰吕吕";
        }

        @Override
        public void fly() {
            System.out.println(getName() + " 飞起来了");
        }
    }

    
    public static abstract class AbstractAnimal {

        private String name;


        public AbstractAnimal(String name) {
            this.name = name;
        }

        
        public abstract String getCry();

        
        public void speak() {
            System.out.println(name + "的叫声是:" + getCry());
        }

        public String getName() {
            return name;
        }

        public void setName(String name) {
            this.name = name;
        }

        
        public static void main(String[] args) {
            Unicorn unicorn = new Unicorn("独角兽");
            unicorn.speak();

            Dog dog = new Dog("小狗");
            dog.speak();
            unicorn.fly();
            //只能通过接口调用静态方法
            Flyable.staticMethod();
        }
    }

    
    public interface Flyable {
        String A = "常量1";
        String B = "常量2";
        public static final String C = "常量3";

        void fly();

        default String getTest() {
            return "test";
        }

        static void staticMethod() {
            System.out.println("接口中静态方法");
        }

    }
}

执行结果

独角兽的叫声是:灰吕吕
小狗的叫声是:汪汪
独角兽 飞起来了
接口中静态方法

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/981698.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号