侧边栏壁纸
博主头像
青菜-halo2 博主等级

行动起来,活在当下

  • 累计撰写 74 篇文章
  • 累计创建 6 个标签
  • 累计收到 7 条评论

目 录CONTENT

文章目录

15-面向对象进阶_05(接口)

Administrator
2025-11-16 / 0 评论 / 0 点赞 / 12 阅读 / 0 字

五 接口

部分子类共同存在的方法(不是所有子类、不知单独一个子类)

  • 接口:就是一种规则

  • 接口和抽象类的异同:

    接口就是一种规则,是对行为的抽象

5.1 接口的定义、使用

  • 接口用关键字 interface 来定义

public interface 接口名{}
  • 接口不能实例化(不能直接创建对象)

  • 接口和类之间是实现关系,通过 implements 关键字表示

public class 类名 implements 接口名 {}
  • 接口的子类(实现类)

    • 要么重写接口中的所有抽象方法

    • 要么是抽象类

注意:

// 1.接口和类的实现关系,可以单实现,也可以多实现
public class 类名 implements 接口名1, 接口名2{}
​
// 2.实现类还可以在继承一个父类的同时,实现多个接口
public class 类名 extends 父类 implements 接口名1, 接口名2 {}

5.2 基础练习

编写带有接口和抽象类的标准 javabean

青蛙          属性:名字、年龄        行为:吃虫子、蛙泳
狗            属性:名字、年龄       行为:吃骨头、狗刨
兔子          属性:名字、年龄        行为:吃胡萝卜

实现代码:

//Animal.jaav
public abstract class Animal {
    private String name;
    private int age;
​
    public Animal() {}
    public Animal(String name, int age) {
        this.name = name;
        this.age = age;
    }
    public String getName() {return name;}
    public void setName(String name) {this.name = name;}
    public int getAge() {return age;}
    public void setAge(int age) {this.age = age;}
​
    public abstract void eat();
}
​
//Frog.java
public class Frog extends Animal implements Swim{
    public Frog() {}
    public Frog(String name, int age) {super(name, age);}
​
    @Override
    public void eat() {System.out.println("青蛙在吃虫子");}
​
    @Override
    public void swim() {System.out.println("青蛙在蛙泳");}
}
​
//Dog.java
public class Dog extends Animal implements Swim{
    public Dog() {}
    public Dog(String name, int age) {super(name, age);}
​
    @Override
    public void eat() {System.out.println("狗在吃骨头");}
​
    @Override
    public void swim() {System.out.println("狗刨");}
}
​
//Rabbit.java
public class Rabbit extends Animal {
    public Rabbit() {}
    public Rabbit(String name, int age) {super(name, age);}
​
    @Override
    public void eat() {System.out.println("兔子在吃胡萝卜");}
}
​
//Swim.java
public interface Swim {
    public abstract void swim();
}
​
//Test.java
public class Test {
    public static void main(String[] args) {
        //创建青蛙的对象
        Frog f = new Frog("小青蛙", 1);
        System.out.println(f.getName() + ", " + f.getAge());
        f.eat();
        f.swim();
​
        //创建兔子的对象
        Rabbit r = new Rabbit("小白", 2);
        System.out.println(r.getName() + ", " + r.getAge());
        r.eat();
    }
}
​

5.3 接口中成员的特点

5.3.1 成员变量

  • 只能是常量

  • 默认修饰符: public static final

5.3.2 构造方法(没有)

  • 接口中没有构造方法

5.3.3 成员方法

  • 只能是抽象方法

  • 默认修饰符:public abstract

JDK7以前:接口中只能定义抽象方法

JDK8新特性:接口中可以定义有方法体的方法

JDK9新特性:接口中可以定义私有方法

示例代码:

//Inter.java
public interface Inter {
    //public static final int a = 10;
    int a = 10;
​
    //public abstract void method();
    void method();
}
​
//InterImpl.java
public class InterImpl implements Inter{
    @Override
    public void method() {System.out.println("method");}
}
​
//Test.java
public class Test {
    public static void main(String[] args) {
        System.out.println(Inter.a);
        //Inter.a = 20; //Cannot assign a value to final variable 'a'
​
        //创建实现类对象。并调用方法
        InterImpl ii = new InterImpl();
        ii.method();
​
        Scanner sc = new Scanner(System.in);
        sc.next();
    }
}

5.4 接口和类之间的关系

