详解 接口

在本篇博文的内容之前,本人要提醒一点,这个知识点,虽然可能会在现在看起来不是很有用,但是本人能够打包票的说,这篇博文的知识点,和class同等重要,那么,开始我们这篇博文内容的讲解吧!

我们的每一个程序都有一个关键字——class.
那么,在本篇博文中,本人要讲一个和class同等级的关键字——interface

我们知道:以class开头的文件是 ,而以interface开头的文件,就是接口

但是接口却有如下特点

接口的特点

  1. 接口用关键字interface表示 格式: interface 接口名 {}
  2. 实现接口用implements表示 格式: class 类名 implements 接口名 {}
  3. 接口不能实例化
    问:那么,接口如何实例化呢?
    答曰:按照多态的方式来实例化。
  4. 接口的子类
    a:可以是抽象类。但是意义不大。
    b:可以是具体类。要重写接口中的所有抽象方法。(推荐方案)
  5. 和class平起平坐
  6. 只含有
    抽象方法
    确定了的 方法——本人先根据我们学习C的函数来讲:相当于规定了函数的名称、参数、函数类型、函数功能(只管有什么功能,不管如何实现);
  7. 任何接口的实现类,都可以看成该接口的派生类。若派生类没有完成“所有”的接口中的>抽象方法,则认为该派生类也是抽象类;
  8. 接口也可以继承接口,但是必须要在子接口中用default定义父接口的所有方法

接口的成员具有如下特点

接口成员特点:

  • 成员变量:只能是常量,并且是静态的
    默认修饰符:public static final
  • 构造方法:接口没有构造方法。
  • 成员方法:只能是抽象方法。
    默认修饰符:public abstract

现在,本人来介绍一下 类 和 接口 之间的关系

类与类,类与接口,接口与接口的关系

  1. 类与类
    继承关系,只能单继承,可以多层继承
  2. 类与接口
    实现关系,可以单实现,也可以多实现
    并且还可以在继承一个类的同时实现多个接口。
  3. 接口与接口
    继承关系,可以单继承,也可以多继承

下面,我们来编写一个接口,顺便来展示下如何继承接口:
IShape .java:

package com.mec.shape;

public interface IShape {

    //本人对于接口中default修饰的方法认识:
    //默认派生类中用到此抽象方法的“大多数”都是按照这种实现方法
    //至于剩余少数,则可以按照在派生类中覆盖这个方法来实现其目的
    default double rounder() {
        return 1.0;
    }
    double area();
    
}

上面的代码,就表示我定义了一个接口,那么,下面我来用一个类来继承这个接口:
Rectangel类;

package com.mec.shape;

public class Rectangel implements IShape {  //继承哪个接口,就要在该类名后写上:implements 接口名。若是继承多个接口,只需在每个接口之间

    private double width;
    private double height;
    
    public Rectangel() {
    }
    
    public Rectangel(double width, double height) {
        this.height = height;
        this.width = width;
    }
    
    //继承接口,就要将其内部所有的方法实现(除default修饰的方法外)
    @Override
    public double rounder() {
        return 2 * (width + height);
    }

    @Override
    public double area() {
        return width * height;
    }

}

下面,本人再编写一个类,来观看下运行结果:
Test类:

package com.mec.shape;

public class Test {
    
    public static void main(String[] args) {
        IShape rectangel = new Rectangel(3.5, 6.5);
        System.out.println("周长:" + rectangel.rounder()+ " 面积:" + rectangel.area());
        
        IShape circle = new IShape() {
            private double radius;
            
            public IShape setRadius(double radius) {
                this.radius = radius;
                
                return this;
            }
            
            @Override
            public double rounder() {
                return 2 * Math.PI * radius;
            }
            
            @Override
            public double area() {
                return Math.PI * radius *radius;
            }
        }.setRadius(2.0);
        System.out.println("周长:" + circle.rounder()+ " 面积:" + circle.area());
        
        //若这里输出true,则表明派生类是接口的子类
        System.out.println(circle instanceof IShape);
    }
        
}

我们来观看下运行结果:

在这里插入图片描述上图说明一个问题:
接口的实现类 的对象,就是 接口 的对象

下面,本人来讲述下 接口 与 HashMap 的联合运用:
IMyUnionType.java:

package com.mec.shape;

public interface IMyUnionType { //接口的名称必须以大写字母“I”开头

}

在这个类中,我们什么先都不写,然后在我们之前的 Complex类、OtherPoint类中,都让其继承这个接口:
Complex类;

package com.mec.study.complex;

import com.mec.shape.IMyUnionType;

public class Complex implements IMyUnionType {
    private double real;
    private double vir;
    
