2014-09-12 80 views
0

我見過用於超類型變量的子類的constructer方法。例如:超類型對象的子類的構造方法?

DateFormat formatter = new SimpleDateFormat("yyyy-MM-dd"); 

formatter一個DateFormat類型對象或SimpleDateFormat類型?由於類SimpleDateFormat繼承自DateFormat,它可能比其超類更多的方法。調用這些函數的實例formatter只能存在於SimpleDateFormat而不是DateFormat?在這種情況下,DateFormatSimpleDateFormat可以互換嗎?如:

SimpleDateFormat formatter = new DateFormat ("yyyy-MM-dd"); 
+3

http://docs.oracle.com/javase/tutorial/java/IandI/subclasses.html – sp00m 2014-09-12 15:01:41

回答

3

formatter運行時類型是由用於初始化它的構造決定的,它的編譯時類型是您在聲明中使用的一個。除非使用強制轉換來解決方法調用,否則不能調用格式器上的方法,該方法存在於其實際運行時類型上,而不是其聲明類型上。

順便說一句,你可能會通過簡單的實驗回答了自己的問題:

public class SuperClass { 
    public void test() { 
     System.out.println("Test"); 
    } 

    public static class SubClass extends SuperClass { 
     public void testSub() { 
      System.out.println("Test sub"); 
     } 

     @Override 
     public void test() { 
      System.out.println("Override test"); 
     } 
    } 

    public static void main(String[] args) { 
     SuperClass sc = new SuperClass(); 
     sc.test();      // prints Test 
     sc = new SubClass(); 
     sc.test();      // prints Override test 
     sc.testSub();     // does not compile 
     ((SubClass) sc).testSub();  // prints Test sub 
    } 
} 
1

Java實例的類型由用於創建它的構造函數確定,並且無法更改。

可以在實例上調用的方法取決於用於引用它的變量的類型。因此,您可以在同一個實例上調用不同的方法集,具體取決於您用來引用它的變量的類型。

類型用於引用一個實例的變量的可以僅:

  • 相同類型的被引用的實例
  • 引用的實例的類型的超類的
  • 接口通過實現參考實例的類型。

作爲變量的類層次結構越高,使用它的代碼越通用(因此可重用)。作爲設計規則,您應該使用接口作爲變量(特別是參數)類型。

建議你閱讀本:http://en.wikipedia.org/wiki/Liskov_substitution_principle

+0

所以它基本上與'SimpleDateFormat formatter = new SimpleDateFormat(「yyyy-MM-dd」)''一樣嗎? 「DateFormat」與其子類的構造函數聲明的點是什麼? – ddd 2014-09-12 15:08:37

+0

@nasreddin完全一樣;將它首先聲明爲'DateFormat'沒有任何好處 – msrd0 2014-09-12 15:09:19

0

formatter是兩種類型,DateFormatSimpleDateFormat的。只要您調用SimpleDateFormat的構造函數,它也會調用DateFormat的構造函數 - 但它只是一個Object。

SimpleDateFormat接入方式,你可以將它轉換:

SimpleDateFormat sdf = (SimpleDateFormat) formatter; 

這隻只要formatterSimpleDateFormat類型或它的任何子類的工作。下面的行會產生一個編譯錯誤:

SimpleDateFormat sdf = (SimpleDateFormat) DateFormat.getDateTimeInstance(); 

順便說一句,我只想宣佈formatter從一開始就SimpleDateFormat。您將它聲明爲DateFormat並沒有任何好處,並且比鑄造它 - 這是對您的CPU的浪費。