Java-接口

目录

1.接口的概念

2.语法规则

3.接口使用

4.接口特性

5.实现多个接口

6.接口间的继承

7.接口使用实例


1.接口的概念

        

         电脑的USB口上,可以插:U盘、鼠标、键盘等所有符合USB协议的设备;数据线的type-c口上,可以插手机,蓝牙耳机充电盒等所有符合规范的设备。由此可以看出:接口就是公共行为的规范表准,在使用时,只要符合规范就可以使用,在Java中,接口可以看成是多个类的公共规范,是一种引用数据类型

2.语法规则

        接口的定义格式与定义类的格式基本相同,将class关键字换成 interface 关键字,就定义了一个接口。

public interface 接口名{

        //抽象方法

        public abstract void method1(); //在接口中public abstract是固定搭配,可以省略不写         public void method2();

        abstract void method3();

        void method4();   //以上几种定义方法的方式都可以

}

        提示:创建接口时,一般以大写字母I开头来命名,命名一般用“形容词”词性的单词,接口中的方法和属性不要加任何修饰符号,保持代码简洁

3.接口使用

        接口不能直接使用,必须要有一个"实现类"来"实现"该接口,实现接口中的所有抽象方法。

public class 类名 implements 接口名{

        //...

}

        注意:子类和父类之间是extends 继承关系,类与接口之间是 implements 实现关系

请实现笔记本电脑使用USB鼠标、USB键盘的例子
1. USB接口:包含打开设备、关闭设备功能
2. 笔记本类:包含开机功能、关机功能、使用USB设备功能
3. 鼠标类:实现USB接口,并具备点击功能
4. 键盘类:实现USB接口,并具备输入功能
 

//USB接口
public interface USB {
    //打开设备
    void openDevicce();
    //关闭设备
    void offDevicce();
}
//鼠标类,实现USB接口
public class Mouse implements USB{
    @Override
    public void openDevicce() {
        System.out.println("连接鼠标设备成功");
    }

    @Override
    public void offDevicce() {
        System.out.println("鼠标设备断开连接");
    }
    //鼠标点击
    public void click(){
        System.out.println("鼠标点击成功~");
    }
}
//键盘类,实现USB接口
public class KeyBoard implements USB{
    @Override
    public void openDevicce() {
        System.out.println("连接键盘设备成功");
    }

    @Override
    public void offDevicce() {
        System.out.println("键盘设备断开连接");
    }
    //输入功能
    public void input(){
        System.out.println("键盘输入");
    }
}
//电脑类,
public class Computer {
    //开机
    public void openComputer(){
        System.out.println("打开电脑");
    }
    //关机
    public void offComputer(){
        System.out.println("关闭电脑");
    }
    //使用USB接口设备
    public void useDevicce(USB usb){
        usb.openDevicce();
        if (usb instanceof Mouse){
            Mouse mouse= (Mouse)usb;
            mouse.click();
        }
        if (usb instanceof KeyBoard){
            KeyBoard keyBoard=(KeyBoard)usb;
            keyBoard.input();
        }
        usb.offDevicce();
    }
}

//测试类

public class Text {
    public static void main(String[] args) {
        //实例化电脑
        Computer computer=new Computer();
        //打开电脑
        computer.openComputer();
        System.out.println("====");
        //使用鼠标设备
        computer.useDevicce(new Mouse());
        System.out.println("====");
        //使用键盘设备
        computer.useDevicce(new KeyBoard());
        //关闭电脑
        computer.offComputer();
    }

}

4.接口特性

        1. 接口类型是一种引用类型,但不能直接new接口的对象

public class TestUSB {
        public static void main(String[] args) {
                USB usb = new USB();
        }
}  //编译报错,USB是抽象类型,无法实例化

        2.接口中每一个方法都是public的抽象方法, 即接口中的方法会被隐式的指定为 public abstract(只能是public abstract,其他修饰符都会报错)。

public interface USB {
        private void openDevice(); // 编译 报错,不允许使用修饰符private
        void closeDevice();
}

        3.接口中的方法是不能在接口中实现的,只能由实现接口的类来实现

public interface USB {
       void openDevice();
         void closeDevice(){
                System.out.println("关闭USB设备");
         }// 编译报错,因为接口中的方法默认为抽象方法,不能带有方法体
}

        4. 重写接口中方法时,不能使用默认的访问权限

public interface USB {

        //打开设备

        void openDevicce();

        //关闭设备

        void offDevicce();

}

