2013-10-17 22 views
0

我有一個名爲函數但沒有定義任何方法的接口。然後我有一個實現類來實現該接口,並且還有一個在實現類中定義的方法。如果我創建一個接口類型的變量併爲其分配一個實現類型的新實例(其中定義了一個方法)。爲什麼我不能從變量訪問該方法?我想我在這裏錯過了一些東西。我的印象是,如果接口類型的變量已經被分配了一個具有在其中定義的方法的實現類型的實例,則可以使用該變量來運行該方法。接口類型的實例變量不能訪問實現類方法,其中作爲實現類的實例變量做

請指教。先謝謝你。

+3

如果您提供了一個小型的,自包含的示例代碼,那就太好了。你會更快得到答案。 – buc

回答

2

從概念上講,你在這裏做錯了事。

如果你想調用「該方法」,那麼你應該使用實現類型的變量,而不是接口類型。或者,如果「該方法」確實屬於接口的預期功能,那麼您應該將其「向上」移動到接口。

0

你不能做到這一點,考慮下面的例子:

interface Foo { 

} 

和類:

class FooBar implements Foo { 
    public void testMethod() { } 
} 

class FooBarMain { 
    public static void main(String[] args) { 
     Foo foo = new FooBar(); 
     //foo.testMethod(); this won't compile. 
    } 
} 

因爲在編譯時,編譯器將不知道你正在創建一個new FooBar();,它有一個方法稱爲testMethod()這將被動態確定。所以它期望你通過接口變量訪問的任何內容都應該在你的界面中可用。

你可以做的是如果你想通過接口變量訪問該方法,最好將該方法移動到接口並讓客戶端實現它。

如果您對此有疑問,請告知我。

+0

那麼爲什麼人們使用列表 mylist = new ArrayList (); –

+0

@ImtiazAhmad,也是一樣,列表是一個接口,ArrayList是List的具體實現,當然它包含了List接口中所有可用方法的實現。 –

0

至於我能理解,你的問題如下:

// Interface with no methods 
public interface Functions { 
} 

// Implementation class with a method defined in it 
public class Implementation implements Functions { 
    public void foo() { 
     System.out.println("Foo"); 
    } 
} 

public class Main { 
    public static void main(String[] args) { 
     // Create a variable from the interface type and 
     // assign a new instance of the implementation type 
     Functions f = new Implementation(); 
     // You try to call the function 
     f.foo();  // This is a compilation error 
    } 
} 

這是正確的行爲,這是不可能的。由於編譯器發現變量f的(靜態)類型爲Functions,因此它只能看到在該接口中定義的函數。編譯器不知道該變量實際上是否包含對Implementation類的實例的引用。

爲了解決這個問題,你要麼應該聲明的方法在接口

public interface Functions { 
    public void foo(); 
} 

或讓你的變量有

Implementation f = new Implementation(); 
+0

那麼爲什麼人們使用'List mylist = new ArrayList ();'?那有什麼好處?爲什麼不直接製作ArrayList類型的mylist變量而不是List接口?另外如果你能解釋爲什麼使用函數類型的變量f而不是實現對我有好處?什麼是我嘗試做的有用的用例? –

+1

他們這樣做是爲了能夠輕鬆更改List實現,如果他們的代碼需要其他類型的列表(鏈接列表,隊列)以獲得更好的操作。如果他們僅使用'List'接口中定義的方法,那麼他們可以將實現更改爲'ArrayList','LinkedList'等,而無需修改其餘的代碼。 – buc

1

您被限制爲通過定義的方法實現類的類型參考類型,而不是實例類型,例如:

AutoClosable a = new PrintWriter(...); 
a.println("something"); 

這裏,AutoClosable是引用類型,PrintWriter是實例類型。

此代碼會給出編譯器錯誤,因爲AutoClosable中定義的唯一方法是close()

+0

那麼爲什麼人們分配類型接口的變量而不是實現類型?這就是我想在此嘗試編碼到界面的一切。學習設計模式,同時嘗試這些東西。 –

+0

再次看看AutoClosable,你可以想象,試圖去適應每一個類(大多數還不存在),程序員可能希望與try-with-resources一起使用嗎?不,當然不。另一方面,很容易想象只處理一個接口,程序員可以用他們的類來實現。這樣,你可以處理任何課程 –