当前课程知识点:Java程序设计 > 第四章 接口与多态 > 4.1-接口 > 接口
大家好
欢迎回来继续学习
JAVA语言程序设计
这一节我们来学习接口
接口是什么呢
实际上我们可以把接口
看作一个纯的抽象类
它只提供设计
而不提供实现
在接口中呢
可以规定方法的原型
包括方法名 参数列表
及返回类型
但是不能规定方法的主体
也就是说不能定义方法的实现
除了可以在接口中
规定方法的原型以外呢
也可以包含基本数据类型的
数据成员
但是这些数据成员默认
都是静态的和常量
也就是默认是用
static和final来修饰的
那么使用接口有什么好处呢
接口的作用又是什么呢
接口是面向对象程序设计的
一个重要机制
使用接口呢
可以继承多个类的设计
实际上我们说过接口
就相当于一个纯的抽象类
实际上只有类的设计
没有类的实现
所以称为它接口
因为它只提供了一个类的
对外提供服务的这种调用形式
但是实现是没有的
所以第一点使用接口
可以实现类的设计的多继承
另外利用接口还可以实现
类与类之间的协议
可以将类从不同的角度
对它的功能进行分组
然后用接口来代表
而不必去介意这些类之间
是否有某种继承关系
也就是不用介意
类与类之间它们的层次关系
这样可以最大限度的
利用动态绑定 利用多态性
实现对细节的隐藏
我们知道接口中
还可以定义什么呢
定义一些基本数据类型的常量
这样使用接口还可以
在不同的类之间
实现常量的共享
现在我们来看一下这个图
通过这个图我们可以来体会一下
接口允许我们在看起来
不相干的对象之间
定义共同的行为
我们看这里定义了一个food食品类
一个weather compoment
天气现象类
那么食品和天气现象类的
下级子类雪
它们都是可以吃的
所以我们从这个角度
将功能进行分组
就是可以吃的
都可以说喂过某个人吃
feed To a person
喂给某个人吃
那么只要把这个特性抽象出来
作为一个分组
设计一个什么呢
设计一个接口
Edible接口可吃的这么一个接口
那现在我们来看这两个类之间
存在着什么继承组合关系吗
不存在
但是我们可以给这两个类
加上一个统一的接口
那么从可吃这个角度
我们可以给这两个类的对象
发同样的消息
比如说feedto这个消息
给某个人吃
这是一个比较形象和好玩的例子
举这个例子为的是让大家
能够理解我们刚才说的
看起来不相干的对象之间
我们可以按照它的共同行为
去为它们设计一个统一的接口
好 接下来我们来看
声明接口的语法形式是什么
声明接口的时候呢
我们要用这个interface这个关键字
表现我们正在声明的是一个接口
然后后面要给出接口名称
接口也可以去继承父接口
这个后面我们会专门讲到
然后在这个接口的这个提议里边
就是这一堆括号里面
是可以声明方法的原型
或者声明静态的常量
那由于接口里面声明的数据
都是静态的常量
所以这些数据成员
是一定要有初值的
而且因为它是常量
这个值是在运行过程中
任何时候都不能再更改的
那么实际上由于它默认是常量
所以final关键字是可以省略的
那么接口中的方法
必须是抽象方法
也就是我们有方法体的
所以我们也可以省略public
还有abstract这两个关键字
它默认是public
因为它规定是对外的服务接口
所以它当然应该是公有的
因为它规定是不许有方法体的
所以它默认是abstract
所以这两个关键字也是可以省略的
现在我们来看一个接口声明的例子
我们可以像这样声明一个
二维几何图形接口
用interface关键字
说明声明的是个接口shape2D
然后在这里面有基本类型的
double类型的一个常量pi
初始化成3.14
这个一定要初始化
另外还有一个抽象方法
是计算面积的方法area
实际上我们前面讲过
由于默认的里面的数据成员
一定要final
默认的这个方法一定是public
和抽象的abstract
所以这些关键字是可以省略的
所以我们看下面这个接口声明
像这样直接声明一个
double类型的pi并且初始化
直接声明一个area
这个求面积的方法原型就可以了
final public abstract关键字
都可以省略了
由于接口里边
只有方法的原型声明
没有方法体的实现
所以跟抽象类一样
接口也是不能够产生实例的
不能实例化
所以我们不能去new
一个接口类型的对象出来
那接口在什么时候
它声明的这个方法
可以真正起作用呢
而不是一种原型光是个形式呢
就要由实现接口的类来
对方法体给出实现
接下来我们来看实现接口的语法
实现接口呢
实际上就是利用接口
来设计类的过程
我们来看这个语法形式
在这儿我们要使用implements关键字
看起来这个形式跟我们定义一个类
去继承一个超类是很像的
继承超类的时候
我们用extends关键字
是扩展这个关键字
而实现接口的时候用implements
这个关键字实现
然后后面是接口的名称
然后在类体中呢
要给出接口中声明的那些方法原型
它的方法体的实现要在这里给出
另外除此而外
当然本体中还可以声明更多的变量
和更多的方法
注意我们在这里必须要实现
这个接口中的所有方法
而且来自接口的方法呢
必须要声明成公有的public
现在我们来看一下
实现接口的这个代码的例子
这里我们定义了一个circle圆类
它实现了接口shape2D
这个二维几何图形类
那么在圆类中呢
肯定必须要覆盖这个area
求面积的这个方法
这是继承来的抽象方法
一定要有方法体的实现
除此而外呢圆类还可以声明
自己的方法
比如说它的构造方法
还可以声明它自己的属性
比如说圆的半径
那么这边我们来看
在声明一个rectangle一个矩形类
它同样也是实现了shape2D
它有它不同的求面积方法
按照自己的公式
去覆盖了这个area方法
另外自己又新增了宽和高
这样两个属性
还可以新增自己的其他方法
这里呢有一个自己的构造方法
现在我们来测试一下
实现接口的这两个类
在这里我们构造了一个矩形对象
然后调用area求面积
然后又构造了一个圆面积
同样也调用area求面积
虽然调用的都是area方法
但是我们从计算结果可以看到
这个面积结果都是正确的
说明它们都正确的调用了
各自所属的类的area方法
按照各自正确的公式计算了面积
在接下来这个例子中
我们在做更多的测试
现在我们来声明两个接口类型的
引用变量 var1 var2
同样还是构造一个矩形
构造一个圆
那这次不同的是
将矩形对象的引用
赋值给shape2D接口引用
这中间发生了隐含的类型转换
向上转型了
然后将圆对象的引用
也赋值给shape2D类型的引用
那么我们每次调用area方法
都是通过一个shape2D引用调用的
从引用类型上看
var1 var2类型是一样的
都是shape2D类型的
调用的方法都是area方法
发出了同样的消息
但是真正去执行
这个求面积方法的时候
依然是准确的执行了
矩形自己的求面积方法
和圆自己的面积方法
虽然在JAVA中
我们继承类的时候
只能继承一个直接超类
不许多继承
但是我们实现接口的时候
却可以同时去实现多个接口
也就是说我们可以在
只继承设计的这种前提下
去进行多继承
接下来我们来看一下
实现多个接口的语法
我们来看实现多个接口的语法
就是在implements后面
可以用逗号分隔
列出多个接口的名字
然后在这个类的类体中呢
将这多个接口中
声明的方法原型
全都给予实现
那么通过这样一种机制
就实现了对设计的多重继承
现在我们就来看这个通过
实现接口来达到多重继承的例子
在这个例子中
我们要声明一个circle类圆类
去实现一个shape2D接口
和一个color接口
shape2D接口里面定义了
有常量pi
还有计算面积的这个抽象方法
而color接口里面
就有setcolor设计颜色的这个方法
那么通过实现这两个接口呢
circle类可以同时拥有
这两个接口中定义的方法成员了
这样就达到了
对设计进行多重继承的目的
好 我们来看在这个圆类中
覆盖了area方法
给出了自己特殊的准确的计算
圆面积的这个算法
在setcolor方法的
覆盖的方法体中
也按照自己的方式去覆盖了
去给出了方法体
那么这个时候我们来看
测试一下构造一个圆类对象
然后去调用setcolor方法
然后调用area求面积方法
我们看到都很好的实现了
在圆类中设计的功能
就像类与类之间
可以有继承关系一样
接口与接口之间呢
也可以有继承关系
也就是扩展关系
那么我们可以从一个已有的接口
扩展出更多的接口来
那么已有的这个接口呢
就称为超接口
而扩展出来的接口呢
就称为子接口
当我们去实现一个接口的时候呢
也必须连这些接口
它的超接口中规定的方法
也都要实现
因为超接口中规定的方法原型
也被子接口继承来了嘛
我们来看一下这个接口扩展的语法
接口由于它比较简单
所以它可以支持多继承
也就是一个接口
可以继承自多个超接口
所以在这个extends关键词后面
可以有多个超接口的名字列在那儿
现在我们来看一下这个图
这里给出了一个接口之间
继承的这么一个例子
我们看这个shape是超接口
然后shape2D和shape3D
是它的子接口
然后圆类circle
矩形类rectangle
实现了接口shape2D
而box类以及sphere类
实现了shape3D
所以我们看到这个接口之间
它具有继承关系
那么实现接口的类呢
也就是像这个circle
它就必须把shape2D和shape接口中
规定的方法都实现
现在我们通过这个实际的代码
来看一下接口的扩展
首先我们看在这个接口shape中
声明了常量pi
并且进行了初始化
那么还有一个setcolor方法的接口
在shape2D中呢
是声明了一个计算面积的接口
shape2D继承或者说叫扩展了
shape接口
所以它的常量pi
还有setcolor也都被继承过来了
现在我们以一个具体的circle圆类
为例子来看一下
这个circle呢
它实现了shape2D接口
因此它就具有了shape接口中
声明的这个常量pi
同时继承了shape2D里面的
抽象方法area
还有shape2D的超接口的方法setcolor
那我们来看在这个area
这个方法体中
它用到了pi
直接用就行了
因为pi是继承过来了
覆盖了area方法
也覆盖了setcolor方法
所以它实现的所有的接口中的
抽象方法都覆盖了
这样我们就可以构造一个圆类对象
来测量一下
调用setcolor 调用area
那么调用的是它自己
覆盖的这个方法体
我们看到运行结果是正确的
那么归纳一下
我们在这个例题中
首先声明了父接口shape
然后声明它子接口shape2D
之后我们让这个圆类
circle类实现了shape2D
这个子接口
那它当然连它的超接口中的
方法原型也就都继承过来了
也就是这个类中
必须明确的去定义setcolor的方法体
也就是覆盖它
还有area的方法
也是要覆盖这个方法
都要定义方法体
定义了这样的方法体以后
那么这个circle就完整了
所有的方法就实现了
于是我们就可以去构造
circle类型的对象
然后去调用它的setcolor
还有area方法
在这一节中呢
我们介绍了接口的概念和作用
以及声明和实现接口的语法
还有接口的扩展
好 这一节内容就是这样
-1.0-导学
--1.0-导学
-1.1-Java与面向对象程序设计简介
--第一章 Java语言基础知识--1.1-Java与面向对象程序设计简介
-1.2-基本数据类型与表达式
-第一章 Java语言基础知识--1.2-基本数据类型与表达式
-1.3-数组
--1.3.1-数组
-第一章 Java语言基础知识--1.3-数组
-1.4-算法的流程控制
--第一章 Java语言基础知识--1.4-算法的流程控制
-1.5-第一章小结
-第一章编程练习题
-课件
--外部链接
-Java环境配置、Eclipse使用、Helloworld程序详解
--使用eclipse建立Java项目、编写和运行Java程序
-Java数据类型
--Java整数类型
--Java浮点类型
--数据类型实战
--数据类型转换
--Java强制类型转换精度损失示例与表达式中的数据类型转换
-Java数组
-Java变量
--Java的变量
-命令行参数
--命令行参数的介绍
-2.0-导学
--2.0-导学
-2.1-面向对象方法的特性
--第二章 类与对象--2.1-面向对象方法的特性
-2.2-1-类声明与对象创建
--第二章 类与对象--2.2-1-类声明与对象创建
-2.2-2-数据成员
--第二章 类与对象--2.2-2-数据成员
-2.2-3-方法成员
--第二章 类与对象--2.2-3-方法成员
-2.2-4-包
--2.2-4-包
--第二章 类与对象--2.2-4-包
-2.2-5-类的访问权限控制
--第二章 类与对象--2.2-5-类的访问权限控制
-2.3-1-对象初始化
--第二章 类与对象--2.3-1-对象初始化
-2.3-2-内存回收
--第二章 类与对象--2.3-2-内存回收
-2.4-枚举类
--2.4-枚举类
--第二章 类与对象--2.4-枚举类
-2.5-应用举例
--2.5-应用举例
-2.6-第2章小结
-第二章编程练习题
-课件
--第二章课件
-3.0-导学
--3.0-导学
-3.1.1-3.1.2-类继承的概念和语法
--第三章 类的重用--3.1.1-3.1.2-类继承的概念和语法
-3.1.3-隐藏和覆盖
--第三章 类的重用--3.1.3-隐藏和覆盖
-3.2-Object 类
--第三章 类的重用--3.2-Object 类
-3.3-终结类与终结方法
--第三章 类的重用--3.3-终结类与终结方法
-3.4-抽象类
--3.4-抽象类
--第三章 类的重用--3.4-抽象类
-3.5-泛型
--3.5-泛型
--第三章 类的重用--3.5-泛型
-3.6-类的组合
--3.6-类的组合
-3.7-小结
--3.7-小结
-第三章编程练习题
-课件
--课件
-4.0-导学
--导学
-4.1-接口
--接口
--第四章 接口与多态--4.1-接口
-4.2.1-4.2.2-类型转换
--类型转换
--第四章 接口与多态--4.2.1-4.2.2-类型转换
-4.2.3-方法的查找
--方法的查找
--第四章 接口与多态--4.2.3-方法的查找
-4.3-多态的概念
--多态的概念
--第四章 接口与多态--4.3-多态的概念
-4.4-多态的应用举例
--多态的应用举例
--第四章 接口与多态--4.4-多态的应用举例
-4.5-构造方法与多态性
--构造方法和多态性
--第四章 接口与多态--4.5-构造方法与多态性
-4.6-本章小结
--本章小结
-第四章编程作业
-课件
--课件
-5.0-导学
--5.0-导学
-5.1.1-5.1.2-异常处理的概念
--第五章 输入输出--5.1.1-5.1.2-异常处理的概念
-5.1.3-5.1.5-异常的处理
--第五章 输入输出--5.1.3-5.1.5-异常的处理
-5.2-输入输出流的概念
--输入输出流的概念
--第五章 输入输出--5.2-输入输出流的概念
-5.3.1-写文本文件
--写文本文件
--第五章 输入输出--5.3.1-写文本文件
-5.3.2-读文本文件
--读文本文件
--第五章 输入输出--5.3.2-读文本文件
-5.3.3-写二进制文件
--写二进制文件
--第五章 输入输出--5.3.3-写二进制文件
-5.3.4-读二进制文件
--读二进制文件
-5.3.5-File类
--File类
-5.3.6-处理压缩文件
--处理压缩文件
-5.3.7-对象序列化
--对象序列化
-5.3.8-随机文件读写
--随机文件读写
-5.4-本章小结
--本章小结
-课件
--课件
-6.0-导学
--导学
-6.1-Java集合框架介绍
--第六章 对象群体的组织--6.1-Java集合框架介绍
-6.2-主要接口及常用的实现类
--第六章 对象群体的组织--6.2-主要接口及常用的实现类
-6.3-常用算法
--常用算法
-6.4-数组实用方法
-6.5-基于动态数组的类型(Vector, ArrayList)
--基于动态数组的类型(Vector, ArrayList)
-6.6-遍历Collection
-6.7-Map接口及其实现
-6.8-第6章小结
--第6章小结
-课件
--课件
-7.0-导学
--导学
-7.1-绘图
--绘图
-7.2-Swing基础
--Swing基础
-7.3-Swing的层次
--Swing的层次
-7.4-布局管理
--布局管理
-7.5-内部类
--内部类
-7.6-事件处理的基本概念
-7.7-事件派发机制
--事件派发机制
-7.8-顶层容器
--7.8-顶层容器
-7.9-中间层容器(一)
-7.10-中间层容器(二)
-7.11-原子组件(一)
-7.12-原子组件(二)
-7.13-原子组件(三)
-7.14-其它Swing特性
-7.15-第7章小结
-课件
--课件