Java中 接口 interface的作用——經典實例

interface Extendbroadable{
public void inPut();
}
class KeyBroad     implements Extendbroadable{
public void inPut(){
System.out.println(“\n hi,keybroad has be input into then mainbroad!\n”);
}
}
class NetCardBroad     implements Extendbroadable{
public void inPut(){
System.out.println(“\n hi,netCardBroad has be input into then mainbroad!\n”);
}
}
class CheckBroad{
public void getMainMessage(Extendbroadable ext){
ext.inPut();
}
}
public class InterfaceTest01{
public     static void main(String []args){
KeyBroad kb=new KeyBroad();
NetCardBroad ncb=new NetCardBroad();
CheckBroad cb=new CheckBroad();
cb.getMainMessage(kb);
cb.getMainMessage(ncb);


}
}

1.JAVA多態接口動態加載實例

爲某研究所編寫一個通用程序,用來計算每一種交通工具運行 1000公里所需的時間,已知每種交通工具的參數都是3個整數A、B、C的表達式。現有兩種工具:Car 和Plane,其中Car 的速度運算公式爲:A*B/C,Plane 的速度運算公式爲:A+B+C。需要編寫三類:ComputeTime.java,Plane.java,Car.java和接口Common.java,要求在未來如果增加第3種交通工具的時候,不必修改以前的任何程序,只需要編寫新的交通工具的程序。其運行過程如下,從命令行輸入ComputeTime的四個參數,第一個是交通工具的類型,第二、三、四個參數分別時整數A、B、C,舉例如下:      

計算Plane的時間:”javaComputeTime Plane 20 30 40″

計算Car007的時間:”java ComputeTime Car007 23 34 45″
如果第3種交通工具爲Ship,則只需要編寫Ship.java,運行時輸入:”java ComputeTime Ship 22 33 44″
提示:充分利用接口的概念,接口對象充當參數。


實例化一個對象的另外一種辦法:Class.forName(str).newInstance();例如需要實例化一個Plane對象的話,則只要調用Class.forName(“Plane”).newInstance()便可。


代碼:
1. ComputTime.java 請確保輸入正確,其中沒有捕捉NumberFromatException
package com.hk.demo.interfacetest;
import java.lang.*;
public class ComputeTime {
   public static void main(String args[]) {
	System.out.println("交通工具: "+args[0]);
	System.out.println(" 參數A: "+args[1]);
	System.out.println(" 參數B: "+args[2]);
	System.out.println(" 參數C: "+args[3]);
	double A=Double.parseDouble(args[1]);
	double B=Double.parseDouble(args[2]);
	double C=Double.parseDouble(args[3]);
	double v,t;
	try {
             //這裏com.hk.demo.interfacetest爲包名
	    Common d=(Common) Class.forName("com.hk.demo.interfacetest."+args[0]).newInstance();
	    v=d.runTimer(A,B,C);
	    t=1000/v;
	    System.out.println("平均速度: "+v+" km/h");
	    System.out.println("運行時間:"+t+" 小時");
        } catch(Exception e)    {
	    System.out.println("class not found");
	}
   }
}
這個類,用來調用顯示給用戶,用戶通過這個類,可以直接輸入類型、參數就可以實現其目的。
2.Plane.java
package com.hk.demo.interfacetest;
public class Plane implements Common {
  public double runTimer(double a, double b, double c) {
      return (a+ b + c);
   }
}


3. Car.java


package com.hk.demo.interfacetest;
  public class Car implements Common {
      public double runTimer(double a, double b, double c) {
         return ( a*b/c );
    }
}

4.Common.java

package com.hk.demo.interfacetest;


//方式一: 通過繼承普通父類的方式,重新寫父類中的方法以達到覆蓋
//public  class Common { 
//   double runTimer(double a,double b, double c){
//	   return 0;
//   };
//}


//方式二:接口的方式 推薦
public interface Common{
	double runTimer(double a,double b,double c);
}


