接口(多实现、多继承)

1、接口

1.1 概述

  • 概述:
    • 从广义上讲: 接口就是对外提供的规则 (扩展功能,比如USB接口)
    • 从狭义上:在Java里面指的是用interface修饰的东西

  • 接口,是Java语言中另一种引用数据类型
    • 方法的集合 ,如果说类的内部封装了成员变量、构造方法和成员方法,那么接口的内部主要就是封装了常量和方法
    • 其中方法包含抽象方法 (JDK 7及以前),默认方法静态方法 (JDK 8),私有方法 (JDK 9)

  • 接口的定义,它与定义类方式相似,但是使用 interface 关键字
    • 它也会被编译成.class文件,但一定要明确它并不是类
    • 接口不是类,凡是类都有构造方法,接口没有构造方法,而是一种引用数据类型

  • 接口的使用,几乎跟抽象类的用法一致
    • 它也不能创建对象 ,但是可以被实现implements ,类似于继承,理解继承是亲生的,实现是干的关系)
    • 一个实现接口的类(可以看做是接口的干儿子类),需要实现接口中所有的抽象方法,创建该干儿子类(实现类)对象,就可以调用方法了,否则它必须是一个抽象类

1.2 定义格式

public interface 接口名称 {//跟以前类的写法差不多一致,把class换成interface即可
    // 抽象方法1.7之前,方法怎么写都是拿main方法过来修改,m,去掉static
    // 默认方法1.8以后
    // 静态方法1.8以后
    // 私有方法1.9以后
}

1.2.1 含有抽象方法

  • 跟抽象类里面的抽象方法用法一致,JDK1.7以前

  • 抽象方法:使用abstract 关键字修饰,可以省略,没有方法体,该方法供子类实现使用

public interface InterFaceName {
    public abstract void method();		//抽象方法存在的意义,让子类强制去重写从而实现的事情
    void method();		//这种写法跟上面写法一样,public abstract不写,系统给我写,接口独有的
}

1.2.2 含有默认方法和静态方法

  • JDK1.8含以后才有

  • 默认方法:使用 default 修饰,不可省略,供子类调用或者子类重写

  • 静态方法:使用 static 修饰,供接口名.来直接调用,注意这里不可以给子类调用!!!

public interface InterFaceName {
    public default void method() {		//default默认,以前类的普通方法加上default
        // 执行语句
    }
    
    public static void method2() {		//跟类的静态方法以前的写法是一样的,接口跟类有点不同,子类不能用
        // 执行语句    
    }
}

1.2.3 含有私有方法和私有静态方法

  • JDK1.9出现,为上面的默认方法和静态方法服务的

  • 私有方法:使用 private 修饰,供接口中的默认方法或者静态方法调用

public interface InterFaceName {
    private void method() {		//私有方法,非静态
        // 执行语句
    }
    
    private static void method2() {		//私有方法,静态
        // 执行语句
    }
}

1.3 接口的实现

1.3.1 实现的概述

  • 类与接口的关系为实现关系,即类实现接口,该类可以称为接口的实现类,也可以称为接口的子类

  • 实现的动作类似继承,格式相仿,只是关键字不同,实现使用 implements关键字。

  • 非抽象子类实现接口:

  1. 必须重写接口中所有的抽象方法
  2. 继承了接口的默认方法,可以直接调用,也可以重写
  • 实现格式:
class 类名 implements 接口名 {
    // 重写接口中抽象方法【必须】
  	// 重写接口中默认方法【可选】
}

1.3.2 抽象方法的使用(基本的抽象方法会用就可以了,其他方法目前还是很少用的)

定义接口:

public interface LiveAble {//活着接口
    // 定义抽象方法
    public abstract void eat();
    public abstract void sleep();
}

定义实现类:

public class Animal implements LiveAble {
    @Override //alt enter
    public void eat() {
        System.out.println("吃东西");
    }

    @Override
    public void sleep() {
        System.out.println("晚上睡");
    }
}

定义测试类:

public class InterfaceDemo {
    public static void main(String[] args) {
        // 创建子类对象  
        Animal a = new Animal();
        // 调用实现后的方法
        a.eat();
        a.sleep();
    }
}
输出结果:
吃东西
晚上睡

