接口就是公共的行为规范标准,大家在实现时,只要符合规范标准,就可以通用。在Java中,接口可以看成是:多个类的公共规范,是一种引用数据类型。

1.接口使用关键字interface来修饰。

2.接口当中的成员方法,只能是抽象方法。所有的方法默认都是public abstract。

3.接口当中的方法如果要实现,需要用default来修饰

4.接口当中的成员变量,默认都是public static final

5.接口当中的静态方法,可以有具体的实现

6.接口不能进行实例化。new接口

7.一个普通的类,可以用implements来实现接口

8.接口中不能有静态代码块和构造方法

9.接口虽然不是类,但是接口编译完成后字节码文件的后缀格式也是.class

10. 如果类没有实现接口中的所有的抽象方法,则类必须设置为抽象类

下面用一个简单的代码来介绍一下上方的重点

interface IShape{
    //成员变量

    //成员方法
    void draw();

    default void func1(){
        System.out.println("默认方法");
    }

    public static void staticFunc(){
        System.out.println("静态方法");
    }
}

class A implements IShape {

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

public class TestDemo {
    public static void main(String[] args) {
        IShape a=new A();
        a.draw();
        a.func1();

        IShape.staticFunc();
    }
}

 11.一个类,可以继承抽象类,同时也可以实现多个接口。每个接口之间用逗号隔开。

下面我用一个实例来演示一下。

class Animals{
    public int age;
    public String name;

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

    public void eat() {
        System.out.println(this.name + "在吃饭");
    }
}

interface IRunning{
    void run();
}

interface ISwimming{
    void swim();
}

interface IFlying{
    void fly();
}

class Dog extends Animals implements IRunning,ISwimming{


    public Dog(String name) {
        super(name);
    }

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

    @Override
    public void swim() {
        System.out.println(this.name+"正在游泳");
    }
}

public class TestDemo {
    public static void main(String[] args) {
        Dog dog=new Dog("小狗");
        dog.run();
        dog.swim();
    }
}

这里可以看出,接口的出现解决了多继承的问题。

下面来简单的用代码讲讲这个方法的运用。

class Animals{
    public int age;
    public String name;

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

    public void eat() {
        System.out.println(this.name + "在吃饭");
    }
}

interface IRunning{
    void run();
}

interface ISwimming{
    void swim();
}

interface IFlying{
    void fly();
}

class Dog extends Animals implements IRunning,ISwimming{


    public Dog(String name) {
        super(name);
    }

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

    @Override
    public void swim() {
        System.out.println(this.name+"正在游泳");
    }
}


class Robit implements ISwimming{

    @Override
    public void swim() {
        System.out.println("我是机器人,我在跑");
    }
}

public class TestDemo {
    public static void walk(ISwimming swimming){
        swimming.swim();
    }


    public static void main(String[] args) {
        ISwimming cat=new Dog("mimi");
        ISwimming dog=new Dog("nini2");
        walk(dog);
        walk(cat);
        walk(new Robit());
    }


    public static void main1(String[] args) {
        Dog dog=new Dog("小狗");
        dog.run();
        dog.swim();
    }
}

运行结果如下

 12.类和接口之间是implements,那接口和接口之间的关系是什么呢?extends

下面用代码来实现一下结果。

interface A{
    void func();
}

interface B{
    void func1();
}

interface C extends A,B{
    void func2();
}

class D implements C{

    @Override
    public void func() {
        
    }

    @Override
    public void func1() {

    }

    @Override
    public void func2() {

    }
}

由此可知,接口和接口之间可以用extends来关联,但是当你关联之后,有一个类用了一种一个接口的时候,需要把相关的接口里面的方法全部都重写。

讲三个重要的接口,以前我们排序的代码如下

int[] a={32,1,24,29,17};
        Arrays.sort(a);
        System.out.println(Arrays.toString(a));

那现在我们新建了一个类,来描绘数组学生,里面有学生的姓名,年龄,成绩,那么我们应该怎么排序呢?代码如下

class Student implements Comparable<Student>{
    public String name;
    public int age;
    public 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;
    }
}