public class Mouse implements USB{

        @Override

        void openDevicce() {

        System.out.println("连接鼠标设备成功");

}        //编译报错,重写时不能使用默认修饰符

        5. 接口中可以含有变量,但是接口中的变量会被隐式的指定为 public static final 变量

public interface USB {
     int a=1;//默认被 final public static 修饰
    //打开设备
    void openDevicce();
    //关闭设备
    void offDevicce();
}
public class Text {
    public static void main(String[] args) {
        System.out.println(USB.a); //可以通过接口访问,说明是静态的
        System.out.println(a); //可以直接访问,说明是公开的
        USB a=10; //编译报错,说明a具有final属性
    }
}

        6. 接口中不能有静态、动态代码块和构造方法。

public interface USB {
        public USB(){


        } //编译报错

        {
        } // 编译报错

        static{

        }  //编译报错
        void openDevice();
        void offDevice();
}

        7. 接口虽然不是类,但接口编译完成后字节码文件的后缀格式也是.class
        8. 如果类没有实现接口中的所有抽象方法,则类必须设为抽象类

        9.jdk8中:接口中还可以包含default方法

5.实现多个接口

        在Java中,类和类之间是单继承的,一个类只能有一个父类,即Java中不支持多继承,但是一个类可以实现多个接口。下面通过类来表示一组动物。

//动物类
public class Animals {
    protected String name;
    protected int age;

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

        有的动物会飞,有的动物会跑,有的动物会游泳,还有的动物可能有这三种中的多种,可以设为接口。

//接口,分别表示会飞的、会跑的、会游泳的
interface Flying{
    void fly();
}
interface Running{
    void running();
}

interface Swimming{
    void swimming();
}

        下面创建具体的动物。

        猫,是一种会跑的动物。

//猫类
public class Cats extends Animals implements Running{
    public Cats(String name, int age) {
        super(name, age);
    }

    @Override
    public void running() {
        System.out.println(this.name+"用四只腿跑~");
    }
}

        鱼,是一种会游的动物。

public class Fish extends Animals implements Swimming{
    public Fish(String name, int age) {
        super(name, age);
    }
    @Override
    public void swimming() {
        System.out.println(this.name+"用尾巴游泳");
    }
}

        青蛙,是一种既能跑又能游的两栖动物。

//青蛙类
public class Frog extends Animals implements Running,Swimming{
    public Frog(String name, int age) {
        super(name, age);
    }
    @Override
    public void running() {
        System.out.println(this.name+"可以用两只脚跳");
    }

    @Override
    public void swimming() {
        System.out.println(this.name+"可以用两只脚两只手游");
    }
}

           注意:一个类实现多个接口时,每个接口中的抽象方法都要实现,否则类必须设置为抽象类。(IDEA 中使用 ctrl + i 快速实现接口)

        鸭子,是一种海陆空三栖动物,既可以跑又可以游还能飞。

//鸭子类
public class Duck extends Animals implements Flying,Running,Swimming{
    public Duck(String name, int age) {
        super(name, age);
    }

    @Override
    public void fly() {
        System.out.println(this.name+"可以用两个翅膀飞");
    }

    @Override
    public void running() {
        System.out.println(this.name+"可以两只脚跑");
    }

    @Override
    public void swimming() {
        System.out.println(this.name+"可以用两只脚和两个翅膀游");
    }
}
//测试
public class text {
    public static void main(String[] args) {
        Cats cat=new Cats("小猫",5);
        cat.running();
        System.out.println("====");
        Fish fish=new Fish("小鱼",2);
        fish.swimming();
        System.out.println("====");
        Frog frog=new Frog("小青蛙",3);
        frog.running();
        frog.swimming();
        System.out.println("====");
        Duck duck=new Duck("小鸭子",6);
        duck.fly();
        duck.running();
        duck.swimming();
    }
}

        上面的代码展示了 Java 面向对象编程中最常见的用法: 一个类继承一个父类, 同时实现多种接口。继承表达的含义是 is - a 语义, 而接口表达的含义是 具有 xxx 特性。如上述的猫,是一种动物,具有跑的特性;鱼,是一种动物,具有在水中游的特性等等。

6.接口间的继承

