锋盈数科-知识库 Logo
首页
软件开发
计算机基础
Hello Halo
新手必读
关于本知识库
登录 →
锋盈数科-知识库 Logo
首页 软件开发 计算机基础 Hello Halo 新手必读 关于本知识库
登录
  1. 首页
  2. 软件开发
  3. JAVA
  4. Java抽象类和接口的详细区别(全)

Java抽象类和接口的详细区别(全)

0
  • JAVA
  • 发布于 2024-08-03
  • 0 次阅读
黄健
黄健

原文链接:https://blog.csdn.net/weixin_47872288/article/details/127283356

前言

这两者经常在笔试以及面试中经常问及,甚至在项目实战中还在纠结用哪一种类型

今天就此问题详细剖析一下

以往我的文章中也有稍微提及: java框架零基础从入门到精通的学习路线(超全)

此处将其这些文章抽离公共部分,详细总结下这两概念

1. 抽象类

抽象类是类和类之间的共同特征,将这些共同特征进一步形成抽象类,由于类本身不存在,所以抽象类无法创建对象。

类到对象是实例化,对象到类是抽象

抽象方法不能被 final 修饰,因为抽象方法就是被子类实现的

采用 abstract 关键字定义的类就是抽象类,采用 abstract 关键字定义的方法就

是抽象方法

抽象的方法只需在抽象类中,提供声明,不需要实现

如果一个类中含有抽象方法,那么这个类必须定义成抽象类。抽象类中不一定有抽象方法,抽象方法必须出现在抽象类中

final和abstract不能同时同时使用,这两个关键字是对立的

抽象类的子类可以是抽象类。也可以是非抽象类

一个非抽象的类,继承抽象类,必须将抽象类中的抽象方法进行覆盖/重写/实现

抽象类无法实例化,无法创建对象,抽象类是被子类来继承的

抽象类可以有抽象类的子类

public class AbstractTest01 {

    public static void main(String[] args) {

        new a();//错误,不可创建对象

    }

}

//定义一个抽象类

abstract  class a{

    

}

//不是抽象类可以继承抽象类并且实例化

class b extends a{

}

//抽象子类可以继承抽象类

abstract class c extends a{

}

抽象类无法实例化,但抽象类有构造函数可以供子类使用

如果抽象类定义了有参构造函数而没有无参构造函数,子类定义找不到无参构造函数会出错,抽象类无法实例化调用对象(new对象),但是有构造函数可以给子类使用

abstract  class a{

    

}

class b extends a{

	public b(){

		super();

	}

}

抽象方法表示没有实现的方法,没有方法体的方法

没有方法体,以分号结尾

前面的修饰符列表中有abstract关键字

比如public abstract void dosome();

但是java语言中凡是没有方法体的方法都是抽象方法(×)

因为Object类中就有很多方法都没有方法体,都是以“;”结尾的,但他们都不是抽象方法

public class AbstractTest03 {

    public static void main(String[] args) {

//此时不能再 new Employee 了

        Person p = new Employee();

    } }

abstract class Person {

    private String name;

    public void setName(String name) {

        this.name = name;

    }

    public String getName() {

        return name;

    }

    //此方法各个子类都可以使用

    public void commonMethod1() {

        System.out.println("---------commonMethod1-------");

    }

    //采用 abstract 定义抽象方法

    public abstract void printInfo();

}

abstract class Employee extends Person {

    //再次声明该方法为抽象的

    public abstract void printInfo();

}

class Student extends Person {

    //实现抽象的方法

    public void printInfo() {

        System.out.println("Student.printInfo()");

    } 

    }

2. 接口

接口是特殊的抽象类,类与类是继承extends,类与接口是实现implements,其实都是继承

接口是一种“引用数据类型”,完全抽象的,支持多继承,且一个接口可以继承多个接口,只有常量+抽象方法

所有的元素都是public修饰的,抽象方法的public abstract可以省略,常量的public static final可以省略,方法不能有方法体

定义的格式

[修饰符列表] interface 接口名{}