//方式三:abstract關鍵字方式 這跟方式一是一樣的,只是用了abstract修飾,不能實例化該類。具體請查看abstract的用法
//public abstract class Common{
//	abstract double runTimer(double a,double b,double c);
//}

而,Car中的runTimer和Plane中的runTimer爲什麼一定要繼承Common接口呢?感覺這不是必須的嘛!!我們完全可以寫一個public的方法,名字爲runTimer,這種目的是不是也能也能實現。

但是

    1、倘若plane中寫了runTimer來計算速讀,而另一個Car中寫了runTime這樣的話,當實例化Car的時候,調用runTimer不就錯了嗎?所以此時的接口可以統一約束相同功能但是實現效果不同的情況。下面是Common接口的代碼。

   2、對1的理解其實是錯誤的,看我們代碼中ComputTime類中根據不同的參數實例化不同的對象。既然是不同的對象那麼

Common d=(Common) Class.forName(“CalTime.vehicle.”+args[0]).newInstance();

這句話不就錯了嗎?這裏顯然都是Common對象,怎麼回事不同的對象呢?所以只有一個解釋,那就是Common可以代表這些new出來的對象,所以common就是他們的父類。

  3、既然是父類當然可以用extend繼承父類的方法,當然這樣也可以,也可以用abstract類。但是extend只能單一繼承,並不能繼承多個父類,所以有的時候必須要用interface。(這裏因爲就繼承一個類中的方法,所以用exend繼承父類和implement繼承接口都一樣的。我的附件中兩種情況都列出來了。)


一次運行結果:
這裏是通過控制檯運行的,如果使用的是eclipse可以參考我的上一篇博客,eclipse中如何給main輸入參數。

C:\java>java     ComputeTime Car 100 45 67
交通工具: Car
參數A: 100
參數B: 45
參數C: 67
平均速度: 67.16417910447761 km/h
運行時間:14.88888888888889 小時


C:\java>java     ComputeTime Plane 130 45 67
交通工具: Plane
參數A: 130
參數B: 45
參數C: 67
平均速度: 242.0 km/h
運行時間:4.132231404958677 小時

現在回到我們的最初的要求,倘若我們新加一個Ship類,而且不改變之前的代碼,是不是就很簡單了呢?這樣拓展性也就很強了。

演示了接口的經典使用方法。嗬嗬,只有意會,不可言傳。 Thinking in Java 對此也做出了深刻的分析,可以查看下。

附件 鏈接: http://pan.baidu.com/share/link?shareid=175105860&uk=3037731871
2.接口作爲方法的參數傳遞。


先看一個接口應用的例子:


interface Extendbroadable{
public void inPut();
}
class KeyBroad     implements Extendbroadable{
public void inPut(){
System.out.println(“\n hi,keybroad has be input into then mainbroad!\n”);
}
}
class NetCardBroad     implements Extendbroadable{
public void inPut(){
System.out.println(“\n hi,netCardBroad has be input into then mainbroad!\n”);
}
}
class CheckBroad{
public void getMainMessage(Extendbroadable ext){
ext.inPut();
}
}
public class InterfaceTest01{
public     static void main(String []args){
KeyBroad kb=new KeyBroad();
NetCardBroad ncb=new NetCardBroad();
CheckBroad cb=new CheckBroad();
cb.getMainMessage(kb);
cb.getMainMessage(ncb);


}
}


可以將藉口類型的參數作爲方法參數,在實際是使用時可以將實現了接口的類傳遞給方法,後方法或按照重寫的原則執行,實際調用的是實現類中的方法代碼體,這樣便根據傳進屋的參數的不同而實現不同的功能。


重要的是,當我以後徐要林外一個對象並且擁有接受說生命的方法的時候的時候,我們不必須原類,只需新的類實現藉口即可。



附件鏈接:點擊打開鏈接

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章