1.3.3 默认方法的使用

  • 可以继承,可以重写,二选一,但是只能通过实现类的对象来调用
  1. 继承默认方法,代码如下:

定义接口:

public interface LiveAble {    
    public default void fly(){        
        System.out.println("天上飞");    
    }
}

定义实现类:

public class Animal implements LiveAble {	
    // 继承,什么都不用写,直接调用
}

定义测试类:

public class InterfaceDemo {    
    public static void main(String[] args) {        
        // 创建子类对象          
        Animal a = new Animal();        
        // 调用默认方法        
        a.fly();    
    }
}
输出结果:天上飞
  1. 重写默认方法,代码如下:

定义接口:

public interface LiveAble {    
    public default void fly(){        
        System.out.println("天上飞");    
    }
}

定义实现类:

public class Animal implements LiveAble {    
    @Override    
    public void fly() {        
        System.out.println("自由自在的飞");    
    }
}

定义测试类:

public class InterfaceDemo {    
    public static void main(String[] args) {        
        // 创建子类对象         
        Animal a = new Animal();        
        // 调用重写方法        
        a.fly();    
    }
}
输出结果:自由自在的飞

1.3.4 静态方法的使用

  • 静态与.class 文件相关,只能使用接口名调用,不可以通过实现类的类名或者实现类的对象调用
  • 接口静态方法子类无法继承,更加无法重写 代码如下:

定义接口:

public interface LiveAble {    
    public static void run(){
        //接口的静态方法,子类无法继承,更加无法重写        
        System.out.println("跑起来~~~");    
    }
}

定义实现类:

public class Animal implements LiveAble {	
    // 无法重写静态方法
}

定义测试类:

public class InterfaceDemo {    
    public static void main(String[] args) {        
        // Animal.run(); // 【错误】无法继承静态方法,不能这样调用,要通过下面的接口名.来调用        
        LiveAble.run(); //     
    }
}
输出结果:跑起来~~~

1.3.5 私有方法的使用

  • 私有方法:只有默认方法可以调用

  • 私有静态方法:默认方法和静态方法都可以调用

    如果一个接口中有多个默认方法,并且方法中有重复的内容,那么可以抽取出来,封装到私有方法中,供默认方法去调用。从设计的角度讲,私有的方法是对默认方法和静态方法的辅助

定义接口:

public interface LiveAble {    
    default void func(){       
        func1();        
        func2();    
    }    
    private void func1(){        
        System.out.println("跑起来~~~");    
    }    
    private void func2(){        
        System.out.println("跑起来33~~~");    
    }
}

上面抽象方法1.7,默认方法和静态方法1.8,私有方法1.9总的使用代码如下:

public class Test02 {
    public static void main(String[] args) {
        //Jiekou j = new Jiekou();//接口不能创建对象,所有要有干儿子类,实现类
//        Jiekou.method3();//接口静态方法,接口名.调用,子类不能使用

        Son s = new Son();
        s.method();
        s.method2();
    }
}

class Son implements Jiekou {//实现继承,干,亲生
    //alt enter

    @Override
    public void method() {
        System.out.println("sonmethod");
    }

}

interface Jiekou {//default接口才有,类没有
    //抽象方法,1.7和以前
    // public void method(){};普通方法,修修改改
    public abstract void method();//强制要求子类重写

    //默认方法和静态方法,1.8
    public default void method2(){//子类可以继承(实现),也可以重写,可选的,对象的,后有,后有的可以先有的
        method4();
        method4();
        method5();
    }

    public static void method3(){//子类不能使用,不能继承也不能重写,子类不能使用,给接口服务,接口名.使用,类,
        System.out.println("staticmethod3");
        //method4();//报错
        method5();
    }

    //私有方法,给上面默认方法和静态方法服务的,跟子类无关
    private void method4(){//私有非静态
        System.out.println("defaultmethod2");//100
    }

    private static void method5(){//私有静态,类,接口,类似,先有类,
        System.out.println("staticdefaultmethod2");//100
    }
}

