你所要知道的关于接口的知识点

简介: 你所要知道的关于接口的知识点

接口
什么是接口
在Java中,接口可以看成是:多个类的公共规范,接口是一种引用数据类型。

接口的特点
1、使用interface来修饰接口

2、接口的成员变量默认都是public static final修饰的,因为有final,所以要进行初始化赋值

3、接口的成员方法默认都是抽象方法【以后的类要进行重写抽象方法】,由public abstract 修饰

4、接口的普通成员方法一般是不能有具体的实现的,但是在前面加上default就可以加上具体实现【JDK8以后才有的】

5、接口中可以有静态的成员方法,但是不管是default还是静态的方法,都是public的

6、接口也不能进行实例化

7、类与接口之间使用implements关联,接口可以引用具体的实现类,也能实现向上转型

8、接口里面不能有代码块或者构造方法(都不能实例化,要构造方法干什么呢)

9、抽象类实现一个接口,可以在在前面加上abstract,就不用重写接口中的抽象方法,但是下面还是要写别的类,还是要重写抽象方法【重写抽象方法是逃不掉的】

interface IShape{

int COUNT=12;//接口的成员变量默认是public static final修饰的
void func();//接口的成员方法默认是public abstract修饰的
void func1();//接口的成员方法一般不具体实现

default void func2() {  
    System.out.println("haha");
}
static void func3() {
    System.out.println("heihei");
}

}
public class Test {

    //IShape iShape=new IShape();   err,接口也是不能实例化的

}
复制代码
接口的具体应用
interface IShape{ //interface修饰接口

void draw();

}
class Rect implements IShape { //使用implements来连接接口与具体的类,叫做实现

@Override  //对抽象方法重写
public void draw() {   //上面的draw方法是public,所以这里要想访问draw就必须要使用public(大于等于接口的访问修饰限定符)
    System.out.println("矩形");
}

}
class Circle implements IShape {

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

}

public class Test {

public static void drawMap(IShape shape){
    shape.draw();//动态绑定
}
public static void main(String[] args) {
    //IShape iShape=new IShape();//err,接口不能实例化
    IShape rect= new Rect();//向上转型
    drawMap(rect);
    IShape circle = new Circle();
    drawMap(circle);
    //不进行实例化
    /* drawMap(new Rect());
    drawMap(new Circle());*/

}

}
复制代码
多个接口的具体使用
abstract class Animal{

String name;
int age;

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

 public abstract void eat();//吃

}

//如何实现跑的动作?
//首先,不是所有的动物都能跑,所以跑这个动作不能放在Animal里面,其次,要是再写一个跑的类,但是Java是不允许多继承的(一个子类继承两个父类)
//所以为了实现这样的灵活调用,就要用到多个接口
interface IRUNNING{ //跑步的接口

void run();

}
interface IFLYING{ //飞的接口

 void fly();

}

class Dog extends Animal implements IRUNNING { //Dog这个类继承了Animal类并且实现了IRUNNING接口

public Dog(String name, int age) {
    super(name, age);
}

@Override
public void eat() {
    System.out.println(this.name + "正在吃狗粮");
}

@Override
public void run() {
    System.out.println(this.name+"正在四处跑");
}

}

class Bird extends Animal implements IRUNNING,IFLYING{ //Bird类继承了Animal类并且实现了IRUNNING,IFLYING多个接口,而狗就没有飞这个功能/接口,所以使用接口十分灵活

public Bird(String name, int age) {
    super(name, age);
}

@Override
public void eat() {
    System.out.println(this.name+"正在吃鸟粮");
}

@Override
public void run() {
    System.out.println(this.name+"正在用细细的腿跳着跑");
}

@Override
public void fly() {
    System.out.println(this.name+"准备起飞");
}

}

public class test {

public static void Run(IRUNNING irunning) {   //传过来的都已经实现了接口,所以可以成功
    irunning.run();
}
public static void main(String[] args) {
    Run(new Dog("旺财", 2));
    Run(new Bird("小鸟", 3));
}
//以下是多态的使用,可以对比一下
public static void func(Animal animal) {
    animal.eat();
public static void main1(String[] args) {
    func(new Dog("旺财", 2));
    func(new Bird("小鸟", 3));
}
}

}
复制代码
继承是is-a的关系(子类父类包含关系),接口是XXX特性,十分灵活

接口的继承
接口可以继承别的接口,也是使用extends,实现代码的复用

interface IA{

void func1();

}
interface IB{

void func2();

}

//接口的继承---接口功能的拓展
//IC拥有IA和IB的功能
interface IC extends IA, IB{

void func3();

}