5.4.1 类和类的关系

  • 继承关系

  • 只能单继承,不能多继承

  • 但是可以多层继承

5.4.2 类和接口的关系

  • 实现关系

  • 可以单实现,也可以多实现

  • 还可以在继承一个类的同时实现多个接口

示例1:(一个类中实现多个接口,需要重写接口中所有的方法)

//Inter1.java
public interface Inter1 {
    public abstract void method1();
    public abstract void method2();
    public abstract void method3();
}
​
//Inter2.java
public interface Inter2 {
    public abstract void method4();
    public abstract void method5();
    public abstract void method6();
}
​
//InterImpl.java
public class InterImpl implements Inter1, Inter2{
    @Override
    public void method1() {System.out.println("method1");}
​
    @Override
    public void method2() {System.out.println("method2");}
​
    @Override
    public void method3() {System.out.println("method3");}
​
    @Override
    public void method4() {System.out.println("method4");}
​
    @Override
    public void method5() {System.out.println("method5");}
​
    @Override
    public void method6() {System.out.println("method6");}
}
​
//Test.java
public class Test {
    public static void main(String[] args) {
        InterImpl ii = new InterImpl();
        ii.method1();
        ii.method2();
        ii.method3();
        ii.method4();
        ii.method5();
        ii.method6();
    }
}

示例2:(一个类中实现多个接口,不同接口中有重名方法,重名的方法重写一次即可)

//Inter1.java
public interface Inter1 {
    public abstract void method1();
    public abstract void method2();
    public abstract void method3();
}
​
//Inter2.java
public interface Inter2 {
    public abstract void method1();
    public abstract void method2();
    public abstract void method3();
    public abstract void method4();
}
​
//InterImpl.java
public class InterImpl implements Inter1, Inter2{
​
    @Override
    public void method1() {System.out.println("method1");}
​
    @Override
    public void method2() {System.out.println("method2");}
​
    @Override
    public void method3() {System.out.println("method3");}
​
    @Override
    public void method4() {System.out.println("method4");}
}
​
//Test.java
public class Test {
    public static void main(String[] args) {
        InterImpl ii = new InterImpl();
        ii.method1();
        ii.method2();
        ii.method3();
        ii.method4();
    }
}

5.4.3 接口和接口的关系

  • 继承关系

  • 可以单继承,也可以多继承

注意:如果实现类实现了最下面的子接口,那么就需要重写所有的抽象方法

示例代码:

Inter3 继承于Inter1Inter2 ,实现类(InterImpl) 实现了 Inter3 接口,那么 InterImpl 需要重写所有的抽象方法

//Inter1.java
public interface Inter1 {
    public abstract void method1();
}

//Inter2.java
public interface Inter2 {
    public abstract void mehtod2();
}

//Inter3.java
public interface Inter3 extends Inter1,Inter2{
    public abstract void method3();
}

//InterImpl.java
public class InterImpl implements Inter3{
    @Override
    public void method1() {System.out.println("method1");}

    @Override
    public void mehtod2() {System.out.println("method2");}

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

//Test.java
public class Test {
    public static void main(String[] args) {
        //接口、接口之间是继承关系;可以单继承,也可以多继承
        //细节:如果实现类实现了最下面的子接口,那么就需要重写所偶遇的抽象方法
        InterImpl ii = new InterImpl();
        ii.method1();
        ii.mehtod2();
        ii.method3();
    }
}

5.5 拓展练习

现在有乒乓球运动员、篮球运动员,乒乓球教练、篮球教练
为了出国交流,跟乒乓球相关的人员都需要学习英语
在这个案例中,哪些是具体类,哪些是抽象类,哪些是接口?

乒乓球运动员:姓名、年龄、学打乒乓球、说英语
篮球运动员:姓名、年龄、学打篮球
乒乓球教练:姓名、年龄、教打乒乓球、说英语
篮球教练:姓名、年龄、教打篮球

image-20251113103956905

实现代码:

功能类

//Person.java
//不想让外界直接创建人的对象,直接创建人的对象没有意义,所以将其写为抽象类
public abstract class Person {
    private String name;
    private int age;

    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }
    public Person() {}

    public String getName() {return name;}
    public void setName(String name) {this.name = name;}
    public int getAge() {return age;}
    public void setAge(int age) {this.age = age;}
}

//Sporter.java
public abstract class Sporter extends Person{
    public Sporter(String name, int age) {super(name, age);}
    public Sporter() {}

