在面試可能經常被問到,接口有什么作用?相對于類而言,為何需要用類實現接口等等諸如此類的問題。如果不仔細想想,有時候還會卡住。這篇文章將簡單介紹下接口的作用。
對于接口而言,就是用來標記類的一個產物。每個接口都對應有一個或多個實現它的類,否則這個接口就成為冗余代碼。因為管理接口比管理類要簡單挺多,接口就由此體現了抽象的觀點。換句話說,接口就是沒有屬性和行為實現的類。類實現多個接口,可以解決類不能繼承多個類的機制。那么接口該怎么使用呢?
一 接口的作用
下面有兩個方面:
1. Java多態接口動態加載實例
這種實現方式,大家在很多場合下都可以見到。下面介紹一個Sample:
1) 接口類:
public interface PersonService {
/**
* 計算每月的工資
* sal:工資基數
* type:員工等級
*/
public double calcuMonthlySalary(double sal, int type);
}
2) 實現類:
public class ManagerServiceBean implements PersonService {
/**
*
*/
public ManagerServiceBean() {
}
/* (non-Javadoc)
* @see com.java.test.Interface.PersonService#calcuMonthlySalary(double, int)
*/
public double calcuMonthlySalary(double sal, int type) {
System.out.println("ManagerServiceBean: "+(sal*type*2));
return sal*type*2;
}
}
public class EmployeeServiceBean implements PersonService {
/**
*
*/
public EmployeeServiceBean() {
}
/* (non-Javadoc)
* @see com.java.test.Interface.PersonService#calcuMonthlySalary(double, int)
*/
public double calcuMonthlySalary(double sal, int type) {
System.out.println("EmployeeServiceBean: "+(sal*type*2));
return sal*type*1.5;
}
}
}
3) 測試類:
public class SalaryManageTest {
/**
* @param args
*/
public static void main(String[] args) throws Exception{
try{
//這里寫得不智能,還需要傳入傳輸
PersonService personService = (PersonService)Class.forName(args[0]).newInstance();
if (args[1] != null && args[1] != "" &&
args[2] != null && args[2] != ""){
int sal = Integer.valueOf(args[1]).intValue();
int type = Integer.valueOf(args[2]).intValue();
//這里可以根據傳入參數的不同,調用不同的實現類,
//如果再增加一類新的成員,我們也只要新增一個類,無需修改方法
personService.calcuMonthlySalary(sal, type);
}
}catch(Exception ex){
ex.printStackTrace();
}
}
}
這里,通過接口在獲取類對象的時候,個人覺得寫得不是很好。。但也許大家用過Ejb的人都應該知道,客戶端獲取Ejb bean的時候,就是通過這種方式獲取:
Java代碼
PersonService personService = (PersonService)context.lookup(“personServiceBean/remote”);
2. Java接口作為參數傳遞
下面列出一個Sample:
1) 接口,實現類同上。
2) Person實體類:
public class Person {
private double sal;
private int type;
/**
*
*/
public Person() {
}
/**
* @param sal
* @param type
*/
public Person(double sal, int type) {
this.sal = sal;
this.type = type;
}
/**
* @return the sal
*/
public double getSal() {
return sal;
}
/**
* @param sal the sal to set
*/
public void setSal(double sal) {
this.sal = sal;
}
/**
* @return the type
*/
public int getType() {
return type;
}
/**
* @param type the type to set
*/
public void setType(int type) {
this.type = type;
}
}
3) 接口作為參數傳入類:
public class SalaryManager {
/**
*
*/
public SalaryManager() {
}
public void getMonthlySalary(PersonService personService, Person person){
personService.calcuMonthlySalary(person.getSal(), person.getType());
}
}
4) 測試類:
public class SalaryManageTest {
/**
* @param args
*/
public static void main(String[] args) throws Exception{
try{
ManagerServiceBean managerServiceBean = new ManagerServiceBean();
EmployeeServiceBean employeeServiceBean = new EmployeeServiceBean();
SalaryManager salaryManager = new SalaryManager();
//call 接口作為傳入參數的實現類方法
salaryManager.getMonthlySalary(managerServiceBean, new Person(1000, 7));
salaryManager.getMonthlySalary(employeeServiceBean, new Person(1000, 4));
}catch(Exception ex){
ex.printStackTrace();
}
}
}
二 接口與抽象類的區別
我個人認為有以下幾點:
1.abstract class 在 Java 語言中表示的是一種繼承關系,一個類只能使用一次繼承關系。但是,一個類卻可以實現多個interface。這彌補了類的多繼承問題。
2.在abstract class 中可以有自己的數據成員,也可以有非abstarct的成員方法,而在interface中,只能夠有靜態的不能被修改的數據成員(也就是必須是static final的,不過在 interface中一般不定義數據成員),所有的成員方法都是abstract的。
3.abstract class和interface所反映出的設計理念不同。其實abstract class表示的是"is-a"關系,interface表示的是"like-a"關系。 注意:當一個行為與一個類的所屬行為方法不相關聯時,應該采用接口來實現這個行為,不能使用抽象類,否則違反面向對象的ISP(Interface Segregation Principle)規則和OCP原則.
4.實現抽象類和接口的類必須實現其中的所有方法。抽象類中可以有非抽象方法。接口中則不能有實現方法。
5.接口中定義的變量默認是public static final 型,且必須給其初值,所以實現類中不能重新定義,也不能改變其值。當然,變量定義也可以是friendly.
6.抽象類中的變量默認是 friendly 型,其值可以在子類中重新定義,也可以重新賦值。
7.接口中的方法默認都是 public,abstract 類型的。