现实中电脑 相机 笔记本等都有USB接口,且任何一个U盘都可以插入。这是因为所有的厂家都遵循了USB接口的标准和规范。才可以让全部的USB接口和产品兼容匹配。
而JAVA接口是一系列方法的声明,是一些方法特征的集合。一个接口只有方法的特征没有方法的实现,因此这些方法可以在不同的地方被不同的类实现,因此这些实现可以具有不同的行为。
接口可以理解为一种特殊的类,在这个特殊的类中,里面只有 全局常量和公共抽象方法(jdk8以后可以有默认方法和静态方法)。 接口是解决Java无法多继承的一种手段,实际运用中接口更多是指定标准的作用。
抽象类和接口的区别
抽象类中可以有正常类的所有成员:代码块 静态代码块 构造器 属性…
接口中只能有全局常量和抽象方法和静态方法和默认方法。静态方法与默认方法必须有方法体
ps: ( 抽象类可以存在非抽象方法,接口只能存在抽象方法)java8以后接口中可以有静态方法和default修饰符的默认方法(有方法体)
就像一个普通类一样接口也有方法和属性,但是在接口中声明的方法默认是抽象的。只有方法标识符,没有方法体
普通方法默认以 public abstract修饰符修饰,也可以不写但是默认这两个修饰符还是存在的。
声明一个类 我们是用 class 类名 。同理接口是用 interface 接口名声明一个接口
interface 接口名{
//全局变量属性
// 抽象方法
// 静态方法
// default修饰的默认方法
}
class 类名 implements 接口名{
//该类自己的属性和方法
//实现接口的抽象方法
}
public interface UsbInterface {//全局变量public static final可以不写,结果是一样的。默认就是这三个修饰符public static final int num =1 ;//抽象方法 public abstract可以不写,结果是一样的public abstract void read();//默认方法 必须有方法体default void work(){}//静态方法 必须有方法体static void wee(){}
}
在接口中所有的方法都必须只声明方法标识,而不实现方法体。因为具体的实现是由基础该接口的类去实现的。
入门演示:
public interface UsbIntelface {//接口public static final int num = 90;public abstract void inMethod();
}
class TestInterface implements UsbIntelface{//实现接口@Overridepublic void inMethod() {//重写接口的抽象方法System.out.println("实现了接口的inMethod方法"+num);}public static void main(String[] args) {new TestInterface().inMethod();}
}
入门案例
在现实生活中如果某个设备想向电脑读取或者写入一些东西,最常见的方法就是通过USB接口。只要带有USB功能的设备就可以通过USB接口与电脑完成交互。在这可以认为USB就是一种功能,一种标准,一种接口。只要实现了USB标准的设备就是有了USB功能。我们可以通过代码模拟一下。
比如触手可及的键盘和鼠标,默认USB接口中有读取和写入的功能。
public interface UsbIntelface {public abstract void read();//也可以直接写 void read,结果是一样的void write();
}
class keyboard implements UsbIntelface{@Overridepublic void read() {System.out.println("键盘正在读取...");}@Overridepublic void write() {System.out.println("键盘正在写入...");}
}
class mouse implements UsbIntelface{@Overridepublic void read() {System.out.println("鼠标正在读取...");}@Overridepublic void write() {System.out.println("鼠标正在写入...");}
}
class Test122{public static void main(String[] args) {keyboard k = new keyboard();k.read();k.write();mouse m = new mouse();m.read();m.write();}
}
运行结果:
键盘正在读取…
键盘正在写入…
鼠标正在读取…
鼠标正在写入…
而使用接口定义标准就可以很好的规范程序员,或者指定一个标准。
例如:定义一个接口 里面有抽象方法connect是连接到数据库,close方法是断开数据库。
然后让两个程序员分别在两个类去实现这个接口完成要求的功能。再根据java的多态使用接口,就可以规范代码,和降低复杂度。
代码演示:
public interface AInterface {void connect();void close();
}
class Mysqlinterface implements AInterface{@Overridepublic void connect() {System.out.println("连接到Mysql");}@Overridepublic void close() {System.out.println("断开Mysql");}
}
class Oraclelinterface implements AInterface{@Overridepublic void connect() {System.out.println("连接到Oracle");}@Overridepublic void close() {System.out.println("断开Oracle");}
}
class testinterface{public static void str(AInterface aInterface){aInterface.connect();aInterface.close();}public static void main(String[] args) {Mysqlinterface m = new Mysqlinterface();Oraclelinterface o = new Oraclelinterface();testinterface.str(m);testinterface.str(o);}
}
下列语法是否正确?如果正确会输出什么
interface A{
int a = 23;
}
class B implements A{//正确,因为接口中没有抽象方法,所以不用实现
}
//主类main方法中
B b = new B();
System.out.println(b.a);//23
System.out.println(A.a);//23
System.out.println(B.a);//23可以把implement看成一种另类的继承extends
举例说明:
猴子会爬树,这是与之俱来的功能。或者是猴子他爸教给他的能力。这种就是继承 LittleMmonkey extends Oldmonkey。
但是这只小猴子比较好学,他想像鱼一样游泳。或者像鸟一样飞翔。但是它本身又没有这个功能,它的父类也没有这个能力,所以它得通过自己去学习,实现游泳和飞翔的能力。
代码演示:
public class OldMonkey {String name;public void tree(){System.out.println("猴子上树");}
}
interface Fish{void swimming();
}
interface Bird{void fly();
}
class LitteMonkey extends OldMonkey implements Fish,Bird{@Overridepublic void swimming() {System.out.println(name+"通过学习,学会了游泳");}@Overridepublic void fly() {System.out.println(name+"通过学习,学会了飞");}
}
class testm{public static void main(String[] args) {LitteMonkey li = new LitteMonkey();li.tree();li.swimming();li.tree();}
}
综上:由于java中不允许多继承,所以接口可作为继承的一种补充拓展,或多继承的替代。
继承的价值在于:解决代码的复用性和可维护性
接口的价值在于:设计好各种规范,使其他类更加灵活
继承需要满足 is a 的关系。例如猫是一个动物。而接口只需要满足like a 的关系,猴子像一只鸟,也是可以的,因为并没有改变它的物种。
接口的多态在运用上和继承体现的多态大差不差,概念大致相同。
1.接口参数的多态
和继承一样,在定义一个方法时,形参使用的是父类,实际传入子类是允许的。接口也是同理,在定义方法时使用接口类型,实际运行时传入实现了接口的类,也是允许的。
案例:
public class OldMonkey implements USBinterface{@Overridepublic void fly() {System.out.println("正在飞");}
}
interface USBinterface{void fly();
}
class testm{public void deFly(USBinterface usBinterface){//形参是接口类型usBinterface.fly();}public static void main(String[] args) {OldMonkey om = new OldMonkey();new testm().deFly(om);//实际传入运行的是实现接口的类}
}
2.接口的多态数组
接口的多态数组和继承体现的差不多,只不过继承是父类的数组存放着子类对象。而接口是接口类型的数组 存放着实现了接口的类对象
案例体现:
1.Usb数组种存放Phone和相机对象
2.Phone类有一个特别的方法call()
3.相机有一个特别的方法photo()。
4.Usb是一个接口类型,有抽象方法work()
5.遍历这个数组,且除了调用work方法外都调用一下各自的方法
public class Homework {public static void main(String[] args) {Usb[] usbs = new Usb[2];usbs[0] = new Phone();usbs[1] = new Camera();for (int i = 0; i < usbs.length; i++) {usbs[i].work();//因为要分别调用各个类自己的方法,所以要先进行类判断,然后向下转型再调用自己的方法if (usbs[i] instanceof Phone){((Phone) usbs[i]).call();}if (usbs[i] instanceof Camera){((Camera) usbs[i]).photo();}}}
}
interface Usb{void work();
}
class Phone implements Usb{public void call(){System.out.println("正在打电话");}@Overridepublic void work() {System.out.println("IPhone正在工作");}
}
class Camera implements Usb{public void photo(){System.out.println("正在拍照");}@Overridepublic void work() {System.out.println("相机正在工作");}
}
3.接口的多态传递
在继承种向上转型可以使用 父类的引用指向子类的对象,也可以使用爷爷类的引用指向子类的对象。
在接口种也可以使用接口类型的引用指向实现了接口的类对象,那么接口B继承与接口A,是否可以用接口A的引用指向实现了接口B的类对象呢
答案是可以的,因为B接口继承于A接口,而类想要implement接口B就必须把接口A和B的所有抽象方法都给实现了。因此他们也是有关系的。这就是接口的多态传递
代码演示
public class abc {public static void main(String[] args) {B b = new SON();A a = new SON();//多态传递}
}
interface A{void me();
}
interface B extends A{}
class SON implements B{//必须实现A的抽象方法@Overridepublic void me() {}
}
1.下面代码是否有错误,怎么修改。
interface A{int x = 0;}
class B{int x = 1;}
class C extends B implements A{
public void px(){
Sysem.out.println(x)}//错误点,编译器会不知道x是指谁,两个x是同级存在
public static void main(String [] args){
new C().px();
}
}
如果要输出父类的x就使用super.x,如果要输出接口的x就使用 A.x.