Java基础教程——接口
接口
接口只是一种约定。——Anders
接口定义了一种规范——多个类共同的公共行为规范。
- 对于接口的实现者——规定了必须向外提供哪些服务
- 对于接口的调用者——规定了可以调用哪些服务,如何调用这些服务
生活中经常见到“接口”——

接口的意义:
- 体现了“规范和实现分离”的设计哲学;
- 降低了各模块之间的耦合;
- 可以提高可扩展性和可维护性。
接口的使用
使用interface关键字定义接口:
|-- 接口中的方法默认是抽象方法,只定义不实现(Java 8开始可以有已实现的特殊方法)
|--|-- 类实现接口(implements), 必须实现接口中的所有的未实现方法,否则实现类成为抽象类
|-- 接口中的方法默认是public,可以不写。
|-- 接口不能实例化(不能new)
|-- 接口中的成员变量默认是public static final修饰的,是“常量”。
|-- 一个类可以实现多个接口
interface 接口务虚 {
void 应该做什么();
}
class 实现类务实 implements 接口务虚 {
@Override
public void 应该做什么() {
System.out.println("实现步骤:1.2.3.……");
}
}
public class 接口测试 {
public static void main(String[] args) {
接口务虚 instance;
// instance = new 接口务虚();不能new一个接口,编译不让过
instance = new 实现类务实();
}
}
Java不支持多重继承,但一个类可以实现多个接口。这是Java中接口的一个重要功能。
示例:让郭靖同时继承郭啸天和洪七公是会出错的!
class 郭啸天 {
}
class 洪七公 {
}
class 郭靖 extends 郭啸天 , 洪七公 {
}

使用接口可以实现“多重继承”:
郭靖只能是郭啸天的儿子,
但是郭靖可以同时是很多人的弟子

