请不要喷我是标题党,毕竟你点进来了,也就说明你确实相信你会爱上它,事实上,你会的!!!
一、认识接口
接口(interface):在JAVA编程语言中是一个抽象类型,是抽象方法的集合,接口通常以interface来声明。一个类通过继承接口的方式,从而来继承接口的抽象方法。
接口的其他维度:jdbc,serverlt jsp,mybatis,spring
二、接口与类的异同
接口与抽象类
接口相当于特殊的抽象类,定义方式、组成比分与抽象类类似。
1.抽象类:
- 对象不能独立存在,虽然抽象类有构造方法,但是不能单独使用,即不能new对象
- 可以定义抽象方法,子类必须被覆盖;
2.接口:
interface MyInterface{
//公开静态常量
public static final String FIELD = "value";
//公开抽象方法
public abstract void mythod();
}
- 接口使用interface关键字定义接口;
- 只能定义 公开静态常量、公开抽象方法;当然抽象类也是可以的,但是在接口中定义的常量必须为公开静态常量(隐式用
public static final
修饰)1 ,定义的方法必须是公开抽象的方法(隐式用public abstract
修饰);
- 接口不是类,没有构造方法,因此,接口不能new对象;
- 没有动态代码块、静态代码块
三、接口的应用
微观概念
接口的微观概念:接口是一种能力和约定。而方法的定义代表了能力的具体要求。
举一个简单的例子:狗、鸟、鱼都有 睡觉 吃食物 两种能力,而各自也独有一些能力(如:狗和鱼可以游泳,鸟可以飞等),相同点在于他们都是动物,而动物是抽象的(没有说哪种动物叫Animal????),不能被实例化;具体代码如下:
1.使用抽象类
abstract class Animal{
String breed;
Integer age;
String sex;
//抽象方法:规定子类必须存在的行为、规范了该行为的具体要求(参数,返回值等),
public abstract void eat();
public abstract void sleep();
}
class Dog extends Animal{
//覆盖父类方法
public void eat() {}
public void sleep() {}
//独有方法
public void run(){}
public void swim(){}
}
class Bird extends Animal{
//覆盖父类方法
public void eat() {}
public void sleep() {}
//独有方法
public void run(){}
public void fly(){}
}
class Fish extends Animal{
//覆盖父类方法
public void eat() {}
public void sleep() {}
//独有方法
public void swim(){}
}
- 在父类里面定义抽象方法的作用:抽象类必须被子类覆盖,这样就规定子类必须存在的行为、规范了该行为的具体要求(参数,返回值等),即所有的子类必须会 睡觉 吃饭;
- 父类中未定义的方法,即子类独有的方法,是不受控制的;即可以有可以没有,不受父类限制;
2.使用接口
在使用抽象类的时候,对于子类独有的方法,一方面它是不受父类控制的(可以任意定义自己的参数和返回类型),另一方面部分子类的独有方法是有重合部分的(如 狗和鱼都会游泳,鸟和狗都会跑);那么不能给子类的独有方法做单独的限制和约定呢?就引入了接口…
既然接口的作用是一种能力和约定,那么对于Dog
来说它的能力就是跑,如何使用接口去定义呢?
class Dog extends Animal implements RunAble{ //实现
//覆盖父类方法
public void eat() {}
public void sleep() {}
//实现接口里的方法
public void run(){}
//独有方法
public void swim(){}
}
//能力:会跑
interface RunAble{
//约定:无参无返回
public abstract void run();
}
- 接口
RunAble
是一种跑的能力,对于这个能力的约定是:无参无返回的,当Dog
去实现了(implements
)RunAble
这个具备跑的能力的接口的时候,那么Dog
就有了跑的能力;当Dog
拥有了run
的能力的时候,必须覆盖接口里的抽象方法; - 总结上一点:实现了某个接口,其实就是为某个类型增加了一种能力和约定;
如果有多种特有的能力呢?技多不压身嘛,implements
后面的接口用,
隔开就可以啦,整体下来,代码可以修改为:
class Dog extends Animal implements RunAble,SwimAble{ //实现
//覆盖父类方法
public void eat() {}
public void sleep() {}
//实现接口的能力和其约定的方法
public void run(){}
public void swim(){}
}
class Bird extends Animal implements RunAble,FlyAble{
//覆盖父类方法
public void eat() {}
public void sleep() {}
//实现接口的能力和其约定的方法
public void run(){}
public void fly(){}
}
class Fish extends Animal implements SwimAble{
//覆盖父类方法
public void eat() {}
public void sleep() {}
//实现接口的能力和其约定的方法
public void swim(){}
}
//接口是一种能力,接口是一种约定
//能力:会跑
interface RunAble{
//约定:无参无返回
public abstract void run();
}
//能力:会游泳
interface SwimAble{
//约定:无参无返回
public abstract void swim();
}
//能力:会飞
interface FlyAble{
//约定:无参无返回
public abstract void fly();
}
- 父类给出的抽象方法是所有子类的共性,而实现接口的过程,则是类需要拥有的能力,这种能力是超出父类限制的,但在接口里对这种能力有明确的约定(规定参数类型和返回值等),如果某个类需要拥有这个能力,就必须满足接口的约定(覆盖接口里的抽象方法)!
总结:
Java为单继承,当父类的方法种类无法满足子类需求时,可实现接口扩充子类的能力;
接口支持多实现,可为类扩充多种能力(用,
隔开即可)
四、接口的规范
“接口的规范”在前文中也已经提及,这里做具体的整理:
- 任何类在实现接口时,必须实现接口中所有的抽象方法,否则此类为抽象类。
- 实现接口中的抽象方法时,访问修饰符必须为public2
- 接口中的方法是不能在接口中实现的,只能由实现接口的类来实现接口中的方法
五、接口引用
实现接口和继承父类都可以在主函数里面通过实例化来引用,但是实例化的意义和方式是不一样的,还是以上文的代码为例:
public class TestAble {
public static void main(String[] args){
//狗是一种动物(侧重讲狗是一种动物)
Animal animal = new Dog();//父类引用指向子类对象;(多态)
//可以调用父类的公共方法
animal.eat();
animal.sleep();
//接口引用关注的是行为!!!
//狗是一种会跑的东西(侧重讲狗是会跑的)
RunAble runAble = new Dog();//接口引用指向实现类对象;(多态)
//只能调用接口里的方法,无法调用父类对象
runAble.run();
}
}
abstract class Animal{
//抽象方法:规定子类必须存在的行为、规范了该行为的具体要求(参数,返回值等),
public abstract void eat();
public abstract void sleep();
}
class Dog extends Animal implements RunAble{ //实现
//覆盖父类方法
public void eat() {}
public void sleep() {}
//实现接口的能力和其约定的方法
public void run(){}
public void swim(){}
}
//能力:会跑
interface RunAble{
//约定:无参无返回
public abstract void run();
}
父类引用:
父类引用(Animal animal = new Dog();
):父类引用指向子类对象(多态);此时关注的是接口的类型;可以调用父类中定义的共有方法;
通俗的说:父类引用,就是把狗当成动物看,此时侧重的讲狗是一种动物,狗既然是一种动物,它就应该有动物该有的属性:吃、睡
接口引用
接口引用(RunAble runAble = new Dog();
):接口引用指向实现类对象(多态);此时关注的是接口的能力(行为),而不是对象的类型;因此只能调用接口里的方法,无法调用父类对象;
通俗的说:接口引用,就是把狗看成是一种会跑的东西,此时侧重的讲狗是一种会跑的东西,侧重的是行为!!!只能调用接口里的方法,无法调用父类对象
六、接口的多态
上文已经涉及多态的概念,在这里单独做整理:
举例代码:
public class TestAble {
public static void main(String[] args){
Dog dog = new Dog();
Animal animal = new Dog();
RunAble runAble = new Dog();
SwimAble swimAble = new Dog();
}
}
//父类
abstract class Animal{
public void eat(){}
public void sleep(){}
}
//接口
interface RunAble{
public abstract void run();
}
//接口
interface SwimAble{
public abstract void swim();
}
//子类
class Dog extends Animal implements RunAble,SwimAble{ //实现
public void run(){} //接口方法
public void swim(){}//接口方法
public void shout(){}//独有方法
}
在主函数类里涉及了不同类型的引用指向一个对象,表示看待对象的视角不同,这就是多态!
Dog dog = new Dog();
Animal animal = new Dog();
RunAble runAble = new Dog();
SwimAble swimAble = new Dog();
不同的引用所看到的对象的范围不同,只能调用自身类型
七、常见关系
多继承
如接口C多继承了A,B,当用户调用C中的c方法的实现的时候,就必须实现a,b
interface A{
void a();
}
interface B{
void b();
}
interface C extends A,B{
void c();
}
class Word implements A,B,C{
public void c() {}
public void a() {}
public void b() {}
}