    public abstract void study();
}

//Coach.java
public abstract class Coach extends Person{
    public Coach(String name, int age) {super(name, age);}

    public Coach() {}

    public abstract void teach();
}

//PingPangSporter.java
public class PingPangSporter extends Sporter implements English{
    public PingPangSporter(String name, int age) {super(name, age);}
    public PingPangSporter() {}

    @Override
    public void speakEnglish() {System.out.println("乒乓球运动员在说英语");}

    @Override
    public void study() {System.out.println("乒乓球运动员在学习打乒乓球");}
}

//PingPangCoach.java
public class PingPangCoach extends Coach implements English{
    public PingPangCoach(String name, int age) {super(name, age);}
    public PingPangCoach() {}

    @Override
    public void teach() {System.out.println("乒乓球教练正在教如何打乒乓球");}

    @Override
    public void speakEnglish() {System.out.println("乒乓球教练正在学习说英语");}
}

//BasketballSporter.java
public class BasketballSporter extends Sporter{
    public BasketballSporter(String name, int age) {super(name, age);}
    public BasketballSporter() {}

    @Override
    public void study() {System.out.println("篮球运动员在学习如何打篮球");}
}

//BasketballCoach.java
public class BasketballCoach extends Coach{
    public BasketballCoach(String name, int age) {super(name, age);}
    public BasketballCoach() {}

    @Override
    public void teach() {System.out.println("狼求教练正在教如何打篮球");}
}

//English.java
public interface English {
    public abstract void speakEnglish();
}

测试类

//Test.java
public class Test {
    public static void main(String[] args) {
        //创建对象
        PingPangSporter pps = new PingPangSporter("张三", 23);
        System.out.println(pps.getName() + ", " + pps.getAge());
        pps.study();
        pps.speakEnglish();

        PingPangCoach ppc = new PingPangCoach("lisi", 24);
        System.out.println(ppc.getName() + ", " + ppc.getAge());
        ppc.teach();
        ppc.speakEnglish();

        BasketballSporter bbs = new BasketballSporter("wangwu", 25);
        System.out.println(bbs.getName() + ", " + bbs.getAge());
        bbs.study();

        BasketballCoach bbc = new BasketballCoach("zhaoliu", 26);
        System.out.println(bbc.getName() + ", " + bbc.getAge());
        bbc.teach();
    }
}

5.6 JDK8开始接口中新增的方法

接口升级时,处理兼容问题(升级后,之前用接口的类不需要重写方法)

JDK7以前:接口中执行能定义抽象方法

JDK8的新特性:接口中可以定义有方法体的方法(默认、静态)

JDK9的新特性:接口中可以定义私有方法

5.6.1 接口中定义默认方法

  • 允许在接口中定义默认方法,需要使用关键字 default 修饰

    作用:解决接口升级的问题

  • 接口中默认的定义格式

//格式
public default 返回值类型 方法名(参数列表){}

//示例
public default void show(){}

  • 接口中默认方法的注意事项:

1、默认方法不是抽象方法,所以不强制被重写。但是如果被重写,重写的时候去掉 default 关键字

示例代码:

//Inter.java
public interface Inter {
    public abstract void method();
    
    //默认方法(show)不是抽象方法,所以不会强制被重写
    public default void show() {
        System.out.println("接口中的默认方法 --- show");
    }
}

//InterImpl.java
public class InterImpl implements Inter{
    @Override //
    public void method() {
        System.out.println("实现类重写的抽象方法 --- method");
    }

    
    //默认不会被强制重写,如果被重写,重写的时候去掉 `default` 关键字
    @Override
    public void show() {
        System.out.println("重写接口中的默认方法 --- show");
    }
}

//Test.java
public class Test {
    public static void main(String[] args) {
        InterImpl ii = new InterImpl();
        ii.method();
        ii.show();
    }
}

2、public 可以省略,default 不能省略

public interface Inter {
    //public可以省略
    public abstract void method();
    
    //default不能省略
    public default void show() {
        System.out.println("接口中的默认方法 --- show");
    }
}

3、如果实现多个接口,多个接口中存在相同名字的默认方法,子类就必须对该方法进行重写

//InterA.java
public interface InterA {
    public default void show() {
        System.out.println("InterA接口中的默认方法 --- show");
    }
}

//InterB.java
public interface InterB {
    public default void show(){
        System.out.println("InterB接口中的默认方法 --- show");
    }
}

