抽象类和接口——Java

本文详细介绍了Java中的抽象类和接口的区别与联系。抽象类主要用于被继承,强制子类实现抽象方法,而接口提供了定义规范的方式,可以实现多继承。文章通过实例分析了抽象方法、抽象类的规则以及接口的命名、内容和继承特性,强调了面向抽象编程的重要性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

抽象方法和抽象类

如果一个class定义了方法,但没有具体执行代码,这个方法就是抽象方法

  • 抽象方法用abstract修饰
  • 抽象方法没有执行任何语句
  • 因为无法执行抽象方法,因此这个类也必须申明为抽象类(abstract class)
  • 无法实例化一个抽象类

那么我们现在看最后一个,

无法实例化的抽象类有什么用?

  • 抽象类用于被继承
  • 抽象类可以强迫子类实现其定义的抽象方法(否则编译错误)
  • 抽象方法实际上相当于定义了“规范”

抽象类的作用:

  • 被继承
  • 强迫子类实现抽象方法
  • 抽象方法相当于定义“规范”
public abstract class Person{
    public abstract void run();
}
public class Student extends Person{
    @Oveerride
    public void run(){....}
}
public class Teacher extends Person{
    @Override
    public void run(){....}
}

Person s = new Student();
Person t =new Teacher();
//不关心Person类型对象的具体类型;
s.run();
t.run();
//同样不关心新的子类是如何实现run()方法的;
Person e = new Emploee();
e.run();

面向抽象编程的本质:

  • 上层代码只定义规范
  • 不需要子类即可编译
  • 具体逻辑由不同子类实现,调用者不用关心具体是怎么实现的。

再解释一遍

  抽象方法和抽象类必须使用abstract修饰符来定义,有抽象方法的类只能被定义成抽象类,抽象类里可以没有抽象方法。

抽象方法和抽象类的规则如下:

  • 抽象类必须使用abstract修饰符来修饰,抽象方法
  • 抽象类不能被实例化,无法使用new关键字来调用抽象类的构造器创建抽象类的实例。及时抽象类里不包含抽象方法,这个抽象类也不能创建实例。
  • 抽象类可以包含成员变量、方法(普通方法和抽象方法都可以)、构造器、初始化块、内部类(接口、枚举)5种成分。抽象类的构造器不能用于创建实例,主要是用于被其子类调用
  • 含有抽象方法的类(包括直接定义了一个抽象方法;或继承了一个抽象弗雷,但没有完全实现父类包含的抽象方法;或实现了一个接口但没有完全实现接口包含的抽象方法三种情况)只能被定义成抽象类。

抽象类多了个能力:抽象类可以包含抽象方法;
抽象类少了个能力:抽象类不能用于创建实例

例子分析

关于疯狂java这本书给出的例子如下:

我想如果在eclipse里的配色方案会帮助我们阅读代码的话以后是不是应该只用图片贴代码会好一点?

这里写图片描述

这里写图片描述

这里写图片描述

已经做了居中处理

上面main()方法中定义了两个shape类型的引用变量,他们分别指向triangle对象和circle对象。由于在shape类中定义了calPerimeter()方法和gettype方法,所以程序可以直接盗用s1变量和s2变量的calperimeter()方法和gettype()方法,无须强制类型转换为其子类类型。

我们从前边的程序可以看出,抽象类不能创建势力,只能当做父类来被继承。所以它具有更高层次的抽象。从多个具有相同特征的类中抽象出一个抽象类,以这个抽象类作为其子类的末班,从而避免了子类设计的随意性。

接口

如果一个抽象类没有字段,所有方法全部是抽象方法,就可以把该抽象类改写为接口(interface)

  • 使用interface声明一个接口
  • 接口定义的方法默认是public所有abstract不用写

命名规则

  • 修饰符可以是public或者省略, 如果省略了public访问控制符,则默认采用包权限访问控制符,即只有在相同包接口下才可以访问该接口
  • 接口名应与类名采用相同的命名规则,即如果仅从语法角度来看,接口名只要是合法的标识符即可;如果要遵守java可读性贵方,则接口名应由多个有意义的单词连缀而成,每个单词首字母大写,单词与单词之间无需任何分隔符。接口名通常能够使用形容词
  • 一个接口可以有多个直接父接口(也就是说接口可以多“继承”,前面说过很多次了),但接口只能继承接口,不能继承类

接口里可以有什么?

  • 接口里可以包含成员变量(只能是静态常量)
  • 方法(只能是抽象实例方法、类方法或默认方法)
    • 所以如果不是定义默认方法,系统将自动为普通方法增加abstract修饰符;定义接口里的普通方法时不管是否使用public abstract修饰符,接口里的普通方法总是使用public abstract来修饰。 接口里的普通方法不能有方法实现(方法体);但类方法、默认方法都必须有方法实现(方法体)
  • 内部类(包括内部接口、枚举)

接口和继承有啥明显区别?

  • interface是java内置的纯抽象接口
  • 实现interface使用implements
  • 可以实现多个interface(这就是java取代多继承的功能)

这个接口和我们平时所常听到的接口一样吗?

  • java的接口特指interface定义的接口,只定义方法签名
  • 编程接口泛指接口规范,如方法签名,数据格式,网络协议等

接口和抽象类

abstract classinterface
继承只能extends一个class可以implement多个interface
字段可以定义实例字段不能定义实例字段
抽象方法可以定义抽象方法可以定义抽象方法
非抽象方法可以定义非抽象方法可以定义default方法


那么接口和接口之间呢?

  • 一个interface可以继承自另一个interface
  • interface继承自interface使用extends
  • 相当于扩展了接口的方法

总结:

  • 接口定义了纯抽象规范
  • 类可以实现多个接口
  • 接口也是数据类型,适用于向上转型和向下转型
  • 接口不能定义实例字段
  • 接口可以定义default方法(1.8)

具体例子

这里写图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值