慎入!不然你会爱上“Java接口”

请不要喷我是标题党,毕竟你点进来了,也就说明你确实相信你会爱上它,事实上,你会的!!!

一、认识接口

 接口(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去实现了(implementsRunAble这个具备跑的能力的接口的时候,那么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();

不同的引用所看到的对象的范围不同,只能调用自身类型
Alt

不同引用与对象可见方法的关系

七、常见关系

常见关系
类与类:单继承
类与接口:多实现
接口与接口:多继承

多继承

 如接口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() {}
}

  1. 隐式的意思是,即使用户在使用的时候不写public甚至不写public static final,这里值还是默认为是public static final,而在抽象类或普通类则不能这样,只能默认访问权限为包内访问; ↩︎

  2. 默认public的原因:因为接口既然是一种能力,对于某种能力来说,不能为某个类所私有(如:我们不能说某个人私有某种能力,其他人肯定也会有这种能力),因此能力默认是公开的,谁有资格谁就去实现。 ↩︎

发布了72 篇原创文章 · 获赞 105 · 访问量 8万+

猜你喜欢

转载自blog.csdn.net/qq_44717317/article/details/104496345
今日推荐