    public Complex(double real, double vir) {
        this.real = real;
        this.vir = vir;
    }
    
    public Complex() {
        this(0.0, 0.0);
    }

    public Complex(Complex c) {
        this(c.real, c.vir);
    }

    public double getReal() {
        return real;
    }

    public void setReal(double real) {
        this.real = real;
    }

    public double getVir() {
        return vir;
    }

    public void setVir(double vir) {
        this.vir = vir;
    }
    
    public Complex add(Complex c) {
        this.real += c.real;
        this.vir += c.vir;
        
        return this;
    }
    
    public static Complex add(Complex one, Complex another) {
        return new Complex (one).add(another);
    }
    
    private static Complex opposite(Complex c) {
        return new Complex(-c.real, -c.vir);
    }
    
    private static Complex reciprocal(Complex c) {
        double model = c.real * c.real + c.vir * c.vir;
        
        if(Math.abs(model) < 1e-6) {
            return null;
        }
        
        return new Complex(c.real / model, -c.vir / model);
    }
    
    public Complex sub(Complex c) {
        return this.add(opposite(c));
    }
    
    public static Complex sub(Complex one, Complex another) {
        return new Complex(one).add(opposite(another));
    }
    
    public Complex mul(Complex one) {
        double real = this.real;
        
        this.real = real * one.real - this.vir * one.vir;
        this.vir = real * one.vir - this.vir * one.real;
        
        return this;
    }

    public static Complex mul(Complex one, Complex another) {
        return new Complex (one).mul(another);
    }
    
    public static Complex div(Complex one, Complex another) {
        Complex rec = reciprocal(another);
        return rec == null ? null : new Complex(one).mul(rec);
    }
    
    @Override
    public String toString() {
        return "(" + real + "," + vir + ")";
    }
    
    @Override
    public boolean equals(Object obj) {
        if(null == obj) {
            return false;
        }
        if(this == obj) {
            return true;
        }
        if(!(obj instanceof Complex)) {
            return false;
        }
        Complex c = (Complex) obj;
        return Math.abs(this.real - c.real) < 1e-6
                && Math.abs(this.vir - c.vir) < 1e-6;
    }
    
}

OtherPoint类:

package com.mec.about_point;

import com.mec.shape.IMyUnionType;

public class OtherPoint extends Point implements IMyUnionType {
    
    public OtherPoint() {
        super();
    }
    
    public OtherPoint(int row, int col) {
        super(row, col);
    }
    
}

然后,编写一个 Demo类,来用HashMap来存储这些类的对象:
Demo类:

package com.mec.about_test;

import java.util.HashMap;
import java.util.Map;

import com.mec.study.complex.Complex;
import com.mec.shape.IMyUnionType;
import com.mec.about_point.OtherPoint;

public class Demo {

    public static void main(String[] args) {
        //这里是我们用名为objectMap的HashMap来存储 两个类的对象
        Map<String, IMyUnionType> objectMap = new HashMap<>();
        
        OtherPoint p =new OtherPoint(1, 2);
        if(p instanceof IMyUnionType) {
            IMyUnionType q = (IMyUnionType) p;
            objectMap.put("点", q);
        }

        Complex c = new Complex();
        objectMap.put("复数",  c);
    }

}

下面,我们来看一下运行结果:
在这里插入图片描述运行结果没有出错,这就表明,我们未来可以用这种手段来保护我们所编写的一些类,只给外部提供那张表即可。

这里对default关键字 做一下解释:

default 在 接口 中的的应用:
一般用于接口中有默认实现手段
但若想在派生类中自行完成,可以覆盖基类中的default方法

最后,本人还要讲解一点:
可能有同学想问:本人说过一个类只能有一个基类,但一个类可以有多个接口。
那么,若是两个接口中有同名的成员 或者 同名的方法 呢?
答曰:若是一个类有两个以上的接口时,调用该接口的成员或方法时,一般都会加上如下的前缀,以表明是哪个接口的成员或方法:

接口名.

在文章的末尾,本人来介绍一个有关接口的最最最最最重要的知识点
那就是——接口的四大性质

接口的 性质

  1. 消费未来;
  2. 海纳百川;
  3. 开闭原则;
  4. 分类。

而这四大性质,本人不进行深入讲解,先提出,当在本人之后的博文中遇到时,本人再来重新进行实例化讲解。
因为现在进行深入讲解的话,同学们可能会因为没有见过应用场合而觉得其作用很鸡肋。
但当我们之后的博文中出现了遇到了这四大基本作用时,本人将通过例子来让同学们了解其的重要性。

猜你喜欢

转载自www.cnblogs.com/codderYouzg/p/12418730.html