秦怀杂货店

General Store

  • 首页
  • 文章归档
  • 标签
  • 分类
  • 关于页面

  • 搜索
随便聊聊 数据结构 小游戏 数据库 Docker Springboot 系统设计 雪花算法 分布式 海量ip 最长回文子串 算法 面试题 线程池 多线程 线程 java学习 布隆过滤器 github 架构设计 docsify Git JVM LeetCode 杂货思考 设计模式 Lambda native isAssignableFrom 反射 剑指Offer mybatis SPI JDBC 编程工具 Java基础 集合

【java基础】-- java接口和抽象类的异同分析

发表于 2020-12-05 | 分类于 Java基础 | 0 | 阅读次数 465
  • 在java中,通常初学者搞不懂接口与抽象类,这也是面试比较容易问到的一个问题。下面我来谈谈自己的理解。如有不妥之处,还望批评指正,不胜感激。
  • 1.抽象类怎么定义和继承?
  • 2.接口怎么定义和实现?
  • 3.总结与对比

1.抽象类怎么定义和继承?

我们定义一个抽象类person.class表示类(人):

//使用关键字abstract
public abstract class person {
    //吃东西的抽象方法,已经有所实现
    public void eat(){
        System.out.println("我是抽象方法吃东西");
    }
    
    //public 修饰的空实现的方法
    public void run(){}
    
    //无修饰,空实现
    void walk(){}
    
    //protected修饰的方法,空实现
    protected void sleep(){}
    
    //private修饰的空实现方法
    private void read(){}
}

  • 1.抽象类使用abstract修饰,可以有抽象方法,也可以完全没有抽象方法,也可以是实现了的方法,但是所有的方法必须实现,空实现(public void walk(){})也是实现的一种,而不能写 public void eat(),后面必须带大括号。
  • 2.方法修饰符可以使public,protected,private,或者是没有,没有默认为只能在同一个包下面继承,如果是private那么子类继承的时候就无法继承这个方法,也没有办法进行修改.
  • 下面我们来写一个Teacher.class继承抽象类

同一个包下继承:

不同的包下面继承:

同个包下正确的代码如下(不重写私有的方法):

public class teacher extends person {
    @Override
    public void run(){
        System.out.println("我是实体类的方法跑步");
    }
    @Override
    void walk(){
        System.out.println("我是实体类的方法走路");
    }
    @Override
    protected void sleep(){
        System.out.println("我是实体类的方法睡觉");
    }
}

  • 结果如下(没有覆盖抽象类吃东西的方法,所以会调用抽象类默认的):

  • 下面代码是重写了eat()方法的代码,重写是即使没有使用@Override也是起作用的:
public class teacher extends person {
    public void eat(){
        System.out.println("我是实体类的方法吃东西");
    }
    @Override
    public void run(){
        System.out.println("我是实体类的方法跑步");
    }
    @Override
    void walk(){
        System.out.println("我是实体类的方法走路");
    }
    @Override
    protected void sleep(){
        System.out.println("我是实体类的方法睡觉");
    }
}
  • 结果如下,吃东西的方法被覆盖掉了:

  • 抽象类不能被实例化,比如:

  • 子类可以实现抽象类的方法,也可以不实现,也可以只实现一部分,这样跑起来都是没有问题的,不实现的话,调用是默认使用抽象类的空实现,也就是什么都没有输出,要是抽象类有实现,那么会输出抽象类默认方法。
    比如:

  • 抽象类中可以有具体的方法以及属性(成员变量)
  • 抽象类和普通类之间有很多相同的地方,比如他们都可以都静态成员与静态代码块等等。

2.接口怎么定义和实现?

  • 接口就是对方法或者动作的抽象,比如person.class想要成为教师,可以实现教师的接口,可以理解为增加能力。
  • 接口不允许定义没有初始化的属性变量,可以定义public static final int i=5;,以及public int number =0;,但不允许public int num;这样定义,所有private的变量都不允许出现,下面是图片

定义public int number =0;默认是final修饰的,所以也不能改变它的值:

下面是正确的接口代码:Teacher.java

public interface Teacher {
    public static final int i=5;
    public int number =0;
    public void teach();
    void study();
}
  • 实现类TeacherClass.java
public class TeacherClass implements Teacher{
    @Override
    public void teach() {
        System.out.println("我是一名老师,我要教书");
        System.out.println("接口的static int是:"+i);
    }

