查了一些国内资料,都说java中extended与implements的区别是,一个类只能有一个继承,一个类能够有多个容器。java
后来去看了些国外资料。web
在我理解上,interface就是一个公共的类,能够包含公共函数、变量。设计模式
Java接口是用于指定一组抽象方法的类来实现一个抽象类型。ide
当一个类实现一个接口,它必须继承全部的内声明的抽象方法,好像签定了一份合同,并履行协议。函数
先来看看怎么声明一个接口,文件保存为 InterFace.java
:this
public class InterFace { public static void main(String[] args) { MyTest x = new MyTest(); x.speak(); x.say(); x.fuck(); } } class MyTest implements MyInterface2, MyInterface3 { @Override public void speak() { System.out.println("MyTest Called => jump() =>"+MyInterface.hello); } @Override public void fuck() { System.out.println("MyTest Called => fuck()"); } @Override public void say() { System.out.println("MyTest Called => say()"); } } interface MyInterface1{ public String hello = "hello"; public void speak(); } interface MyInterface2{ public int num = 1; public void fuck(); } // 接口之间能够相互继承 interface MyInterface3 extends MyInterface1{ public void say(); }
输出以下:spa
$javac InterFace.java $java InterFace MyTest Called => jump() =>hello MyTest Called => say() MyTest Called => fuck()
这里咱们声明了3个接口,而且interface3继承自interface1,因此当类容器导入接口interface3就会导入父类接口interface1。.net
只要添加了容器implements,就会包含接口中的全部东西,因此必须在MyTest
类中添加该重写函数,不然找不到该函数会报错。设计
再看下面一个例子,多个类共同使用一个interface接口,保存为Account.java
:
interface Transaction { int BALANCE = 500; Object transaction(Object input); } class CurrentAccount implements Transaction { int bal; public Object transaction(Object input) { this.bal = BALANCE - (int)input; return bal; } public String toString() { return "Current acc"; } } class SavingsAccount implements Transaction { int bal; public Object transaction(Object input) { this.bal = BALANCE + (int)input; return bal; } public String toString() { return "Savings acc"; } } public class Account { public static void payment(Transaction t, Object input) { System.out.println(t + " is debited: " + t.transaction(input)); } public static void deposit(Transaction t, Object input) { System.out.println(t + " is credited: " + t.transaction(input)); } public static void main(String[] args) { Integer input = new Integer(600); deposit(new SavingsAccount(), input); payment(new CurrentAccount(), input); } }
代码输出:
$javac Account.java $java Account Savings acc is credited: 1100 Current acc is debited: -100
一个接口能够供多个类共同使用,而且多个类之间使用不冲突,这样看来,interface倒有点像是静态函数了。
观察一下这两个实现类活期帐户和储蓄帐户自动的向上转型在接受Transaction接口Account类中的方法。
payment()和deposit()方法利用咱们所讲的战略设计模式,表明了接口的实现彻底脱钩的一个实例。
从理论上说,你能够适应任何类,只需使它们符合的界面,使用这些方法。
对于接口与容器,我见过的一个更具备实用价值的地方,在于类之间的监听函数调用。
相似于js中的事件驱动函数,当有事件发生时候,经过回调函数,通知主函数。
实例代码以下,文件命名为Homeway.java:
public class Homeway { public static void main(String[] args) { System.out.println("\n=======================Implements======================\n"); ClassImplements mClassImplements = new ClassImplements(); mClassImplements.run(); } } class ClassImplements implements Implements1.Listener { public Implements1 mImplements1 = null; public ClassImplements(){ mImplements1 = new Implements1(); mImplements1.setListener(this); } @Override public void onCallStart(){ System.out.println("ClassImplements => onCallStart()"); } @Override public void onCallStop(){ System.out.println("ClassImplements => onCallStop()"); } public void run(){ mImplements1.run(); } } //test 2level implements for class class Implements1 implements Implements2.Listener { private Listener mListener; private Implements2 mImplements2; public Implements1(){ mImplements2 = new Implements2();//把当前类传给下个类 mImplements2.setListener(this); System.out.println("Init Implements1 =>..."); } public static interface Listener { void onCallStart(); void onCallStop(); } public void setListener(Listener listener) { mListener = listener; } @Override public void onCallStart(){ System.out.println("Implements1 => onCallStart()"); mListener.onCallStart();//call at Implements1 and then throw to ClassImplements } @Override public void onCallStop(){ System.out.println("Implements1 => onCallStop()"); mListener.onCallStop();//call at Implements1 and then throw to ClassImplements } public void run(){ this.mImplements2.run(); } } //3 level implement test class Implements2{ private Listener mListener; public Implements2(){ System.out.println("Init Implements2 =>..."); } public static interface Listener { void onCallStart(); void onCallStop(); } public void setListener(Listener listener) { mListener = listener; } public void onCallStart(){ System.out.println("Implements2 => onCallStart()"); } public void onCallStop(){ System.out.println("Implements2 => onCallStop()"); } public void run() { System.out.println("Run some functions and then callback from Listener..."); mListener.onCallStart(); mListener.onCallStop(); } }
输出以下:
$javac Homeway.java $java Homeway =======================Implements====================== Init Implements2 =>... Init Implements1 =>... Run some functions and then callback from Listener... Implements1 => onCallStart() ClassImplements => onCallStart() Implements1 => onCallStop() ClassImplements => onCallStop()
咱们先是声明了类ClassImplements,这个是咱们的主类,而且implements了Implements1.Listener
经过一个Listener创建了监听接口,
而后Implements1
又implements了Implements2.Listener
创建了第2级的监听。
一旦Implements1
或Implements2
内的某个函数触发了某个事件,就能经过监听接口发送给主函数ClassImplements
,相似js中的事件回调函数。
父类与子类经过Listener实现接口调用,此时Listener即为父类自己。
大体的模型以下:
implements容器与interface接口在java类中有不少很好用的模型,有时间该多去研究研究。