接口的概念:
官方解释:Java接口是一系列方法的声明,是一些方法特征的集合,一个接口只有方法的特征没有方法的实现,因此这些方法可以在不同的地方被不同的类实现,而这些实现可以具有不同的行为。在接口中,它的方法是绝对抽象的,用来抽象子类的能力、规则。例如鸟的fly,????的swim,数字能够Compare,这就是鸟类,????类的能力。
在现实中也有很多事物用到了接口的概念例如:数据线,在使用数据线充电时,只要你使用安卓的数据线,一般都能够给安卓手机充电,因为这类充电线的插口都按照Android的规则、规格来生产数据线,这里使用到的是接口能定义规则生活中很多物品的规格都是严格要求好的,这有利于产品的拓展。对于面对对象的java语言也是如此,对象是用来描述、描绘一个事物的,有了接口,可以提高对象的扩展性,灵活性。
接口中除了默认方法和静态方法,都没有方法体
在jdk8以前,所有方法都是抽象的.接口没有方法体,是因为,接口是用来规范代码,使得代码结构更清晰。jdk接口可以有默认方法,默认方法有方法体,并且子类可以不实现默认方法,直接使用,也可以覆盖接口的方法意义:现在有一个接口和若干个实现该接口的类,假如只是部分接口需要这个新方法,那怎么办?在接口中直接添加新方法:所有类都要实现该方法,很麻烦使用抽象类(建议看完下面抽象类再来看这个):使用抽象类实现接口并添加新方法,需要实现的子类继承自抽象类即可在接口中添加默认方法!!接口无法实例化
一个类可以实现多个接口
接口可以继承其他接口,并且可以多继承接口,但是接口接口需要使用extends
public interface InterfaceB extends InterfaceA,InterfaceC{
}
//这里要注意了,接口继承接口,接口可以不实现其父接口的抽象方法
//虽然这个接口里面没有抽象方法,但是实现这个接口的类必须实现接口A中的方法
//即:类实现某个接口,从层级关系上讲,类必须实现其接口层级往上的所有的抽象方法
一个类如果要实现某个接口,需要实现其中所有的抽象方法因为接口是提取规则、能力,实现这个接口肯定就有这种能力,既然接口都抽象了这种方法,那子类都应该有这些方法。
为什么需要接口?
java无法多继承,接口可以用来抽象特性,可以弥补无法多继承的局限,同时也避免了多继承的复杂性良好的代码书写规范和清晰的代码层级关系利于源码的阅读和理解
接口无法实例化
接口的方法都是public的
因为接口是提取规则,没有子类实现接口,接口就没存在的意义了。要被子类实现,public是最好的,不同包内也可以实现这个接口
接口中的属性默认publicstaticfinal
因为接口中抽象的是规则,规则不应该能被改变,并且能被子类使用。定义静态常量时候必须有初始值
接口也有标识作用:
例如Serializable,其内部是连抽象方法都没有的,没有内容,这个接口的作用只是标识这个类具有某种功能。
publicstaticvoidmain(String[]args){Animalssheep=newAnimals(){@Overridepublicvoideat(Stringfoo{Systeout.println('羊吃'+foo;}};sheep.eat('草');Animalsfish=newAnimals(){@Overridepublicvoideat(Stringfoo{Systeout.println('鱼吃'+foo;}};fiseat('水草');}
接口和抽象类的区别
但是我先举一个实际的例子,来解释接口的作用,在此同时也会介绍抽象类和接口的区别这里我们先假设我们需要实现一种抽象的数字类,来思考一下其需要实现什么功能
能保存用户传给的值能和其他数字比较可以来输出保存的值最大能保存数字的范围能和其他数字进行转换
先别急,现在我们来看一下Java中是如何实现数字类及其子类的这个是IDEA中的Digrams,想使用可以IDEA中Digrams的使用来看一下源代码
public abstract class Number implements java.io.Serializable {
public abstract int intValue();//对应上方的保存值功能,注意这里的所有方法都没有方法体
public abstract long longValue();//返回值(相当于保存值、输出值)
public abstract float floatValue();//同上
public abstract double doubleValue();
public byte byteValue() {//强制转换
return (byte)intValue();
}
public short shortValue() {
return (short)intValue();
}
private static final long serialVersionUID = -8742448824652078965L;
}
再看一下实现Number抽象类的Integer的源码
public final class Integer extends Number implements Comparable{//注意这里继承了Number抽象类和Comparable接口
//保存值的范围
@Native public static final int MIN_VALUE = 0x80000000;
@Native public static final int MAX_VALUE = 0x7fffffff;
//输出值
public static String toString(int i, int radix){
....省略
}
//保存值
public int intValue() {
return value;
}
static int formatUnsignedInt(int val, int shift, char[] buf, int offset, int len) {
....省略
}
//和其他Integer类比较
public int compareTo(Integer anotherInteger) {
return compare(this.value, anotherInteger.value);
}
//转换成其他数字类
public long longValue() {
return (long)value;
}
}
再来看一下Comparable接口
public interface Comparable {
public int compareTo(T o);
}
//comparable接口中参数使用了泛型,不同的类实现不同的comparable接口即可,实现comparable接口的类需要实现其中的compareTo方法
现在我们思考几个问题
为什么Comparable是一个接口解:在编写代码的时候,我们要使得代码结构清晰,需要规范代码,这也是抽象类,父类,接口存在的意义之使用接口可以提取类的规则,抽象类可以提取类的共性内容。对于比较功能,数字肯定是可以比较是吧,但是很多其他类,比如自己创建一个employee和employer类,两个类之间可以有工资的比较方法或者其他比较方法,所以说Comparable应该是一个规则,Comparable作为接口最好,这样有比较功能的类实现该接口就行,如果,有比较功能的类的不实现comparable接口,却私自定义一个compare方法,那么接口存在的意义就被忽略了。Java无法实现多继承,这意味着假如Comparable是抽象类的话,那我们又如何让Integer继承Number类,两个类无法同时被一个类继承。这里也侧面体现了,接口可以解决java无法多继承的局限。为什么Number是一个抽象类解:抽象类抽取的是子类的特性、共性内容,可以看见Number类中有一些返回数值和保存数值的方法以及转换方法,这很明显是所有数字类的共性内容。先前介绍了数字类应该有的五个个功能,返回和保存以及转换只是其中三个功能,但是为什么数字范围没在抽象类中:上面Integer保存范围是用的final常量,抽象类虽然可以有final属性,但是不同数字类保存范围不一样,不是共同内容为什么Number中没有实现Comparable接口,而是其子类去实现Comparable接口:因为Comparable接口有泛型参数T,实现该接口的时候需要填写参数,所以放在抽象类Number的子类中最合适,方便实现Comparable的CompareTo方法。我这里写了一个小代码
public class IntegetTest extends NumberTest{
@Override
public int compare(NumberTest numberTest) {
return 0;
}
@Override
public int compareTo(NumberTest o) {
return 0;
}
}
假如有数字类继承了这个接口,其子类需要实现这个compare方法以及compareTo方法并且参数是NumberTest抽象类。我们看看Double继承了Number抽象类,那Double怎么实现compareTo方法的
......上方其他代码省略
public int compareTo(Double anotherDouble) {
return Double.compare(value, anotherDouble.value);
//value是newDouble类是保存在Double类中的一个值,体现了Double保存数值的功能
}
public static int compare(double d1, double d2) {
if (d1 < d2)
return -1; // Neither val is NaN, thisVal is smaller
if (d1 > d2)
return 1; // Neither val is NaN, thisVal is larger
// Cannot use doubleToRawLongBits because of possibility of NaNs.
long thisBits = Double.doubleToLongBits(d1);
long anotherBits = Double.doubleToLongBits(d2);
return (thisBits == anotherBits ? 0 : // Values are equal
(thisBits < anotherBits ? -1 : // (-0.0, 0.0) or (!NaN, NaN)
1)); // (0.0, -0.0) or (NaN, !NaN)
}
....下方其他代码省略
不需要理解很多,这里的compareTo方法使用了Double中保存的value,我们思考一下,假如是Number实现comparable接口,那么子类方法参数应该就是抽象类了,但是抽象类中虽然有保存数值的方法,但是并没有方法体,如果Number实现该接口,其子类的CompareTo方法和Compare方法的实现会变得麻烦很多。
为什么Number不能设计成一个接口Number是一种模板,它偏向于提取子类的共性内容,接口偏向于提取规则。所以写成抽象类比较方便
案例总结:
文章为作者独立观点,不代表股票交易接口观点