    @Override
    public void study() {
        System.out.println("我是一名老师,我也要学习");
        System.out.println("接口的int number是:"+number);
    }
}
  • 测试类Test.java
public class Test {
    public static void main(String[] args){
        TeacherClass teacherClass = new TeacherClass();
        teacherClass.study();
        teacherClass.teach();
        System.out.println("-----------------------------------------------------");
        Teacher teacher =teacherClass;
        teacher.study();
        teacher.teach();
    }
}

结果:

分析:接口里面所定义的成员变量都是final的,不可变的,实现接口必须实现接口里面所有的方法,不能只实现一部分,没有使用static final修饰的,默认也是final,同时必须有初始化的值,接口不能直接创建对象,比如Teacher teacher = new Teacher() ,但是可以先创建一个接口的实现类,然后再赋值于接口对象。

3.总结与对比

抽象类接口
使用关键字abstract修饰使用关键字interface
使用关键字extends实现继承,可以只实现一部分方法,一部分不实现,或者不实现也可以implements来实现接口,实现接口必须实现里面都有的方法
抽象类里面的方法可以是空实现,可以默认实现,但是必须要带{}接口里面的方法都没有实现体,也就是{}
抽象类中可以有具体的方法以及属性,也可以有静态代码块,静态成员变量接口里面不能有普通成员变量,必须都是不可变的final成员变量,而且所有的成员变量都必须是public
抽象类里面的方法可以是public,protect,private,但是private无法继承,所以很少人会这么写,如果没有修饰符,那么只能是同一个包下面的类才能继承接口的方法只能是public或者无修饰符,所有的private修饰都是会报错的
如果有改动,添加新的方法,可以直接在抽象类中实现默认的即可,也可以在实现类中实现接口增加新方法必须在接口中声明,然后在实现类中进行实现
抽象类不能直接创建对象接口也不能直接创建对象 ,可以赋予实现类的对象
抽象类可以有main方法,而且我们可以直接运行,抽象类也可以有构造器接口不能有main方法,接口不能有构造器

那么我们什么时候使用接口什么时候使用抽象类呢?

  • java有一个缺点,只能实现单继承,个人觉得接口是为了弥补单继承而设计的。
  • 接口是对本质的抽象,比如人,可以设计为person.class这个抽象类,提供相关的方法,属性,但是接口是只提供方法的,也就是像增加功能的,那么也就是对方法的抽象。
  • 如果需要默认实现,或者基本功能不断改变,那么建议使用抽象类,如果只是增加一种方法,那么建议使用接口,如果想实现多重继承,只能是接口与抽象类一起使用以达到想要实现的功能。

本文章是初学时的记录,仅是初级的对比,深入学习还需各位保持Keep going~

此文章仅代表自己(本菜鸟)学习积累记录,或者学习笔记,如有侵权,请联系作者删除。人无完人,文章也一样,文笔稚嫩,在下不才,勿喷,如果有错误之处,还望指出,感激不尽~

技术之路不在一时,山高水长,纵使缓慢,驰而不息。Keep going~

公众号:秦怀杂货店

  • 本文作者: 秦怀杂货店
  • 本文链接: http://aphysia.cn/archives/接口和抽象类
  • 版权声明: 本博客所有文章除特别声明外,均采用CC BY-NC-SA 3.0 许可协议。转载请注明出处!
# 随便聊聊 # 数据结构 # 小游戏 # 数据库 # Docker # Springboot # 系统设计 # 雪花算法 # 分布式 # 海量ip # 最长回文子串 # 算法 # 面试题 # 线程池 # 多线程 # 线程 # java学习 # 布隆过滤器 # github # 架构设计 # docsify # Git # JVM # LeetCode # 杂货思考 # 设计模式 # Lambda # native # isAssignableFrom # 反射 # 剑指Offer # mybatis # SPI # JDBC # 编程工具 # Java基础 # 集合
【java基础】-- instanceof 用法详解
JDBC【4】 -- jdbc预编译与拼接sql对比
  • 文章目录
  • 站点概览
秦怀杂货店

秦怀杂货店

纵然缓慢,驰而不息。

145 日志
19 分类
37 标签
Github E-mail
Creative Commons
0%
© 2022 秦怀杂货店
由 Halo 强力驱动
|
主题 - NexT.Pisces v5.1.4