2017-02-17 106 views
1

代碼正在運行,但我想更好地理解該主題,但我不確定如何命名該問題。在抽象類方法中,如果接口方法是空的,我可以調用接口方法嗎?任何人都可以告訴我在Java中如何調用這種操作?在我參加的uni課程中,幻燈片將該問題命名爲「通過API編程」,但當我在Google上搜索時找不到任何內容。調用抽象類方法中的接口方法

我有具有爲getBalance方法的接口類:

public interface BankAccount { 

int getBalance(); 
... 
} 

然後我調用接口方法在一個抽象類方法:

public abstract class AbstractBankAccount implements BankAccount { 

private final bankAccountNo; 
private int accountBalance; 

abstractBankAccount(int bankAccountNo) { 
    this.bankAccountNo = bankAccountNo; 
} 

public void transferBalance(bankAccount account) { 

// so here is what I am struggling to understand: account.getBalance() is called, but getBalance() method in interface is empty, how does it work then? 

final int accountBal = account.getBalance(); 

    if (accountBal < 0) 
     throw new IllegalArgumentException("not enough money on the account"); 

    accountBalance += accountBal; 

    account.withdraw(accountBal); 
} 
} 

回答

3

在一個抽象類的一些方法被放置具體的繼承者來實現。

雖然現在該方法爲空(抽象),但當您創建非抽象實現時,您必須爲該方法提供一個正文。該身體就是所謂的。

下面是一個例子:

abstract class Parent { 
    abstract String someMethod(); 

    public String getValue() { 
    return someMethod();//how could this work?! someMethod() has no body! 
    } 
} 

class Child extends Parent { 

    @Override 
    String someMethod() { //this won't compile unless I implement someMethod() 
    return "data"; 
    } 
} 

雖然的someMethod()是抽象父,你不能真正建立家長的一個實例(因爲它是抽象的)。你必須擴展它,這需要你提供someMethod()的實現。

0

答案是,當這個運行時,account參數將是一個實現bankAccount.getBalance()的具體類的實例。這是抽象的工作原理

+0

謝謝,掃清事情了我。 Java中的這種操作稱爲「通過接口編程」? – FervidWhirl

0

在我的單班我參加,幻燈片名稱的問題,因爲 「通過API編程」但我不能當我google一下發現任何東西。

怎麼可能在抽象類的方法,我可以調用 接口方法,如果接口方法是空的?

在具體類的方法中,您可能會遇到完全相同的情況。
這裏的接口定義了一個契約:實現的方法,但這些在接口中都是抽象的。
要通過接口進行編程,操縱放入接口(此處爲BankAccount)的概念的代碼不應該直接引用接口的具體類,而應該接口本身,如果我們希望能夠切換到接口的另一個實現類。

這就是爲什麼public void transferBalance(BankAccount account)定義爲BankAccount類型作爲參數。

當然,一個具體的類必須被選擇和實例化,但它是應該被指定的單一時間。

執行傳輸客戶端代碼可以這樣寫:

// I instantiate concrete classes but I refer interface as declared type. 
BankAccount bankAcountDebitor = new ConcreteBankAccount(); 
BankAccount bankAcountCreditor = new ConcreteBankAccount(); 

// I invoke a method that takes as argument a type derived from the interface type 
bankAcountDebitor.transferBalance(bankAcountCreditor); 

這樣,即使一天我們切換到另一個具體BankAccount表示:

bankAcountDebitor.transferBalance(bankAcountCreditor); 

仍將編譯罰款該方法將參數作爲接口類型。

所以,你可以寫:

BankAccount bankAcountDebitor = new ConcreteUniversalBankAccount(); 
BankAccount bankAcountCreditor = new ConcreteUniversalBankAccount(); 

bankAcountDebitor.transferBalance(bankAcountCreditor); 
+0

謝謝你的回答。我理解得好嗎?我的transferBalance()方法中的'account'參數是否總是引用接口類的具體實現(例如ConcreteBankAccount)? Java中這種稱爲「通過接口編程」的操作? – FervidWhirl

+0

歡迎您:) 1)是傳遞的參數總是指接口類的具體實現。這是一個編譯約束,因爲編譯器需要一個具體的實例但它也可以從聲明的接口類型派生。 2)在你的實際代碼中'public void transferBalance(BankAccount account)'是指通過接口進行編程。我們將'BankAccount'接口公開爲聲明類型。所以我們可以傳遞任何'BankAccount'的實現作爲參數,並且傳遞的對象只會在'BankAccount'接口公開時處理。 – davidxxx

+0

謝謝你的一個很好的解釋,那幫了我:) – FervidWhirl