接口和抽象类很像,接口是把行为给抽象化,可以理解成一个抽象类抽象到极致的情况下,形成的类,也就是一个抽象类有且只有抽象方法的时候,就可以用接口来写。
一、抽象类与接口在书写上的异同
这是一个抽象类
public abstract class Animal {
public abstract void sleep();
public abstract void eat();
}
这是一个接口
public interface Animal {
void sleep();
void eat();
}
从书写代码量来看,接口的书写比抽象类要简单的多
抽象类中的“abstract class”变成了“interface”,方法中的“public abstruct”均可省略
二、接口的定义
接口定义使用interface关键字
public interface Run{ void run(); }
从用的角度来理解接口是怎么由抽象类一步一步演变来的?
就是一个没有任何属性,全部由抽象方法组成的抽象类
三、接口中的修饰符
1.方法
接口中所有的方法默认都是public abstract 修饰的
2.成员变量
接口中所有的成员变量都由 public static final 修饰,所以记得赋值
理解:接口就是一个行业标准,既然是标准那他就是(共享、开放、不变的,所以它是类(体现出共享)、public(开放)、final(不变)
所谓的行业标准就是在,你想做一件事情不知道该怎么做的时候,去找的一个有指导作用的东西,比如你想开一家茶百道,可是不知道怎么开,这个时候你就选择加盟茶百道,然后按照他的要求去一步一步的达到要求就可以,接口在我们写代码中就是这么一个作用。
四、接口中的构造器,以及多态
1.接口没有构造方法
抽象到极致的抽象类,因为接口没办法new,但是接口可以使用多态(和抽象类类似,让接口引用,指向实现了接口的实体类对象)
因为抽象类可以使用多态,我们创建抽象类目的就是为了让它当父类来使用多态,那您可能就要说了,普通类也可以做父类呀,为什么还要有抽象类?
这是因为普通类无法保证方法的统一性。这句话怎么理解呢?如果普通父类中的方法,子类可以自由选择是否重写,而抽象类中的方法子类必须重写,就满足了使用多态的条件。
接口是抽象到极致的抽象类,所以抽象类可以使用多态,接口也可以
2.小插曲为什么必须重写抽象类的抽象方法?
您可能要说了这是与法规定的,可是我们还是要想一下原因的,这更有助于我们理解和记忆,要我说的话就是,因为子类想当个人,子类想去new对象,类可以看成是一个图纸,按照图纸才能new出对象,可是抽象方法中的抽象方法是不完善的,子类想要去必须把父类的方法完善了,才可以去new出来对象。
public static void main(String[] args) {
Animal animal = new Cat();
}
五、接口定义好之后怎么用?
public interface Run {
void run();
}
public class Dog implements Run{
@Override
public void run() {
System.out.println("我是狗,我会跑");
}
}
实现接口的类必须实现接口中的所有方法;
如果不实现接口中的所有方法,那么这个类也声明为抽象类,如下
public abstract class Person implements Animal{//声明为抽象类,因为未实现sleep方法
@Override
public void eat() {
}
}
六、接口与接口,接口与类之间的关系
1.接口和接口之间可以继承,同时支持多继承(java的类只支持单继承,但是接口支持多继承)
2.接口和类之间是实现关系,并且一个类可以实现多个接口
接口之间的多继承
类若想实现多继承功能
public class Cow extends Animal implements Run,Eat{
@Override
public void jump() {
//TODO Auto-generated method stub
}
@override
public void drunk() {
//TODO Auto-generated method stub
}
}
3.为什么接口可以多继承呢,类不支持多继承?
- java类中如果多继承可能两个父类有相同的方法会冲突,接口中方法都没有方法块,只有方法名
- 具体的实现都由实现接口的类决定 接口里的方法是抽象的,没有具体内容就可以直接去重,但是类就得作取舍
理解:这时候就有要提到《道德经》中的一句话了 “有之以为利,无之以为用”,放到这就是父类里面的方法可能是写好的,非常便利可以直接使用,接口中是除了方法签名什么都没有的,就像一个器皿,里面装什么是自己决定的,告诉你一个方向,怎么发展靠自己。
public interface A extends B,C{
}
4.与继承类似,接口和实现类之间存在多态
5、什么是接口回调
通过下面的代码理解一下:
首先定义一个接口Usb:
- 首先定义一个接口Usb:
public interface Usb {
void service();
}
- 然后我们定一个接口使用者
注意:此时接口没被实现,就已经出现了接口的调用者,这个过程就叫做接口回调
//定义接口的使用者
public class Computer {
//用的过程
Usb usb1;
Usb usb2;
Usb usb3;
public void run()
{
if(usb1 != null){//如果第一个接口插着东西
//这就是接口的使用此时接口的使用这就出现了,可是此时接口还没有被实现
usb1.service();
}
if(usb2 != null){
usb2.service();
}
if(usb2 != null){
usb2.service();
}
}
}
- 下面我们定义接口的实现者
public class Fengshan implements Usb{
@Override
public void service() {
System.out.println("风扇启动了");
}
}
public class Mouse implements Usb{
@Override
public void service() {
System.out.println("鼠标启动了");
}
}
public class Upan implements Usb{
@Override
public void service() {
System.out.println("U盘启动了");
}
}
- 现在测试一下
public class Test {
public static void main(String[] args) {
Computer computer = new Computer();
//在usb1接口上插上鼠标
computer.usb1 = new Mouse();
//在usb2接口上插上风扇
computer.usb2 = new Fengshan();
//在usb3接口上插上U盘
computer.usb3 = new Upan();
computer.run();
}
}
七、接口和抽象类的异同:
- 1、接口中的方法默认是抽象方法,在接口中不能有实现(java8开始允许接口方法有默认实现,使用default关键字);抽象类可以有非抽象方法)
public interface A {
default void have(){
System.out.println("我有A");
}
}
此时Cat不一定非要重写A接口中的hava方法
public class Cat implements Animal,A{
@Override
public void sleep() {
}
@Override
public void eat() {
}
}
- 2、接口中的变量默认是final类型,抽象类中则不一定
- 3、一个类可以实现多个接口,但是最多只能继承一个抽象类
- 4、一个了尅实现接口的话,需要实现接口中的所有方法,而抽象类则不一定
- 5、从设计层来说,抽象对类的抽象,是一种模版设计,而接口是行为的抽象是一种行为的规范