目录
1.接口
1.1接口描述
其实在生活中接口随处可见比如说:
家里的插线面板:
这里有两个五孔插线面板,它们由不同的厂商生产的
左边这个是公牛的,右边这个是西门子的,为什么不同厂商生产的插线面板装在家里都可以使用呢,因为它们是遵循同样的规范来生产的。
所以说接口其实就是一种公共的规范,只要符合规范,我们都可以使用。
其实与计算机相关的接口也随处可见
比如这是一个笔记本,它旁边有两个小口
这个是usb口,那么看到这个口,我在操作笔记本的时候发现了笔记本面板控制鼠标不方便,我要接一个鼠标怎么办呢?
这样我们买一个带usb线的鼠标接到笔记本上的usb接口就可以了
那么再比如说,我怕把笔记本的自带的键盘敲坏了,怎么办呢我们买一个自带usb线的外置键盘接到笔记本上的usb接口就可以了。
再比如说我想把电脑上的东西拷贝给别人,如果有网络我通过网络或者一些软件发送就可以了,如果没有网络怎么办呢?可以使用u盘,用u盘拷贝出来,再把u盘插到你电脑上的口里面,那么我的东西就传到你的电脑里面了。
那么这些东西是由不同的厂商生产的,但是它们却可以通用在usb接口上,这为什么呢?
因为它们参照的是同样的usb接口的规范来生产的。
小结:
接口就是一种公共的规范标准,只要符合规范标准,大家都可以通用
Java中的接口更多体现在对行为的抽象。
1.2接口的特点
先到程序中演示再小结:
代码演示:
/*
定义了一个接口
*/
public interface Jumpping {
//1.在接口类中写一个抽象方法
public abstract void jump();
}
/*
2.子类继承Jumpping接口
这时候会报错,按照以前的思想就是没有重写抽象方法
所以我们来重写方法
*/
//4.Cat类实现了Jumpping接口。再来一个类实现接口→5.
class Cat implements Jumpping{
@Override
public void jump() {
System.out.println("猫可以跳高了");
}
/*3.这时候发现它还报错:这里不需要接口
说明它需要一个类,而我们类和接口之间不能用继承
用的是implements 实现的意思
也就是类实现接口。这是接口的第二个特点
*/
}
/*5.让这个狗也实现跳高。
我让这个Dog实现接口Jimpping,必须要重写抽象方法
但是我现在不想重写方法怎么办呢?
很明显我们要提供一个abstract修饰一下
这个类就变成了抽象类,抽象类在实现接口的时候
它可以不用重写接口里面的方法,但是Dog的具体的子类要继承
Dog的时候还得去重写接口里面的抽象方法
*/
abstract class Dog implements Jumpping{
}
/*
测试类
*/
class JumppingDemo {
public static void main(String[] args) {
//4.接口有了我们来创建接口的对象
// Jumpping j = new Jumpping();
/*5.这里又报错了它说:Jumpping是抽象的不能实例化
由此可见接口也是一个抽象的内容,它主要是对行为进行抽象
所以它本身也是一个抽象的内容,它不能被实例化。
接口真的不能被实例化嘛?不要急,我们还是参照多态的方式
来实例化
*/
//6.这样写
Jumpping j = new Cat();
j.jump();//猫可以调高
/*7.然后编译左边,Jumpping接口里面有jump这个内容
执行看右边,然后右边Cat类里重写了这个方法
所以在控制台输了猫可以跳高了,这就是接口的第三个特点
接口的实例化也采用的是多态的形式,用它的实现类对象来进行实例化的
*/
}
}
小结接口的特点:
- 接口用关键字interface修饰
public interface 接口名 { }
- 类实现接口用关键字implements表示
public class 类名 implements 接口名 { }
- 接口不能实例化
接口如何实例化呢?老规矩 参照多态的方式,通过实现类对象实例化,这叫接口多态。
- 接口的形式有:
具体类多态,抽象类多态,接口多态。
详解:具体、抽象、接口多态:
具体类多态:
public class Fu { }
public class Zi extends Fu { }
具体类多态:
Fu f = new Zi();
抽象类多态:
public abstract class Fu { }
public class Zi extends Fu { }
Fu f = new Zi();
接口多态:
public interface class Fu { }
public class Zi implements Fu { }
Fu f = new Zi();
- 多态的前提:
有继承或者实现关系;有方法重写;有父(类/接口)引用指向(子/实现)类对象。
- 接口的实现类:
要么重写接口中的所有抽象方法;
要么是抽象类。
1.3接口的成员特点
先到程序中演示然后再小结:
//1.看看接口类的所有成员
public interface Inter {
//2/成员方法
// private String name;//报错:此处不允许private修饰
// public String name;//报错:变量“name”可能没有被初始化
// protected int age;//报错:此处不允许使用“protected”修饰符
// public int height = 30;//这样是可以的,说明它可以是变量
// public final int number = 20;//这样也可以,说明它也可以是一个常量
// String name = "你好";//初始化过没有被protected/private修饰过的变量或者常量可以使用
//3.给出一个接口的实现类看看
//12.注释掉上面成员常量改写默认格式:
// public static final int height = 30;
// public static final int number = 20;
// public static final String name = "你好";
/*13.所以以后直接可以省略 public static final,因为它是默认格式:
直接写作 int height = 30;它等价于:public static final int height = 30;
*/
//14.注释掉上面的默认格式的成员常量改写:
int height = 30;
int number = 20;
String name = "你好";
//15.接着来写构造方法方法
// public Inter(){}//报错:这是个抽象方法,但是我们这样写不就是构造方法嘛?
/*16.由此可见接口里面不能有构造方法的
因为接口主要是对行为进行抽象,所以它是没有具体存在的。
*/
//22.成员方法:
// public void show(){}//报错:说接口里面应该是抽象方法不能有方法体的
//23.也说明接口类里面不能有非抽象类方法的
public abstract void method();//然后在实现类重写method方法
//25.直接这样写方法也可以,写完要去实现类里面重写方法:
void show();//这样也说明他是抽象方法,可以省去public abstract,因为它有默认的修饰
}
/*4.InterImpl实现Inter接口
因为这个接口没有任何抽象方法
所以这个这个接口实现类不需要重写任何抽象的方法
*/
/*19
这种写法的定义类,我们把它给注释掉并改写
*/
//public class InterImpl implements Inter{
/*20.它和这种写法是等价的,虽然之前的定义类,
没有显示继承Object,但是它默认的有这个东西
*/
class InterImpl extends Object implements Inter{
/*17.这时就有一个问题了:
这是一个构造方法啊,在这个构造方法里面的
第一句有一个super啊,他要去调父类的构造方法啊,
那么父类接口中没有构造方法,super调的是哪里的?
*/
public InterImpl() {
//21.所以这里面调用的是Object类里面的构造方法
super();
}
/*18.打开帮助文档查询Object,这个类
类Object是类层次结构的根。每个类都有Object作为超类。
所有对象(包括数组)都实现此类的方法。
所以说每个类都直接或者简介的继承自Object。就是说
如果一个类没有父类那么Object就是它的父类,如果说一个
类有父类,它就是间接的继承着Object。Object的构造方法
只有一个无参构造所以我们说所有的构造方法默认的访问父类的
都是无参构造,因为它们的"祖宗Object"只有无参构造方法
*/
//24.重写接口类的抽象方法
@Override
public void method() {
System.out.println("method");
}
//26.重写show方法
@Override
public void show() {
System.out.println("show");
}
}
/*
接口测试类
*/
class InterfaceDemo {
public static void main(String[] args) {
//5.在测试类中创建接口多态方式的对象
Inter i = new InterImpl();
//6.通过对象i输出接口类的成员变量
//7.因为这三个变量是用public和默认修饰符修饰的所以可以直接输出
System.out.println(i.number + i.name + i.height);//20你好30
//8.通过对象i修改Inter接口类的成员变量的值
// i.number = 40;//报错:因为它被final修饰了所以不能给最终变量“number”赋值
// i.height = 168;//报错:不能给最终变量“number”赋值
/*9.height没有被final修饰为什么还是报错不能给最终变量height赋值呢?
由此可见接口中的成员变量默认被final修饰,所以接口里面没有成员变量,
我们要把它看成常量,因为它默认被final修饰
*/
//10.可以通过Inter这个类名直接访问常量name所以name是默认被静态修饰的
System.out.println(Inter.name);//你好
//11.所以接口中的常量它默认是常量,并且默认是被静态修饰的。
//27.调用方法
i.method();//method
i.show();//show
}
}
接口的成员特点小结:
- 接口的成员变量:
只能是常量;
默认修饰符:public static final
- 接口的构造方法:
接口没有构造方法,因为接口主要是对行为进行抽象的,是没有具体存在;
一个类如果没有父类,默认继承子Object类。
- 接口的成员方法:
只能是抽象方法
默认修饰符:public abstract
关于接口中的方法,JDK8和JDK9中有一些新特性,后面再学。
1.4类和接口的关系
①类和接口的关系
继承关系,只能单继承,但是可以多层继承
②类和接口的关系
实现关系,可以但实现,也可以多实现,还可以继承在一个类的同时实现多个接口
③接口和接口的关系
继承关系,可以单继承,也可以多继承
(所以说Java也是有多继承的,只不过多继承是体现在接口上的)
代码演示:
/*
3.接口和接口是继承关系我们直接写extends
然后来个逗号,再继承一个接口,让它变成多继承也没有问题
*/
public interface Inter1 extends Inter2,Inter3{
//4.所以说接口和接口是继承关系,并且是可以多继承的
}
interface Inter2 {
}
interface Inter3 {
}
class IInterImpl extends Object implements Inter1,Inter2,Inter3{
/*2.一个类可以继承一个类的时候,还可以实现多个接口,
这就是我们说的类和接口是实现关系,可以单实现也可以多实现。
还可以在继承一个类的时候,实现多个接口。
*/
}
1.5抽象类和接口的区别
①成员区别:
抽象类: 变量,常量;有构造方法;有抽象方法,也有非抽象方法。
接口: 常量;抽象方法。
②关系区别:
类与类: 继承关系继承,且只有单继承。
类与接口: 实现关系,可以单实现,也可以多实现。
接口与接口:继承关系,可以单继承,也可以多继承。
③设计理念区别:
抽象类: 对类抽象,包括属性、行为。
接口: 对行为抽象,主要是行为。
举例说明③的区别:
以门和警报作为例子
门:都有open()和close()两个动作,这时候,我们可以分别使用抽象类和接口来定义这个抽象概念。
抽象类:
public abstract class Door {
public abstract void open();
public abstract void close();
}
接口:
public interface Door {
void open();
void close();
}
在类和接口里面分别定义两个抽象方法,那么将来这个具体的门它继承抽象类也许,或者实现接口也可以的。随着时代的发展,门具备了报警的功能,那么又该如何实现呢?
现在给出两种思路:
- 将三种功能都放在抽象类里面。但是这样一来,所有继承这个抽象类的子类都具备了报警功能,但是它有的门,它可能不具备报警功能,所以这种设计不好。
- 将这三种功能放在接口里,需要用到报警功能的类,它就实现接口中的方法,但是这样open();和close();功能也必须去实现,也许这个门连这两个功能都无法实现,比如火灾报警器,他就不具备开关门的功能,那么由此可见这两种设计都不好。
那么应该怎样来设计呢?
答:open();close();它是属于门该有的动作而alarm();报警它是额外的附加的行为,所以最好的解决方案就是将报警功能单独设计一个接口,把open和close放到一个抽象类里面,将来报警门直接继承抽象类实现报警接口就可以了。
代码这样实现就可以了:
来一个报警接口,来一个抽象的门类,然报警的门类继承抽象类,实现报警接口就可以了,他是独立开来的。
强调:抽象类是对事物的抽象,而接口是对行为的抽象