zoukankan      html  css  js  c++  java
  • 接口和抽象类的区别,实不相瞒,我忘记了?

    接口和抽象类的区别,实不相瞒,我忘记了?

    在Java基础部分,接口和抽象类是相当重要的知识点,尤其是接口,在后面的开发中,经常会见到这么四个字“面向接口编程”,而且对于接口和抽象类的知识也是面试中经常会被问到的,所以我们非常有必要熟练掌握这部分的知识!今天吗,我们就一起来回顾下!

    小白: 庆哥,说真的,现在让我来说接口和抽象类的区别,我发现自己的记忆是模糊的,能说出来的大概就是:
    接口和抽象类之间有相同也有不同,接口可以用来实现多实现,弥补继承的不足,接口使用关键字implements来实现接口,每一个实现接口的类都要实现其中的方法,而且接口中的方法默认都是public的,对于接口而言,不能有已经实现的方法,这个对于抽象类来说好像就可以,这好像就是两者的区别吧!

    庆哥: 感觉你记得已经可以了,有的时候我们之所以会对某一个知识点的记忆产生模糊,一是自己不太理解,二是即使理解了,如果长时间不回顾,也是很容易忘记的,所以,复习,有的时候真的很重要!

    小白: 是的,对于一个知识,我觉得首先就是有一个完整清晰的理解,然后再进行间断性的复习,巩固记忆,这样才会记忆的牢固。

    庆哥: 可以啊,感觉你说出来学习的真谛啊!下面咱来一起回顾下接口和抽象类,以及他们的区别,或者说我们该怎么选择使用他们?

    小白: 嗯嗯,我觉得首先要搞清楚的就是两者的概念了,什么是接口,什么是抽象类?我查了一下,找到这么些定义说明。

    什么是接口?

    接口,英文叫做interface,在Java编程语言中是一个抽象类型,是抽象方法的集合,接口通常使用interface来声明,一个类通过实现接口的方式,从而来实现接口中的抽象方法。

    什么是抽象类?

    在面向对象的概念中,所有的对象都是通过类来描绘的,但是反过来,并不是所有的类都是用来描绘对象的,如果一个类中没有包含足够的信息来描绘一个具体的对象,这样的类就是抽象类。

    另外我还了解到对于接口,有这样的描述

    接口并不是类,编写接口的方式和类很相似,但是它们属于不同的概念。类描述对象的属性和方法。接口则包含类要实现的方法。
    除非实现接口的类是抽象类,否则该类要定义接口中的所有方法。
    接口无法被实例化,但是可以被实现。一个实现接口的类,必须实现接口内所描述的所有方法,否则就必须声明为抽象类。另外,在 Java 中,接口类型可用来声明一个变量,他们可以成为一个空指针,或是被绑定在一个以此接口实现的对象。

    对于抽象类有这样的描述

    抽象类除了不能实例化对象之外,类的其它功能依然存在,成员变量、成员方法和构造方法的访问方式和普通类一样。
    由于抽象类不能实例化对象,所以抽象类必须被继承,才能被使用。也是因为这个原因,通常在设计阶段决定要不要设计抽象类。
    父类包含了子类集合的常见的方法,但是由于父类本身是抽象的,所以不能使用这些方法。
    在Java中抽象类表示的是一种继承关系,一个类只能继承一个抽象类,而一个类却可以实现多个接口。

    庆哥: 可以啊,你这功夫做的挺足啊,说的还很详细嘛我感觉我都没有什么好说的了,你这是在哪找的啊,总结的不错啊!

    小白: 这是在菜鸟教程中找的,很适合我这种菜鸟啊!

    庆哥: 哦哦,原来是在菜鸟教程啊,这个菜鸟教程还是不错的,总结的很到位,包含的也不仅仅有Java,是个自学的好地方!不过总结归总结,我们还需要一个个来,然后结合着代码来看,增加我们的印象,尤其是一些重点概念,我们先来看一下接口

    接口

    首先要知道接口如何定义

    /**
     * @author ithuangqing
     */
     interface ITest {
        /**
         * 用来展示输出信息
         */
       void show();
    
    }
    

    以上我们就定义了一个接口,在定义接口的时候我们可以注意一些细节,比如说不要这样写

    /**
     * @author ithuangqing
     */
     public interface ITest {
        /**
         * 用来展示输出信息
         */
       public abstract void show();
    
    }

    就是不要加任何修饰符,包括public,而且在接口中尽量不要定义变量,如果必须定义变量的话记住变量名一定要大写,像这样

    /**
     * @author ithuangqing
     */
      interface ITest {
         String NAME = "Java从0到1";
        /**
         * 用来展示输出信息
         */
        void show();
    
    }
    

    以上我们就完美定义一个接口了

    小白: 为什么要这样呢?

    庆哥: 这就牵涉到接口的一些特点了,它有这么几点特性

    1. 使用interface修饰
    2. 接口中的所有方法都是公开的,并且是抽象方法
    3. 接口中可以定义成员变量,但都是公共静态常量
    4. 接口中不能存在实现的方法
    5. 实现了接口就必须实现接口中全部的方法
    6. 接口不是一个类,不能实例化

    也就是说接口中的方法默认都是公共且抽象的,看下面几种写法

    1. Public abstract void a();
    2. Public void a();
    3. void a();

    其实都是一样的效果,最终等同于第一种写法,所以为了保持代码的简洁性,因此不要加任何的修饰符,而对于变量,在接口中是不建议写变量的,如果非要写,那变量名统一大写,这是因为接口中的成员变量都是公共静态常量。

    小白: 接口中不能有已经实现的方法吗?

    庆哥: 是的,在接口中,是不能有实现的方法的,你看

    image

    看到这里已经报错了,所以在接口中是不存在已经实现的方法的。

    小白: 嗯,接口不是一个类,不能被实例化,可以通过一个类去实现这个接口,然后实现接口中的方法来实现,这个接口中的方法要全部实现吧?

    庆哥: 是的,实现了一个接口就要实现全部的方法。好了,接下来啊我们再来说一下抽象类吧

    抽象类

    首先要会定义一个抽象类

    public abstract class AbstractPerson {
        String name;
        int age;
        public abstract void show();
        public void doMe(){
            System.out.println("我是一个人");
        }
    }

    这就定义了一个抽象类

    小白: 我看你这个抽象类的命名是以Abstract开头,是不是抽象类的命名都这样命名呢?

    庆哥: 一般推荐抽象类的命名以Abstract开头,便于判别是一个抽象类。

    小白: 那这个抽象类不需要跟接口似的省略掉修饰符,以追求简洁吗?

    庆哥: 这个我们通过代码来看,首先我们不加修饰符,是这样

    public abstract class AbstractPerson {
    
        abstract void show();
    
    }

    然后看它的继承类,实现方法之后是这样的、

    /**
     * 继承抽象类
     */
     class Man extends AbstractPerson {
    
        @Override
        void show() {
    
        }
    }

    然后再来看加上修饰符

    public abstract class AbstractPerson {
    
        public abstract void show();
    
    }
    

    然后再看继承类

    /**
     * 继承抽象类
     */
     class Man extends AbstractPerson {
    
        @Override
        public void show() {
    
        }
    }

    所以,对于抽象类我倒是建议加上修饰符,这样更加直观。

    小白: 嗯嗯,知道了,那抽象类中可以有实现的方法吗?

    庆哥: 我们可以来试一下就知道了

    image

    可以看到,在抽象类中是可以有实现的方法的,另外在抽象类中也是可以定义成员变量的,抽象类说到底还是一个类,跟接口是有区别的,对于抽象类,我们可以总结一下特点

    1. 使用abstract修饰作为抽象类和抽象方法
    2. 子类必须实现抽象类的抽象方法
    3. 那么就可以判断抽象类中的抽象方法不能是私有的,否则子类无法实现
    4. 抽象类是一个类,必然涉及到继承
    5. 抽象类中允许有实现的方法

    抽象类和接口的区别

    小白: 哦哦,到这里,我似乎可以总结一下两者的区别了

    1. 抽象类需要一个类去继承,接口则是需要去实现,并且都是要全部实现其中的抽象方法,两者皆是如此。
    2. 接口中不能有已经实现的方法,而抽象类则可以
    3. 接口可以多实现,但是抽象类只能单继承。

    庆哥: 是的,总结的不错,我再补充几点
    1. 抽象类里面是可以没有抽象方法的
    2. 如果一个类,其中包含抽象方法,那么这个类一定是个抽象类

    那么说到这里,你明白了到底什么是接口,什么是抽象类了吗?

    小白: 经过上面的讨论学习,我感觉,接口更像是定义一种功能或者说操作,实现了这个接口就可以干某些事,而抽象类更像是对一些事物的高级概括。

    庆哥: 你说的非常好,总的来说,接口的扩展性要比抽象类好很多,因为抽象类始终是一个类,注定只能单继承,不像接口可以多实现,就从灵活性和可扩展性而言,接口我们一般使用的较多!

    小白: 经过这么讨论,我对接口和抽象类的认识更加深刻了,以后再经常复习,相信一定能很好的掌握这个知识,谢谢庆哥!

    庆哥: 不谢,咱们是共同学习,一起进步,那今天就先到这啦!

    Java从0到1,我们一起!完!

  • 相关阅读:
    重新梳理HTML基础知识
    Bootstrap响应式栅格系统的设计原理
    php 循环爬虫 or 持久执行任务 总断掉服务 解决,flush(),ob_flush()的组合使用
    Linux中工作目录切换命令
    Linux中系统状态检测命令
    Linux系统中rm删除命令
    Linux中touch命令使用(创建文件)
    Linux中 mkdir 创建文件夹命令
    Linux 中 cp 命令(文件复制)
    Linux中 mv(文件移动)
  • 原文地址:https://www.cnblogs.com/ithuangqing/p/12113651.html
Copyright © 2011-2022 走看看