说明
测试环境:JDK8
1.接口概述
1.1 接口的概念
接口就是公共的行为规范标准,在Java中,被看成是多个类的公共规范(
但并不是类哦
),是一种引用数据类型;例如,生活中我们常用的有USB接口 等等;
1.2 接口的语法规则
跟定义类的格式基本相同,只要将class
关键字换成 interface
关键字,就成功定义了一个接口;
如下所示:
public interface Iinterface {
//方法或属性
}
注:interface
为接口的关键字,Iinterface
为接口的名字,里面的方法和属性一般不加任何修饰符,也没有方法体(本质:就是抽象方法
);
1.3 接口的使用
接口定义好了之后,不能直接使用,必须由类进行实现,实现其中的所有的抽象方法,否则定义的该接口没有意义;
public class 类名称 implements 接口名称{
//.....
}
范例:笔记本电脑使用键盘、鼠标
要求如下:
(1)USB 接口:包含打开设备、关闭设备功能;
(2)笔记本类:包含开机、关机、使用USB设备功能;
(3)鼠标类:实现USB接口,并具备点击功能;
(4)键盘类:实现USB接口,并具备输入功能;
分析:由上可以看出有三个对象,分别为笔记本、键盘、鼠标,因此,就需要有三个实现类;
具体实现如下:
第1步: 定义一个USB接口;
public interface IUSB {
void openDevice();
void closeDevice();
}
第 2步:定义Computer 、Mouse、 Keyboard 的三个实现类;
Computer 类
public class Computer {
protected String brand; //笔记本型号
protected int price; // 笔记本价格
public void PowerOn(){
System.out.println("笔记本开机");
}
public void PowerOff(){
System.out.println("笔记本关机");
}
//使用USB设备
public void useDevice(IUSB usb){
if(null == usb){
System.out.println("没有设备接入");
return;
}
if(usb instanceof Mouse){
Mouse mouse = (Mouse) usb; //向下转型
mouse.Click();
}else if(usb instanceof Keyboard){
Keyboard keyboard = (Keyboard) usb;
keyboard.input();
}else{
System.out.println("无法识别该设备");
}
}
}
Keyboard 实现类
public class Keyboard implements IUSB{
@Override
public void openDevice() {
System.out.println("打开键盘");
}
@Override
public void closeDevice() {
System.out.println("关闭键盘");
}
//键盘输入功能
public void input(){
System.out.println("键盘输入");
}
}
Mouse 实现类
public class Mouse implements IUSB{
@Override
public void openDevice() {
System.out.println("打开鼠标");
}
@Override
public void closeDevice() {
System.out.println("关闭鼠标");
}
//鼠标点击功能
public void Click(){
System.out.println("鼠标点击");
}
}
第 3步:测试Computer
类;
public class TestComputer {
public static void main(String[] args) {
Computer computer = new Computer();
//笔记本开机
computer.powerOn();
computer.useDevice(new Mouse());
computer.useDevice(new Keyboard());
//笔记本关机
computer.powerOff();
}
}
运行结果:
笔记本开机
鼠标点击
键盘输入
笔记本关机
1.4 接口的特性
(1)
接口类型是一种引用类型,不能直接实例化
;
原因:只有类才能实例化对象,而接口不是类;
(2)
接口中每一个方法都是
public的抽象方法, 即接口中的方法会被隐式的指定为
public abstract(只能是
public abstract,其他修饰符都会报错;
如下所示:
public interface IUSB {
protected void removeDevice(); //报错
}
(3)
接口中可以含有变量,但是接口中的变量会被隐式的指定为 public static final 变量;
public interface IUSB {
double type=3.0;
}
public class TestComputer {
public static void main(String[] args) {
System.out.println(IUSB.type);//指定为static变量
IUSB.type=2.0; //指定为常量,修改会报错
}
}
报错提示如下所示:
(4)
接口虽然不是类,但是接口编译完成后字节码文件的后缀格式也是.class;
如上面所定义的USB接口
(5)
重写接口中方法时,不能使用default访问权限修饰;
public interface IUSB {
void openDevice();
public class Keyboard implements IUSB{
@Override
//报错, void 前面缺少 public
void openDevice() {
System.out.println("打开键盘");
}
报错信息如下所示:
(6)
接口中不能有静态代码块、实例代码块以及构造方法,否则会报错;
报错信息如下:静态代码块、构造方法也是相似的报错信息;
(7)
JDK8还可以包含default方法,对接口进行升级;
例如:增加一个打印USB型号的方法,为了其他代码不用改动,我们就可以增加一个默认方法来进行修改,如下所示:
public interface IUSB {
//默认方法
default void printType(){
System.out.println(type);
}
}
public class Computer {
protected String brand; //笔记本型号
protected int price; // 笔记本价格
public void powerOn(){
System.out.println("笔记本开机");
}
public void powerOff(){
System.out.println("笔记本关机");
}
//使用USB设备
public void useDevice(IUSB usb){
if(null == usb){
System.out.println("没有设备接入");
return;
}
if(usb instanceof Mouse){
usb.printType(); //调用来打印型号
Mouse mouse = (Mouse) usb; //向下转型
mouse.Click();
}else if(usb instanceof Keyboard){
Keyboard keyboard = (Keyboard) usb;
keyboard.input();
}else{
System.out.println("无法识别该设备");
}
}
}
2.实现多个接口
在Java
中,类和类之间是单继承的,一个类只能有一个父类,即:Java不支持多继承
,但是一个类与接口之间是多实现的,即:一个类可以实现多个接口
;
范例:动物(Animal)类
步骤如下:
第1步: 定义一个Animal类
public abstract class Animal {
protected String name;
int age;
// 构造方法
public Animal(String name, int age) {
this.name = name;
this.age = age;
}
// 定义一个eat()抽象方法
abstract void eat();
}
第2步: 提供一组接口, 分别表示 “会飞的”, "会跑的"和 “会游的”;
//表示会飞的接口
public interface IFlying {
void fly();
}
//表示会跑的接口
public interface IRunning {
void run();
}
//表示会游的接口
public interface ISwimming {
void swim();
}
因为接口必须要实现类来实现,因此要创建具体的类,也就是下面的第3步;
第3步: 创建4个具体的动物(可以创建很多哦
);
(1)创建Cat
类继承Animal
类来实现跑
这个接口;
如下所示:
public class Cat extends Animal implements IRunning{
public Cat(String name, int age) {
super(name, age);
}
public void eat(){
System.out.println(name+"吃鱼");
}
@Override
public void run() {
System.out.println(name+":无声的跑");
}
}
(2)创建Fish
类继承Animal
类来实现游
这个接口;
public class Fish extends Animal implements ISwimming{
public Fish(String name, int age) {
super(name, age);
}
@Override
void eat() {
System.out.println(name+"吃草");
}
@Override
public void swim() {
System.out.println(name+"正在用尾巴游");
}
}
但有的动物不仅会游还会跑(
eg:Frog
)所以就需要实现多个接口,如下所示;
(3)创建Frog
类继承Animal
类来实现跑
和游
这两个接口;
public class Frog extends Animal implements IRunning,ISwimming{
public Frog(String name, int age) {
super(name, age);
}
@Override
void eat() {
System.out.println(name+"吃昆虫");
}
@Override
public void run() {
System.out.println(name+"两条腿蹦");
}
@Override
public void swim() {
System.out.println(name+"蹬腿游泳");
}
}
还有一种神奇的动物, 水陆空三栖, 叫做 “鸭子”;因此,它能够
实现游、跑和飞三个接口
;`
如下所示:
public class Duck extends Animal implements IFlying,ISwimming,IRunning{
public Duck(String name, int age) {
super(name, age);
}
@Override
void eat() {
System.out.println(name+"吃菠菜");
}
@Override
public void fly() {
System.out.println(name+"慢慢的飞");
}
@Override
public void run() {
System.out.println(name+:正在用鸭掌跑");
}
@Override
public void swim() {
System.out.println(name+"像浆一样划");
}
}
需要注意的是:
(1)实现多个接口时,中间用
逗号隔开
;
(2)一个类实现多个接口时,每个接口中的抽象方法都要实现,否则类必须设置为抽象类
;
上面的代码展示了
Java
面向对象编程中较常见的用法:,即:一个类继承一个父类, 同时实现多种接口
;
继承表达的是is - a
的关系,而接口表达的是 具有xxx
特性;这样设计有什么好处呢?
类的使用者就不必关注具体类型, 而只需要关注某个类是否具备某种能力就行了;
如下所示:
假设,动物吃饱了就要出去走走,那现在只需要实现一个方法, 叫 “
walk
”,而在该方法的内部, 我们并不用关注到底是哪种动物, 只要参数是会跑就可以;
第4步: 接下来我们就可以测试观察一下结果啦;
public class TestAnimal {
public static void walk(IRunning running){
System.out.println("我要跑出去散步");
running.run();
}
public static void main(String[] args) {
IRunning [] animals={new Cat("元宝猫",1),
new Duck("小黄鸭",2)};
for(int i=0;i< animals.length;i++){
walk(animals[i]);
}
}
}
运行结果:
我要跑出去散步
元宝猫:无声的跑
我要跑出去散步
小黄鸭:正在用鸭掌跑
是不是很简单呢?加油~~