2016-06-10 94 views
1

從Java抽象和/或接口混亂到現在已經很長時間了,但是現在我正在回到一個項目,並且有些東西讓我感到緊張。以下是我的代碼片段。Java抽象和接口

public class A { 

    private static String name = "None"; 
    private static String description = "No description"; 

    public A() {} 

    public A(User user) { 
     user.setData(this); 
    } 

    public static String getName() { 
     return name; 
    } 

    public static String getDescription() { 
     return description; 
    } 

} 

public class B extends A { 

    private static String name = "B"; 
    private static String description = "This is B"; 

    public B() {} 

    public B(User user) { 
     super(user); 
    } 

} 

public class User { 

    private A a; 

    public void setData(A a) { 
     this.a = a; 
    } 

    public A getData() { 
     return a; 
    } 

} 

當我使用B.getName()我希望它返回"B"但它不是返回"None"

現在我明顯做錯了事,四處尋找沒有幫助。我相當肯定,這可能有些可能,除非我與另一種語言混淆。

難道有人請指點我正確的方向嗎?謝謝。

+0

靜態字段不能這樣工作。 – SLaks

回答

2

歡迎回到Java。 您在類A和類B中使用靜態變量。這些變量與類關聯而不是對象。

如果您更改方法以從用戶獲取名稱,它將按您的預期工作。

4

您在類B上調用了getName方法.B沒有一個名爲getName的靜態方法,所以它在超類A中查找它。

也許你認爲B的版本名稱可以覆蓋A的?變量不會被覆蓋。 A正在訪問A上定義的靜態變量名稱,該方法最初在B上調用並不影響該方法。

繼承和靜態方法不能很好地協同工作。像多態這樣的OO概念依賴於運行時調度,字static應該暗示與此相反。通過多態性,程序在高度抽象的情況下工作,通過超類型引用對象並讓子類計算細節。有了靜態方法,你必須引用你想要的方法調用的特定子類,所以你沒有這種抽象級別。

0

你需要重寫getName()方法:

public class B extends A { 

    private static String name = "B"; 
    private static String description = "This is B"; 

    public B() {} 

    @Override 
    public static String getName() { 
     return name; 
    } 

    public B(User user) { 
     super(user); 
    } 

} 
0

你面對謊言中的方法getNamegetDescription定義的問題:他們在課堂上A靜態成員定義。這意味着即使在撥打B.getName()時,實際呼叫爲A.getName(),並且那裏的靜態成員變量值name設置爲None

當想到繼承時,你必須小心你聲明的靜態。這與接口或抽象類無關。

public class A { 

    protected String name = "None"; 
    protected String description = "No description"; 

    public A() {} 

    public A(User user) { 
     user.setData(this); 
    } 

    public String getName() { 
     return name; 
    } 

    public String getDescription() { 
     return description; 
    } 

} 

public class B extends A { 

    public B() { 
     name = "B"; 
     description = "This is B" 
    } 

    public B(User user) { 
     super(user); 
    } 

} 

public class User { 

    private A a; 

    public void setData(A a) { 
     this.a = a; 
    } 

    public A getData() { 
     return a; 
    } 

} 

隨着protected關鍵字可以從擴展的類訪問的字段。

參見:

0

一對夫婦的事情,在你的班上注意:

  1. 名稱和描述中同時使用靜態變量和B
  2. 的getName是在甲

靜態變量一個靜態方法結合到類和靜態方法不能被重寫

0

這是自的getName預期的行爲()類A的方法可以訪問成員變量屬於類別A的「名稱」。它是不是,因爲名稱是靜態即使您將它設置爲非靜態,並且您訪問它,如下面的代碼片段所示,它將返回「無」。請記住,只有方法會被重寫而不是成員變量。所以B類的「名稱」並不是重寫「A」類的「名稱」。另外,如果你想得到「B」作爲輸出,重寫類B的getName()方法,並使方法和變量非靜態。