class A implements IC{

@Override
public void func1() {

}

@Override
public void func2() {

}

@Override
public void func3() {

}

}
public class test {

}
复制代码
几种常用的接口
1、比较自定义类型的大小 / 排序(Comparable接口)
注意:实现接口后面还要加上<自定义类名>

//比较大小
class Student implements Comparable{ //此时会报错,直接alt+enter,就可以重写compareTo方法

String name;
int age;
double score;

public Student(String name, int age, double score) {
    this.name = name;
    this.age = age;
    this.score = score;
}

@Override
public String toString() {
    return "Student{" +
            "name='" + name + '\'' +
            ", age=" + age +
            ", score=" + score +
            '}';
}

@Override
public int compareTo(Student o) {  //重写compareTo方法
    /*if (this.age > o.age) {
        return 1;
    } else if (this.age == o.age) {
        return 0;
    } else {
        return -1;
    }

*/

    return this.age-o.age;//o就是传的参数,谁调用compareTo谁就是this
    //两种代码效果是一样的,按照年龄比较大小
}

}
public class test {

public static void main(String[] args) {
    Student student1 = new Student("zhangsan", 32, 29.0);
    Student student2 = new Student("lisi", 20, 1.2);
    if (student1.compareTo(student2) > 0) {
        System.out.println("student1>student2");
    }
}

}
复制代码
//排序
import java.util.Arrays;
class Student implements Comparable{

String name;
int age;
double score;

public Student(String name, int age, double score) {
    this.name = name;
    this.age = age;
    this.score = score;
}

@Override
public String toString() {
    return "Student{" +
            "name='" + name + '\'' +
            ", age=" + age +
            ", score=" + score +
            '}';
}

@Override
public int compareTo(Student o) {  //重写
    return this.age-o.age;//o就是传的参数,谁调用compareTo谁就是this
    //要是想要改为降序就调换一下减的顺序
}

}
public class test {

public static void main(String[] args) {
    Student[]  student= new Student[3]; //定义Student类型的数组
    student[0] = new Student("zhangsan", 32, 29.0);
    student[1] = new Student("lisi", 20, 1.2);
    student[2] = new Student("wangwu", 52, 89);
    System.out.println("排序前"+Arrays.toString(student));
    Arrays.sort(student);//要是不写Comparable接口就不知道是按照什么进行排序的
    System.out.println("排序后"+Arrays.toString(student));//升序打印
}

}
复制代码
但是上面使用Comparable接口,就将比较/排序的规则定死了,已经加入到了Student类里面,后期就会不方便改

此时既可以使用Comparator接口

2、Comparator接口(比较器)
import java.util.Comparator;

//比较大小
class Student {

String name;
int age;
double score;

public Student(String name, int age, double score) {
    this.name = name;
    this.age = age;
    this.score = score;
}

@Override
public String toString() {
    return "Student{" +
            "name='" + name + '\'' +
            ", age=" + age +
            ", score=" + score +
            '}';
}

}

class AgeComparator implements Comparator { //定义一个年龄比较器的类

@Override
public int compare(Student o1, Student o2) {
    return o1.age - o2.age;
}

}
class ScoreComparator implements Comparator{ //定义一个分数比较器的类

@Override
public int compare(Student o1, Student o2) {
    return (int )(o1.score - o2.score);
}

}

class NameComparator implements Comparator { //定义一个名字比较器的类

@Override
public int  compare(Student o1, Student o2) {
    return o1.name.compareTo(o2.name);//compareTo的返回值是int
}

}