        在Java中,类和类之间是单继承的,一个类可以实现多个接口,接口与接口之间可以多继承。即:用接口可以达到多继承的目的。接口可以继承一个接口, 达到复用的效果. 使用 extends 关键字。
        例如

//接口,表示跑
interface Running{
    void run();
}
//接口,表示游
interface Swimming{
    void swimming();
}
//接口,表示两栖动物(既能跑又能游),这里extends表示拓展
interface Amphibious extends Running,Swimming{

}
//青蛙类
class Frog  implements Amphibious{
   //...
}​​​​​

        此时实现接口创建的 Frog 类, 就继续要实现 run 方法, 也需要实现 swim 方法。接口间的继承相当于把多个接口合并在一起

7.接口使用实例

        给对象数组排序

public class Students {
        private String name;
        private int age;

        public Students(String name, int age) {
            this.name = name;
            this.age = age;
        }
        @Override
        public String toString() {
            return "Students{" +
                    "name='" + name + '\'' +
                    ", age=" + age +
                    '}';
        }

}

        定义一个学生数组对象并对数组中的元素进行排序

Students[] students=new Students[3];
students[0]=new Students("zhangsan",15);
students[1]=new Students("lisi",10);
students[2]=new Students("wangwu",30);

        ,之前我们学过,数组自带有排序方法,是否可以直接使用这个方法呢?

Arrays.sort(students);
System.out.println(Arrays.toString(students));

         我们会发现,编译通过,但运行报错。仔细一想,之前数组中每一个元素是整数,可以直接比较大小,而在这里,数组中的元素为一个个的学生,而两个学生的大小关系无法确定,需要我们额外指定比较方式。

        让我们的 Students 类实现 Comparable 接口, 并实现其中的 compareTo 方法

public class Students implements Comparable(也可以写成Comparable<T>,T表示要比较的数据类型) {              //表示当前的类是可以比较的
        private String name;
        private int age;
        public Students(String name, int age) {
            this.name = name;
            this.age = age;
        }
        @Override
        public String toString() {
            return  "{"+
                    "name=" + name +
                    ", age=" + age+
                    "}";
        }
        //重写字符串比较函数
        @Override              //Object类型的变量o
        public int compareTo(Object o) {
                Students s=(Students)o;//强制类型转换
                /*if(this.age>s.age){
                    return 1;
                } else if (this.age<s.age) {
                    return -1;
                }else {
                    return 0;
                }*/
                return this.age-s.age;
        }
}

        在 sort 方法中会自动调用 compareTo 方法. compareTo 的参数是 Object , 其实传入的就是 Student 类型的对象 。然后比较当前对象和参数对象的大小关系(按年龄计算):如果当前对象应排在参数对象之前, 返回小于 0 的数字;如果当前对象应排在参数对象之后, 返回大于 0 的数字;如果当前对象和参数对象不分先后, 返回 0;

import java.util.Arrays;
public class Text {
    public static void main(String[] args) {
        Students[] students=new Students[3];
        students[0]=new Students("张三",15);
        students[1]=new Students("李四",10);
        students[2]=new Students("王五",30);
        Arrays.sort(students);
        System.out.println(Arrays.toString(students));
    }
}

         注意:对于 sort 方法来说, 需要传入的数组的每个对象都是 "可比较" 的, 需要具备 compareTo 这样的能力. 通过重写 compareTo 方法的方式, 就可以定义比较规则。这种对类的入侵性比较强,一旦写好规定的比较方式,那么以后只能以这种方式比较。

        第二种方式,构造比较器类

public class Students {
    public String name;
    public int age;

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

    @Override
    public String toString() {
        return "{" +
                "name=" + name +
                ", age=" + age +
                "}";
    }
}
//比较器
class ageComparator implements Comparator<Students> {
    @Override
    public int compare(Students o1,Students o2) {
        return o1.age- o2.age;
    }
}
class nameComparator implements Comparator<Students>{
    @Override
    public int compare(Students o1, Students o2) {
        //String 自己重写compareTo 方法
        return o1.name.compareTo(o2.name);
    }
}
public class Text {
    public static void main(String[] args) {
        Students[] students=new Students[3];
        students[0]=new Students("zhangsan",15);
        students[1]=new Students("lisi",10);
        ageComparator ageComparator1=new ageComparator();
        Arrays.sort(students,ageComparator1);
        System.out.println(Arrays.toString(students));
        System.out.println("=====");
        nameComparator nameComparator1=new nameComparator();
        Arrays.sort(students,nameComparator1);
        System.out.println(Arrays.toString(students));
    }
}

        注意:这种方式做到灵活比较,想用那种方式就调用哪种方式。

 

  • 11
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 18
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值