支持多继承,且一个接口可以继承多个接口

每一个interface 都会生成一个class后缀名的文件

public class text1 {

    public static void main(String[] args) {

	}

}

interface a{

}

interface b extends a{

}

interface c extends a,b{

}

接口中的方法是抽象,所以不能有方法体

定义抽象方法的时候可以省略修饰符public abstract

interface a{

	int sum(int a,intb);//可以省略,默认系统会给你加上

	void dosome();//可以执行通过

	void dosome(){};//不可以执行通过,不能有方法体

}

常量的定义结合final 是public static final可以省路

public class text1 {

    public static void main(String[] args) {

    	//定义输出的时候 需要用类名加变量 也就是a.i

    	//而且不允许在修改常量

	}

}
interface a{

	public static final int i=100;

	int z=1;//z也是一个常量而不是变量 不能修改

}

3. 两者结合

当一个非抽象的类实现接口的话,必须将接口中所有的抽象方法全部实现(覆盖、重写)

// 特殊的抽象类,完全抽象的,叫做接口。

interface MyMath{

	double PI = 3.1415926;

	int sum(int a, int b);

	int sub(int a, int b);

}

// 这样没问题

abstract class MyMathImpl implements MyMath {

}

//编译出错

class MyMathImpl implements MyMath {

}

//添加方法重写实现

//修正

class MyMathImpl implements MyMath {

	//错误:正在尝试分配更低的访问权限; 以前为public

	/*

	int sum(int a, int b){

		return a + b;

	}

	*/

	// 重写/覆盖/实现 接口中的方法(通常叫做实现。)

	public int sum(int a, int b){

		return a + b;

	}

	public int sub(int a, int b){

		return a - b;

	}

}

接口中的方法必须是public :

如果删除执行不通过,因为接口是public,如果继承后,不写public执行后是分配更低的权限这是不行的,所以要添加public

结合多态面向接口编程

public class Test02{

	public static void main(String[] args){

		//错误: MyMath是抽象的; 无法实例化

		//new MyMath();

		// 父类型的引用指向子类型的对象

		MyMath mm = new MyMathImpl();

		// 调用接口里面的方法(面向接口编程。)

		int result1 = mm.sum(10, 20);

		System.out.println(result1);

		int result2 = mm.sub(20, 10);

		System.out.println(result2);

	}

}

接口与接口之间可以多继承,一个类也可以多个接口

interface X{

}

interface Y{

}

interface Z extends X,Y{ //接口和接口支持多继承。

}

一个类可以实现多个接口

java中类和类只支持单继承。实际上单继承是为了简单而出现的,java中的接口弥补了单继承带来的缺陷

interface A{

	void m1();

}

interface B{

	void m2();

}

interface C{

	void m3();

}

// 实现多个接口,其实就类似于多继承。

class D implements A,B,C{

	// 实现A接口的m1()

	public void m1(){

		

	}

	// 实现B接口中的m2()

	public void m2(){

		System.out.println("m2 ....");

	}

	// 实现接口C中的m3()

	public void m3(){

	

	}

}

强转类型的时候,需要有继承关系才可

A a = new D();

//a.m2(); // 编译报错。A接口中没有m2()方法。

B b = new D();

C c = new D();

// 这个编译没问题,运行也没问题。

// 调用其他接口中的方法,你需要转型(接口转型。)

B b2 = (B)a;

b2.m2();

// 直接向下转型为D可以吗?可以

D d = (D)a;

d.m2();

但如果没有继承关系不能强转

M m = new E();

// 经过测试:接口和接口之间在进行强制类型转换的时候,没有继承关系,也可以强转。

// 但是一定要注意,运行时可能会出现ClassCastException异常。

// 编译没问题,运行有问题。

K k = (K)m;