public class test {

public static void main(String[] args) {
    Student student1 = new Student("zhangsan", 32, 29.0);
    Student student2 = new Student("lisi", 20, 1.2);
    AgeComparator ageComparator = new AgeComparator();//实例化年龄比较器
    int ret=ageComparator.compare(student1, student2);
    System.out.println(ret);  
    
    
    ScoreComparator scoreComparator = new ScoreComparator();//实例化分数比较器
    int ret2 = scoreComparator.compare(student1, student2);
    System.out.println(ret2);
    
     NameComparator nameComparator = new NameComparator();//实例化名字比较器
    int ret3 = nameComparator.compare(student1, student2);
    System.out.println(ret3);
}

//年龄之差12
//分数之差是27
//名字的首字母相差14

复制代码
使用比较器对数组元素进行排序

import java.util.Arrays;
import java.util.Comparator;

class Student {

String name;
int age;
double score;

public Student(String name, int age, double score) {
    this.name = name;
    this.age = age;
    this.score = score;
}

@Override
public String toString() {
    return "Student{" +
            "name='" + name + '\'' +
            ", age=" + age +
            ", score=" + score +
            '}';
}

}

class AgeComparator implements Comparator {

@Override
public int compare(Student o1, Student o2) {
    return o1.age - o2.age;
}

}

class ScoreComparator implements Comparator{

@Override
public int compare(Student o1, Student o2) {
    return (int)(o1.score - o2.score);
}

}

class NameComparator implements Comparator {

@Override
public int  compare(Student o1, Student o2) {
    return o1.name.compareTo(o2.name);//compareTo的返回值是int
}

}

public class test {

public static void main(String[] args) {
    Student[]  student= new Student[3];
    student[0] = new Student("zhangsan", 32, 29.0);
    student[1] = new Student("lisi", 20, 1.2);
    student[2] = new Student("wangwu", 52, 89);
    
    AgeComparator ageComparator = new AgeComparator();//实例化年龄比较器
    Arrays.sort(student, ageComparator);//Arrays.sort是可以重载的(既可以只放一个数组名,还能再放一个比较器对象)
    System.out.println(Arrays.toString(student));
    
    ScoreComparator scoreComparator = new ScoreComparator();
    Arrays.sort(student, scoreComparator);
    System.out.println(Arrays.toString(student));

    NameComparator nameComparator = new NameComparator();
    Arrays.sort(student, nameComparator);
    System.out.println(Arrays.toString(student));

}

//[Student{name='lisi', age=20, score=1.2}, Student{name='zhangsan', age=32, score=29.0}, Student{name='wangwu', age=52, score=89.0}]
//
//[Student{name='lisi', age=20, score=1.2}, Student{name='zhangsan', age=32, score=29.0}, Student{name='wangwu', age=52, score=89.0}]
//
//[Student{name='lisi', age=20, score=1.2}, Student{name='wangwu', age=52, score=89.0}, Student{name='zhangsan', age=32, score=29.0}]
复制代码
使用比较器不会涉及到自定义的类,想要按照什么比较就写一个专门的比较器,实例化 比较器来进行比较,所以写比较器是十分灵活的,十分好用

3、克隆当前对象(Cloneable接口)
class Person implements Cloneable{ //Cloneable里面没有任何东西,是一个空接口/标记接口:说明当前类可以被克隆

public int age;

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

@Override
protected Object clone() throws CloneNotSupportedException {  //正式实现克隆  alt+enter,选中clone即可
    //重写的是Object里面的clone方法(由C/C++写的,所以看不见)
    return super.clone();
}

@Override
public String toString() {
    return "Person{" +
            "age=" + age +
            '}';
}

}
public class Test {

public static void main(String[] args) throws CloneNotSupportedException {
    Person person = new Person(10);
    Person person2= (Person) person.clone();//要将Object类型的强转为Person
    System.out.println(person);
    System.out.println(person2);
}

}

目录
相关文章
|
7月前
|
前端开发 Python
前端知识(十七)——入口函数和特定函数的区别
前端知识(十七)——入口函数和特定函数的区别
69 0
|
5月前
|
存储 Java
软件开发常用之SpringBoot文件上传接口编写(中),一本书,代码大全(里面有很多代码重构的方法),屎山代码的原因是不断追加逻辑,在错误代码上堆积新的功能,在写完逻辑之后去思考一下,逻辑合理不
软件开发常用之SpringBoot文件上传接口编写(中),一本书,代码大全(里面有很多代码重构的方法),屎山代码的原因是不断追加逻辑,在错误代码上堆积新的功能,在写完逻辑之后去思考一下,逻辑合理不
|
7月前
|
C++
C++ 接口的实现,及作用通俗理解方式
C++中的接口,一般就是指抽象类,是一种用来描述类对外提供的操作、方法或功能的集合——注意,一般只是描述(声明),而不对这些方法或功能进行定义实现,通常在
73 2
|
7月前
|
前端开发 JavaScript
怎样使用接口引用数据
怎样使用接口引用数据
|
存储 前端开发 Java
【SpringMVC】看完这篇简单理解并入门SpringMVC:通过入门案例举例子的方式快速理解
【SpringMVC】看完这篇简单理解并入门SpringMVC:通过入门案例举例子的方式快速理解
|
前端开发
前端学习案例1-属性描述符
前端学习案例1-属性描述符
73 0
前端学习案例1-属性描述符
|
前端开发
前端学习案例2-属性描述符
前端学习案例2-属性描述符
55 0
前端学习案例2-属性描述符
|
前端开发
前端学习案例2-属性描述符2
前端学习案例2-属性描述符2
42 0
前端学习案例2-属性描述符2
|
前端开发
前端学习案例1-属性描述符1
前端学习案例1-属性描述符1
61 0
前端学习案例1-属性描述符1
|
前端开发
前端学习案例3-属性描述符3
前端学习案例3-属性描述符3
50 0
前端学习案例3-属性描述符3