使用代码定义class 郭啸天,以及多个interface,郭靖可以是它们共同的子类——
class 郭啸天 {
void 忠义() {
System.out.println("忠义");
}
}
interface I江南七怪 {
int COUNT = 7;// 接口内成员变量默认加public static final
void 基本功();
}
interface I哲别 {
void 骑射();
}
interface I洪七公 {
void 降龙十八掌();
}
// ----------------------------------------------
class 郭靖 extends 郭啸天 implements I洪七公, I江南七怪, I哲别 {
@Override
public void 忠义() {
System.out.println("忠义");
}
@Override
public void 降龙十八掌() {
System.out.println("郭靖版 降龙十八掌");
}
@Override
public void 基本功() {
// The final field ... cannot be assigned
// COUNT = 8;
System.out.println("基本功:" + I江南七怪.COUNT);
}
@Override
public void 骑射() {
System.out.println("弯弓射大雕");
}
}
// ----------------------------------------------
public class TestInterface {
public static void main(String[] args) {
郭靖 gj = new 郭靖();
gj.忠义();
gj.基本功();
gj.骑射();
gj.降龙十八掌();
}
}
默认方法、静态方法、私有方法。
JAVA8开始,接口允许定义默认方法。
默认方法可以解决接口的升级问题。
比如有接口A,在之前的项目中已经有B、C实现了接口A。现在需要对接口A进行升级,因为接口的方法必须实现,因此B、C也需要新增代码。
有了默认方法,之前的B、C类不用新增代码了。
JAVA8开始,接口允许定义静态方法,也叫类方法,通过接口名直接调用(不能通过对象名调用)
多重继承时,静态方法名可能冲突,因此不准通过对象调用;
实现多接口时,如果默认方法名发生冲突,会出现编译错误,重写方法可以解决冲突。
如果继承的父类和实现的接口中有方法名冲突,可以不重写,默认使用父类里的同名方法。
interface I洪七公 {
void 降龙十八掌();
// Java 8默认方法
default void 打狗棒() {
System.out.println("打狗棒");
}
// Java 8类方法
static void 好吃() {
System.out.println("天生好吃");
}
}
// ----------------------------------------------
class 郭靖 implements I洪七公 {
@Override
public void 降龙十八掌() {
System.out.println("郭靖版 降龙十八掌");
}
}
// ----------------------------------------------
public class TestInterface {
public static void main(String[] args) {
郭靖 gj = new 郭靖();
gj.降龙十八掌();
gj.打狗棒();// 默认方法,不实现也能使用,很像抽象类
I洪七公.好吃();// 类方法,用接口名直接调用
}
}
应用场景
下面程序,模拟了一个Telephone接口,座机(FixedLineTelephone)已经实现了call()方法。
现在接口升级,加入msg()方法用于发短信,新的MobilePhone类需要实现该方法,但是之前的FixedLineTelephone类无需修改。虽然不用实现,但其对象是可以调用新的方法的。
public class 接口新方法 {
public static void main(String[] args) {
FixedLineTelephone p1 = new FixedLineTelephone();
p1.msg();
MobilePhone p2 = new MobilePhone();
p2.msg();
Telephone.mStatic();// 静态方法,通过接口名调用
}
}
interface Telephone {
void call();
default void msg() {// 新加一个默认方法
System.out.println("sendMsg");
}
// 还有静态方法
static void mStatic() {
System.out.println("mStatic");
}
}
// 传统固定电话,只能打电话
class FixedLineTelephone implements Telephone {
@Override
public void call() {
System.out.println(this.getClass() + "call");
}
}
// 新的手机出现,可以发短信了
class MobilePhone implements Telephone {
@Override
public void msg() {
Telephone.super.msg();
System.out.println(this.getClass() + "SendMsg...");
}
@Override
public void call() {
System.out.println(this.getClass() + "call");
}
}
私有方法
JDK9提供的功能,如果多个接口的方法中有重复代码,则可以提取出来放入一个方法中。
这个方法只有接口自己可以调用,实现类不能调用。
|--私有方法有静态和非静态两种
测试(本讲义使用Eclipse,配置JDK12或JDK9比较麻烦,使用如下简单测试办法):
下载JDK12
链接:https://pan.baidu.com/s/12bGX2G_orQq7_OfTZ54eKQ
提取码:fnlg解压到不是之前JAVA安装的文件夹下(JDK12没有独立的JRE,都放在一起回导致javac和java的-version不一致)
修改JAVA_HOME为JDK12的路径,如:C:\Users\XXX\Downloads\jdk-12
在桌面新建一个文件夹,如J12,里面写java代码如下。
public class TestInterfacePrivateMethod{
public static void main(String[] args) {
A a = new A();
a.defaultMethod_1();
a.defaultMethod_2();
// 外界不可调用私有方法 a.privateMethod();
I.staticMethod_1();
I.staticMethod_2();
// 外界不可调用私有方法 I.privateStaticMethod();
}
}
interface I{
private void privateMethod(){
System.out.println("Common");
}
default void defaultMethod_1() {
privateMethod();
System.out.println("defaultMethod_1");
}
default void defaultMethod_2() {
privateMethod();
System.out.println("defaultMethod_2");
}
private static void privateStaticMethod(){
System.out.println("Common Static");
}
static void staticMethod_1() {
privateStaticMethod();
System.out.println("staticMethod_1");
}
static void staticMethod_2() {
privateStaticMethod();
System.out.println("staticMethod_1");
}
}
class A implements I{
}
接口继承接口
接口可以继承接口,一个接口可以继承多个其它接口。
interface I1 {
void m1();
}
interface I2 {
void m2();
}
interface I3 extends I1, I2 {
void m3();
}
class 实现类 implements I3 {
@Override
public void m1() {
}
@Override
public void m2() {
}
@Override
public void m3() {
}
}
// ---------------------------
public class 接口继承接口 {
}
让接口继承其它接口,可以减少单个接口要做的事情,使得职责划分更清晰,代码更易理解。JDK源码、Java开源框架源码中很多接口继承接口的具体案例,后面都会看到。
Java基础教程——接口的更多相关文章
- Java基础教程(18)--继承
一.继承的概念 继承是面向对象中一个非常重要的概念,使用继承可以从逻辑和层次上更好地组织代码,大大提高代码的复用性.在Java中,继承可以使得子类具有父类的属性和方法或者重新定义.追加属性和方法. ...
- Java基础教程(12)--深入理解类
一.方法的返回值 当我们在程序中调用方法时,虚拟机将会跳转到对应的方法中去执行.当以下几种情况发生时,虚拟机将会回到调用方法的语句并继续向下执行: 执行完方法中所有的语句: 遇到return语句: ...
- Java基础教程:注解
Java基础教程:注解 本篇文章参考的相关资料链接: 维基百科:https://zh.wikipedia.org/wiki/Java%E6%B3%A8%E8%A7%A3 注解基础与高级应用:http: ...
- Java基础教程:Lambda表达式
Java基础教程:Lambda表达式 本文部分内容引用自OneAPM:http://blog.oneapm.com/apm-tech/226.html 引入Lambda Java 是一流的面向对象语言 ...
- Java基础教程:泛型基础
Java基础教程:泛型基础 引入泛型 传统编写的限制: 在Java中一般的类和方法,只能使用具体的类型,要么是基本数据类型,要么是自定义类型.如果要编写可以应用于多种类型的代码,这种刻板的限制就会束缚 ...
- Java基础教程:反射基础
Java基础教程:反射基础 引入反射 反射是什么 能够动态分析类能力的程序称为反射. 反射是一种很强大且复杂的机制. Class类 在程序运行期间,Java运行时系统始终为所有对象维护一个被称为运行时 ...
- Java基础教程:面向对象编程[2]
Java基础教程:面向对象编程[2] 内容大纲 访问修饰符 四种访问修饰符 Java中,可以使用访问控制符来保护对类.变量.方法和构造方法的访问.Java 支持 4 种不同的访问权限. default ...
- Java基础教程:JDBC编程
Java基础教程:JDBC编程 1.什么是JDBC JDBC 指 Java 数据库连接,是一种标准Java应用编程接口( JAVA API),用来连接 Java 编程语言和广泛的数据库. JDBC A ...
- Java基础教程:对象比较排序
Java基础教程:对象比较排序 转载请标明出处:http://blog.csdn.net/wangtaocsdn/article/details/71500500 有时候需要对对象列表或数组进行排序, ...
随机推荐
- 【Spring Cloud + Vue 有来商城】研发小组开发规范全方位梳理
项目演示 后端 Spring Cloud实战 | 第一篇:Windows搭建Nacos服务 Spring Cloud实战 | 第二篇:Spring Cloud整合Nacos实现注册中心 Spring ...
- 基于gin的golang web开发:模型验证
Gin除了模型绑定还提供了模型验证功能.你可以给字段指定特定的规则标签,如果一个字段用binding:"required"标签修饰,在绑定时该字段的值为空,那么将返回一个错误.开发 ...
- 【Elasticsearch 技术分享】—— 十张图带大家看懂 ES 原理 !明白为什么说:ES 是准实时的!
前言 说到 Elasticsearch ,其中最明显的一个特点就是 near real-time 准实时 -- 当文档存储在Elasticsearch中时,将在1秒内以几乎实时的方式对其进行索引和完全 ...
- 第4章 Function语意学
第4章 Function语意学 目录 第4章 Function语意学 4.1 Member的各种调用方式 Nonstatic Member Function(非静态成员函数) virtual Memb ...
- z-index属性详解
z-index属性详解 目录 z-index属性详解 一.定义和用法 二.代码 三.效果图 一.定义和用法 z-index属性指定一个元素的堆叠顺序,也就是z轴 position属性定义的是x轴和y轴 ...
- EVM 2.0 预览版,跃见非凡,源于鸿蒙,开启物联网小程序新时代
1. 基于EVUE的物联网小程序 EVM诞生以来,一直致力于让物联网开发变得简单,自鸿蒙OS 1.0 发布后,最引人注目的莫过于华为在应用程序开发框架层面面向应用开发者提供了一种全新的开发方式: 框架 ...
- Python基本数据类型与数据结构(数据挖掘学习)
前言 最近工作和研究涉及到数据挖掘和机器学习,出于归纳和总结知识的目的写下这一系列的文章,这一系列文章将会包括Python的基本数据类型和数据结构,函数和面向对象相关的知识,然后会介绍数据挖掘和机器学 ...
- 把数据转化为JSON格式用ajax进行前后端交互
接着在https://www.cnblogs.com/dong973711/p/10907733.html的基础上做验证. 从前端提交数据 前端页面,submit.html <!DOCTYPE ...
- 跟我一起学Redis之Redis事务简单了解一下
前言 关系数据库中的事务,小伙伴们应该是不陌生了,不管是在开发还是在面试过程中,总有两个问题逃不掉: 说说事务的特性: 事务隔离级别是怎么一回事? 事务处理不好,数据就可能不准确,最终就会导致业务出问 ...
- Git操作:远程仓库(git remote)的添加、管理和删除
这是你的git仓库,他已经添加了一个远程仓库,可以用git remote -v查看绑定的仓库列表,他会以<仓库名> <仓库地址>的形式展示出来(一个仓库会显示两遍): $ g ...