//InterImpl.java
public class InterImpl implements InterA,InterB {
    //InterImpl类实现InterA、InterB接口,两个接口中存在相同名字的默认方法(show),则必须要重写show方法
    @Override
    public void show() {
        System.out.println("重写接口中的默认方法 --- show");
    }
}

//Test.java
public class Test {
    public static void main(String[] args) {
        InterImpl ii = new InterImpl();
        ii.show();
    }
}

5.6.2 接口中定义静态方法

  • 允许在接口中定义静态方法,需要用 static 修饰

  • 接口中静态方法的定义格式

//格式
public static 返回值类型 方法名(参数列表){}

//示例
public static void show(){}

注意事项:

1、静态方法只能通过接口名调用,不能通过实现类名或者对象名调用

2、public 可以省略,static 不能省略

//Inter.java
public interface Inter {
    public abstract void method();
    
    // `public` 可以省略,`static` 不能省略
    public static void show(){
        System.out.println("Inter接口中的静态方法");
    }
}

//InterImpl.java
public class InterImpl implements Inter{
    @Override
    public void method() {
        System.out.println("InterImpl重写的抽象方法");
    }

    //不叫重写
    public static void show(){
        System.out.println("InterImpl定义的重名show方法");
    }
}

//Test.java
public class Test {
    public static void main(String[] args) {
        //调用接口中的静态方法
        Inter.show();

        //调用实现类中的静态方法
        InterImpl.show();
    }
}

5.6.3 接口中定义私有方法

  • 接口中私有方法的定义格式

//格式1
private 返回值类型 方法名(参数列表){}
//示例1
private void show(){}

//格式2
private static 返回值类型 方法名(参数列表){}
//示例2
private static void method(){}

示例代码:

package com.yq.a10interfacedemo8;

public interface InterA {
    public default void show1(){
        System.out.println("show1方法开始执行");
        show3();
    }
    
    public default void show2(){
        System.out.println("show2方法开始执行");
        show3();
    }
    
    public static void show5(){
        show4();
    }
    public static void show6(){
        show4();
    }
    
    //普通的私有方法,给默认的方法服务的
    private void show3(){
        System.out.println("记录程序在运行过程中的各种细节,这里有100行代码");
    }
    
    //静态的私有方法,给静态方法服务的
    private static void show4(){
        System.out.println("记录程序在运行过程中的各种细节,这里有100行代码");
    }
}

5.7 接口的应用

1、接口代表规则,是行为的抽象。想要让哪个类拥有一个行为,就让这个类实现对应的接口即可

2、当一个方法的参数是接口时,可以传递接口所有实现类的对象,这种方式称之为接口多态

5.8 适配器设计模式

设计模式:一套被反复使用、多数人知晓、经过分类编目、代码设计经验的总结

解决各种问题的套路

适配器设计模式:解决接口与接口实现类之间的矛盾问题

实现步骤:

1.编写中间类XXXAdapter,实现对接的接口
2.对接口中的抽象方法进行空实现
3.让真正实现类继承中间类,并重写需要用到的方法
4.为了避免其他类创建适配器类(XXXAdapter)的对象,中间的适配器类用abstract进行修饰

注意:若最后的实现类需要继承其他类时,可以让中间类继承父类,再让最后的实现类继承中间类

示例代码:

//Inter.java
public interface Inter {
    public abstract void method1();
    public abstract void method2();
    public abstract void method3();
    public abstract void method4();
    public abstract void method5();
    public abstract void method6();
    public abstract void method7();
    public abstract void method8();
    public abstract void method9();
    public abstract void method10();
}

//InterAdapter.jaa
package com.yq.a11interfacedemo9;

//abstract让InterAdapter变成抽象类(不让外界直接创建对象)
public abstract class InterAdapter implements Inter{
    @Override
    public void method1() {}

    @Override
    public void method2() {}

    @Override
    public void method3() {}

    @Override
    public void method4() {}

    @Override
    public void method5() {}

    @Override
    public void method6() {}

    @Override
    public void method7() {}

    @Override
    public void method8() {}

    @Override
    public void method9() {}

    @Override
    public void method10() {}
}

//InterImpl.java
public class InterImpl extends InterAdapter{
    //需要用到哪个方法,重写哪个方法即可
    @Override
    public void method5() {
        System.out.println("只需要用到第五个方法");
    }
}


0

评论区