2017-07-19 65 views
2

我編寫了一個簡單的接口繼承示例來說明我正在嘗試執行的操作。調用/分配實現接口的類的變量

interface Fruit{ 
    public void taste();  
} 


class Banana implements Fruit { 
    public String name = "Banana"; 
    public void taste(){ 
     System.out.println("yummy banana!"); 
    } 


class Strawberry implements Fruit { 
    public String name = "Strawberry"; 
    public void taste(){ 
     System.out.println("yummy strawberry!"); 
    } 
} 

class Lunch<Fruittype implements Fruit> { 
    public Fruittype fruit; 

    public void tasteit() { 
     System.out.println("I'm going to eat a"+ fruit.name + "!"); 
     // error: name cannot be resolved or is not a field 
     fruit.taste(); 
    } 
} 

class exec { 
    public static void main(String[] args) { 
      Lunch<Banana> bananalunch = new Lunch<>; 
      bananalunch.fruit = new Banana(); 
      bananalunch.tasteit(); 
    } 
} 

所以香蕉和草莓正在實施水果。在課程午餐中,我試圖稱之爲水果名稱及其功能品味(); 雖然調用函數的味道工作得很好,我不能稱爲名稱(請參閱:在評論中的錯誤)

通緝輸出: 我要去吃香蕉! 美味的香蕉!

就像我說的,美味的香蕉的作品,但名稱無法解決。我試圖聲明「public String name =」default「」;在水果界面。然後你可以調用它,但它總會說「默認」,而不是實際課程中的名稱。

有沒有辦法獲得實現接口的泛型類型的成員? P.S.我需要這樣做,當然這個代碼只是爲了表示,但我有一個更復雜的代碼,我遇到了這個問題 - 我不想重構它,如果不是必要的。

預先感謝您!

+4

我會爲接口添加一個'getName()'方法,並在該接口的實現中實現標準的getter/setter方法。 (當然,使'name'私密。) – David

回答

3

您的問題是由於嘗試直接訪問實例成員而導致的 - fruit.name - 而不是通過方法 - fruit.getName()

如果使用getter方法,將會執行正確的方法並返回所需的輸出。

也就是說,在這個特定的例子中,在基類中有一個單一的getName()方法,並且在該基類中有一個單一的_name變量,它被初始化爲基於實際類型的不同值水果類。

另一方面,看到您的Fruit是一個接口而不是基類,您可以讓每個實現該接口的類都有一個返回不同值的getName()方法。

例如:

class Strawberry implements Fruit { 
    public String name = "Strawberry"; 
    public void taste(){ 
     System.out.println("yummy strawberry!"); 
    } 
} 

將成爲:

class Strawberry implements Fruit { 
    public String getName() { 
     return "Strawberry"; 
    } 
    public void taste() { 
     System.out.println("yummy strawberry!"); 
    } 
} 

你將不得不增加getName()到接口:

interface Fruit { 
    public String getName(); 
    public void taste();  
} 

最後,您Lunch類變爲:

class Lunch<Fruittype implements Fruit> { 
    public Fruittype fruit; 

    public void tasteit() { 
     System.out.println("I'm going to eat a "+ fruit.getName() + "!"); 
     fruit.taste(); 
    } 
} 
+0

謝謝!我沒有想過這個 – kalu

0

當類實現接口時,意味着這個類的對象可以做一些在接口中描述的事情。

例如,每個平面形狀都有面積。所以我們可以確定接口:

interface PlaneShape { 
    int getArea(); 
} 

正方形區域是邊緣的乘積。圈的面積是 平方半徑乘pi數除以2的乘積。所以:

class Square implements PlaneShape { 
    public int edge = 5; 

    public int getArea() { 
     return edge*edge; 
    } 
} 

class Circle implements PlaneShape { 
    public int radius = 5; 
    public int pi = 3.14; 

    public int getArea() { 
     return radius*radius*pi/2; 
    } 
} 

接口用於抽象。 AreaCalculator使用平面形狀進行操作,因此它可以從任何特定類型的平面形狀中抽象出來。 AreaCalculator只知道任何形狀都可以通過執行方法getArea()來給他面積值。 AreaCalculator不知道特殊形狀字段的任何內容,如edgeradius

class AreaCalculator<S implemets PlaneShape> { 
    public S shape; 

    public int calculateArea() { 
     shape.getArea(); 
    } 
} 

通過這種方式,在你的榜樣,Lunch<Fruittype implements Fruit>類不知道什麼水果在內的名稱,它不「看」這個領域,它只能祈求的方法taste()。您需要添加方法getName()來接口並實現它。

關於name="default"的主題在界面中。它在接口的上下文中聲明並且與實現沒有任何關係。