1.4 接口的多实现

  • 类与接口是实现关系,实现是干的关系,接口是干爹,干爹可以有多个,即类可以实现多个接口,多认多个干爹而已

  • 在继承体系中,一个类只能继承(亲生血缘关系)一个父类(亲爹)

  • 而对于接口而言,一个类是可以实现多个接口的,这叫做接口的多实现。并且,一个类能继承一个父类,同时实现多个接口

实现格式:

class 类名 [extends 父类名] implements 接口名1,接口名2,接口名3... {   
    // 重写接口中抽象方法【必须】  	
    // 重写接口中默认方法【不重名时可选】
} 

[ ]继承: 表示可选操作

1.4.1 抽象方法

  • 接口中,有多个抽象方法时,实现类必须重写所有抽象方法**。*

  • 如果抽象方法有重名的,只需要重写一次

定义接口A、B:

interface A {    
    public abstract void showA();    
    public abstract void show();
}
interface B {    
    void showB();    
    void show();
}

定义实现类:类C实现接口A和B,重写了showA()、showB()及A和B中都有的show()方法

public class C implements A,B{    
    @Override    
    public void showA() {        
        System.out.println("showA");    
    }    
    @Override   
    public void showB() {        
        System.out.println("showB");    
    }   
    @Override    
    public void show() {       
        System.out.println("show");   
    }
}

1.4.2 默认方法

  • 接口中,有多个默认方法时,实现类都可继承使用(可继承可不继承使用)
  • 如果默认方法有重名的,必须重写一次

定义多个接口:

interface A {    
    public default void methodA(){}    
    public default void method(){}
}
interface B {    
    public default void methodB(){}    
    ublic default void method(){}
}

定义实现类:

public class C implements A,B{    
    @Override    
    public void method() {    
        System.out.println("method"); 
    }
}

1.4.3 静态方法

接口中,存在同名的静态方法并不会冲突,原因是只能通过各自接口名访问静态方法

1.4.5 优先级的问题(类继承>实现接口,亲爹>干爹)

  • 当一个类,既继承一个父类,又实现若干个接口时,父类中的成员方法与接口中的默认方法重名,子类就近选择执行父类的成员方法

定义接口:

interface A {    
    public default void methodA(){        
        System.out.println("AAAAAAAAAAAA");   
    }
}

定义父类:

class D {    
    public void methodA(){  
        System.out.println("DDDDDDDDDDDD");  
    }
}

定义子类:

class C extends D implements A {  	
    // 未重写methodA方法
}

定义测试类:

public class Test {  
    public static void main(String[] args) {     
        C c = new C();      
        c.methodA();    
    }
}
输出结果:DDDDDDDDDDDD

1.5 接口的多继承【了解】

  • 接口的出现打破了类单继承的局限性

  • 一个接口能继承另一个或者多个接口,这和类之间的继承比较相似

  • 接口的继承使用 extends 关键字,子接口继承父接口的方法。**如果父接口中的默认方法有重名的,那么子接口需要重写一次。**代码如下:

定义父接口:类与类是同类血缘关系继承,类与接口不是同类,没有血缘关系干实现,接口与接口是同类,血缘关系继承

interface A {   
    public default void method(){  
        System.out.println("AAAAAAAAAAAAAAAAAAA"); 
    }
}
interface B {   
    public default void method(){ 
        System.out.println("BBBBBBBBBBBBBBBBBBB");  
    }
}

定义子接口:

interface D extends A,B{
    //alt enter,重写实现,快捷键
    @Override   
    public default void method() {
        System.out.println("DDDDDDDDDDDDDD");  
    }
}

小贴士:

子接口重写默认方法时,default关键字可以保留。

子类重写默认方法时,default关键字不可以保留。(接口里面才有default方法,类里面没有,只有switch会出现default关键字)

1.6 其他成员特点//选择题可能考

  • 接口中,无法定义成员变量,但是可以定义全局常量,其值不可以改变,默认使用public static final修饰

  • 接口中,没有构造方法,接口不是类,凡是类都有构造方法

  • 接口中,没有静态代码块

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值