详解 接口

在本篇博文的内容之前,本人要提醒一点,这个知识点,虽然可能会在现在看起来不是很有用,但是本人能够打包票的说,这篇博文的知识点,和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. 分类。

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

posted @ 2020-03-05 10:18  在下右转,有何贵干  阅读(175)  评论(0编辑  收藏  举报