public class Test {
    public static void main(String[] args) {
        Student[] students=new Student[3];
        students[0]=new Student("zhangsan",26,79.0);
        students[1]=new Student("lisi",36,89.0);
        students[2]=new Student("abc",46,99.0);

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

这个代码就是以年龄来排序,如果用其他的应该怎么写呢?

我就直接展示compareTo里面的代码吧。

public int compareTo(Student o) {
        //return this.age-o.age;
        return this.name.compareTo(o.name);
    }

但是这个方法其实也有他自己的缺陷,你写的是age的比较,但是当其他人用的时候,想用name来比较,还得继续改,就比较麻烦。下面我就用一个新的方法来说一下,名字叫比较器。代码如下

class Student {
    public String name;
    public int age;
    public 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<Student>{

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

class StringComparator implements Comparator<Student>{


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

class ScoreComparator implements Comparator<Student>{

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


public class Test {
    public static void main(String[] args) {
        Student[] students=new Student[3];
        students[0]=new Student("zhangsan",26,79.0);
        students[1]=new Student("lisi",36,89.0);
        students[2]=new Student("abc",46,99.0);

        AgeComparator ageComparator=new AgeComparator();
        StringComparator stringComparator=new StringComparator();
        ScoreComparator scoreComparator=new ScoreComparator();
        Arrays.sort(students,ageComparator);
        System.out.println(Arrays.toString(students));
        Arrays.sort(students,stringComparator);
        System.out.println(Arrays.toString(students));
        Arrays.sort(students,scoreComparator);
        System.out.println(Arrays.toString(students));
    }

下面就提一下一个Clonable接口还有深拷贝,比前面的有一点点绕,但是其实还好。

class Person implements Cloneable{
    public int i=1234;

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

    @Override
    protected Object clone() throws CloneNotSupportedException {
        return super.clone();
    }
}

public class Test {
    public static void main(String[] args) throws CloneNotSupportedException {
        Person person1=new Person();
        Person person2=(Person) person1.clone();
        System.out.println(person2);
    }
    
}

这样就可以克隆person1里面的信息了。

下面来用代码表示一下什么叫深拷贝

class Money implements Cloneable{
    public double money=19.9;

    @Override
    protected Object clone() throws CloneNotSupportedException {
        return super.clone();
    }
}


class Person implements Cloneable{
    public int i=1234;
    public Money m=new Money();

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

    @Override
    protected Object clone() throws CloneNotSupportedException {
        Person tmp=(Person) super.clone();
        tmp.m=(Money) this.m.clone();
        return tmp;
    }
}

public class Test {
    public static void main(String[] args) throws CloneNotSupportedException {
        Person person1=new Person();
        Person person2=(Person) person1.clone();
        System.out.println(person2);
        System.out.println(person1.m.money);
        System.out.println(person2.m.money);
        person2.m.money=99.9;
        System.out.println("=================");
        System.out.println(person1.m.money);
        System.out.println(person2.m.money);
    }

}

实现深拷贝,是代码层次上进行的,不是说,某个方法是深拷贝,是从代码的实现上来看的

抽象类和接口的区别 

抽象类和接口都是 Java 中多态的常见使用方式. 都需要重点掌握. 同时又要认清两者的区别(重要!!! 常见面试题).

核心区别: 抽象类中可以包含普通方法和普通字段, 这样的普通方法和字段可以被子类直接使用(不必重写), 而接口中不能包含普通方法, 子类必须重写所有的抽象方法.

抽象类存在的意义是为了让编译器更好的校验, 像 Animal 这样的类我们并不会直接使用, 而是使用它的子类.万一不小心创建了 Animal 的实例, 编译器会及时提醒我们.

 

 


版权声明:本文为m0_64761752原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
原文链接:https://blog.csdn.net/m0_64761752/article/details/127047151