if(m instanceof K){

K k = (K)m;

interface K{

}

interface M{

}

class E implements M{

}

继承和实现同时存在

extends在前 implements在后

public class Test04{

	public static void main(String[] args){

		// 创建对象(表面看Animal类没起作用!)

		Flyable f = new Cat(); //多态。

		f.fly();

	}

}

// 动物类:父类

class Animal{

}

interface Flyable{

	void fly();

}

// 动物类子类:猫类

// Flyable是一个接口,是一对翅膀的接口,通过接口插到猫身上,让猫变的可以飞翔。

class Cat extends Animal implements Flyable{

	public void fly(){

		System.out.println("飞猫起飞,翱翔太空的一只猫,很神奇,我想做一只猫!!");

	}

}

4. 面试总结

此处的总结偏向于两者概念的总结,将其制作成表格

抽象类是半抽象的,有构造方法,抽象类可以包含抽象方法和非抽象方法,也可以有成员变量(不仅仅是常量)

类和类之间只能单继承,一个抽象类只能继承一个类(单继承)

接口是完全抽象的,没有构造方法,接口和接口之间支持多继承,一个类可以同时实现多个接口

这在Java 8之前基本正确,但在Java 8及之后,接口可以包含默认方法和静态方法

应用场景:

关系密切:多个功能的集成部分,可用抽象类(抽象类提供简单方法)

关系不密切:不相关的类提供公共部分,可用接口

标签: #JAVA 991
相关文章

Spring 实现 3 种异步接口 2024-10-18 09:07

大家好,我是苏三~ 如何处理比较耗时的接口? 这题我熟,直接上异步接口,使用 Callable、WebAsyncTask 和 DeferredResult、CompletableFuture等均可实现。 但这些方法有局限性,处理结果仅返回单个值。在某些场景下,如果需要接口异步处理的同时,还持续不断地

重学SpringBoot3-集成Redis(五)之布隆过滤器 2024-10-08 11:24

更多SpringBoot3内容请关注我的专栏:《SpringBoot3》 期待您的点赞👍收藏⭐评论✍ 重学SpringBoot3-集成Redis(五)之布隆过滤器 1. 什么是布隆过滤器? * 基本概念 适用场景 2. 使用 Redis 实现布隆过滤器 * 项目依赖 Redis 配置

SpringBoot整合异步任务执行 2024-10-08 11:24

同步任务: 同步任务是在单线程中按顺序执行,每次只有一个任务在执行,不会引发线程安全和数据一致性等 并发问题 同步任务需要等待任务执行完成后才能执行下一个任务,无法同时处理多个任务,响应慢,影响用 户体验 异步任务: 异步任务是在多线程中同时执行,多个任务可以并发执行,同时处理多个请求,响应快,资源

springboot kafka多数据源,通过配置动态加载发送者和消费者 2024-10-08 11:24

前言 最近做项目,需要支持kafka多数据源,实际上我们也可以通过代码固定写死多套kafka集群逻辑,但是如果需要不修改代码扩展呢,因为kafka本身不处理额外逻辑,只是起到削峰,和数据的传递,那么就需要对架构做一定的设计了。 准备test kafka本身非常容易上手,如果我们需要单元测试,引入ja

SpringBoot 集成 Redis 2024-10-08 11:24

一:SpringBoot 集成 Redis ①Redis是一个 NoSQL(not only)数据库, 常作用缓存 Cache 使用。 ②Redis是一个中间件、是一个独立的服务器;常用的数据类型: string , hash ,set ,zset , list ③通过Redis客户端可以使用多种语

SpringBoot整合QQ邮箱 2024-10-08 11:24

SpringBoot可以通过导入依赖的方式集成多种技术,这当然少不了我们常用的邮箱,现在本章演示SpringBoot整合QQ邮箱发送邮件…. 下面按步骤进行: 1.获取QQ邮箱授权码 1.1 登录QQ邮箱 1.2 开启SMTP服务 找到下图中的SMTP服务区域,如果当前账号未开启的话自己手动开启。

目录

IT 外包服务商

  • 意见投递
  • zyf6619

软件开发应用

主菜单

  • 首页
  • 软件开发
  • 计算机基础
  • Hello Halo
  • 新手必读
  • 关于本知识库
Copyright © 2024 your company All Rights Reserved. Powered by Halo.